crates.sage_ir.resolution.lookup.precedence

Lookup precedence is determined by scope, namespace, and path form. Lexical ribs take priority only for an unqualified one-segment name; module lookup then follows the applicable Rust namespace, imports, ancestry, prelude, and external-module rules rather than combining every visible name into an unordered global set. Leaving a lexical scope restores enclosing bindings; later bindings retain their own body-local identity and type even when nested or sibling scopes have allocated other locals.

Read in specification context · design/crates/sage_ir/resolution.sage

Implementation

Implemented crates/sage-ir/src/check/expr.rs:70–75

sage_ir::check::expr · lib:sage_ir

#![allow(unused)]
fn main() {
            // {anchor}`crates.sage_ir.resolution.lookup.precedence`
            ExprCstKind::Block(stmts, tail) => {
                let mut scope = scope.clone();
                scope.resolver.ribs.push_scope();
                let mut rstmts = Vec::new();
                for s in cx.source_stash[*stmts].iter() {

}

See more source ↗

Implemented crates/sage-ir/src/check/infer_ctx.rs:2373–2378

sage_ir::check::infer_ctx · lib:sage_ir

#![allow(unused)]
fn main() {
// {anchor}`crates.sage_ir.resolution.lookup.precedence`
impl<'db> Scope<'db> {
    pub fn new(resolver: Resolver<'db>) -> Self {
        Self {
            resolver,
            locals: FxHashMap::default(),

}

See more source ↗

Implemented crates/sage-ir/src/check/resolve/ribs.rs:1–6

sage_ir::check::resolve::ribs · lib:sage_ir

#![allow(unused)]
fn main() {
// {anchor}`crates.sage_ir.resolution.lookup.precedence`
use crate::generic_param::GenericParam;
use crate::name::Name;
use crate::symbol::Symbol;
use crate::ty::Ty;
use crate::tytree::LocalId;

}

See more source ↗

Implemented crates/sage-ir/src/check/resolve/mod.rs:130–135

sage_ir::check::resolve · lib:sage_ir

#![allow(unused)]
fn main() {
    // {anchor}`crates.sage_ir.resolution.lookup.precedence`
    // {anchor}`crates.sage_ir.resolution.lookup.identity_only`
    // {anchor}`crates.sage_ir.resolution.lookup.dependencies`
    pub fn resolve_path(
        &mut self,
        stash: &Stash,

}

See more source ↗

Implemented crates/sage-ir/src/local_syms/uses.rs:45–50

sage_ir::local_syms::uses · lib:sage_ir

#![allow(unused)]
fn main() {
    // {anchor}`crates.sage_ir.resolution.lookup.precedence`
    pub fn diagnostics(self, db: &'db dyn crate::Db) -> Vec<crate::diagnostic::Diagnostic<'db>> {
        use crate::cst::uses::UseKind;
        use crate::diagnostic::{Diagnostic, Span};
        use crate::resolve::{MacroKind, Namespace, Resolver};
        let mut resolver = Resolver::new(db, self.scope(db));

}

See more source ↗

Implemented crates/sage-ir/src/scope.rs:1–6

sage_ir::scope · lib:sage_ir

#![allow(unused)]
fn main() {
// {anchor}`crates.sage_ir.resolution.lookup.precedence`
use crate::Db;
use crate::local_syms::mods::LocalModSym;
use sage_macros_from_impls::FromImpls;

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, salsa::Update)]

}

See more source ↗

Implemented crates/sage-ir/src/symbol/mod.rs:460–465

sage_ir::symbol · lib:sage_ir

#![allow(unused)]
fn main() {
    // {anchor}`crates.sage_ir.resolution.lookup.precedence`
    pub fn name(&self, db: &'db dyn Db) -> Option<(Name<'db>, Namespace)> {
        match self.data {
            SymbolDataPriv::FnSymbol(sym) => Some((sym.name(db), Namespace::Value)),
            SymbolDataPriv::StructSymbol(sym) => Some((sym.name(db), Namespace::Type)),
            SymbolDataPriv::EnumSymbol(sym) => Some((sym.name(db), Namespace::Type)),

}

See more source ↗

Tests and review

Indexed tests and the implementation-completeness and test-adequacy review; no test run is implied.

TODO sage_meta::todo::resolution_lookup_precedence

crates/sage-meta/tests/semantic_spec.rs · test:semantic_spec

#![allow(unused)]
fn main() {
#[test]
    #[sage::test(crates.sage_ir.resolution.lookup.precedence)]
    fn resolution_lookup_precedence() {
        // TODO: Complete the remaining import/path matrix: macro subnamespace distinctions and Rust 2015
        // path rules. Source fixtures now cover lexical/nested/sibling shadowing, independent
        // type/value/bang-macro namespaces, named-versus-glob precedence, renamed imports,
        // cyclic and ambiguous globs, repeated routes to one definition, local/external enum
        // globs, qualified/absolute paths, and 2018/2021/2024 preludes.
    }
}

See more source ↗

Implemented sage_test_harness::file_module_scope_tests::transitive_local_globs_resolve_and_glob_cycles_terminate

crates/sage-test-harness/src/lib.rs · lib:sage_test_harness

#![allow(unused)]
fn main() {
#[test]
    #[sage::test(crates.sage_ir.resolution.lookup.precedence)]
    fn transitive_local_globs_resolve_and_glob_cycles_terminate() {
        with_test_crate_files(
            &[(
                "lib.rs",
                "mod c { pub use crate::b::*; pub struct Item; }\n\
                 mod b { pub use crate::c::*; }\n\
                 mod a { pub use crate::b::*; }\n\
                 use crate::a::*;\n\
                 fn resolved(_: Item) {}\n\
                 fn missing(_: Missing) {}",
            )],
            |db, root| {
                let parameter = |name: &str| {
                    let function = root
                        .expanded_module_items(db)
                        .iter()
                        .find_map(|symbol| match symbol.data(db) {
                            SymbolData::FnSymbol(FnSymbol::Local(function))
                                if function.name(db).text(db) == name =>
                            {
                                Some(function)
                            }
                            _ => None,
                        })
                        .unwrap_or_else(|| panic!("{name} function"));
                    let signature = function.sig(db);
                    let (stash, binder) = signature.open();
                    let [parameter] = &stash[binder.value.params] else {
                        panic!("expected one parameter")
                    };
                    match stash[*parameter] {
                        Ty::Adt(adt, arguments) => (Some(adt), stash[arguments].len(), false),
                        Ty::Error(_) => (None, 0, true),
                        other => panic!("unexpected {name} parameter type: {other:?}"),
                    }
                };

                let (Some(item), 0, false) = parameter("resolved") else {
                    panic!("transitive glob should resolve Item")
                };
                assert_eq!(Symbol::from(item).name(db).unwrap().0.text(db), "Item");
                assert_eq!(parameter("missing"), (None, 0, true));
            },
        );
    }
}

Conditional source: #[cfg(test)]

See more source ↗

Implemented sage_test_harness::absolute_external_paths_bypass_a_shadowing_local_module

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn absolute_external_paths_bypass_a_shadowing_local_module() {
    compile_test! {
        edition: "2021",
        source: indoc! {r#"
            mod std { pub mod cmp { pub enum Ordering { Less } } }
            fn local() -> std::cmp::Ordering {
                std::cmp::Ordering::Less //# sym
            }
            fn external() -> ::std::cmp::Ordering {
                ::std::cmp::Ordering::Less //# sym
            }
        "#},
        observations: expect![[r#"
            src/lib.rs: path `std::cmp::Ordering::Less`
              symbol: variant crate::std::cmp::Ordering::Less
            src/lib.rs: path `::std::cmp::Ordering::Less`
              symbol: variant std::cmp::Ordering::Less
        "#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::competing_glob_definitions_remain_ambiguous_despite_equal_types

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn competing_glob_definitions_remain_ambiguous_despite_equal_types() {
    compile_test! {
        source: indoc! {r#"
            mod first { pub fn value() -> u16 { 1 } }
            mod second { pub fn value() -> u16 { 2 } }
            use first::*;
            use second::*;
            fn example() -> u16 {
                value() //# ERROR
                //# sym
            }
        "#},
        observations: expect![[r#"
            src/lib.rs: path `value`
              symbol: <unresolved>
        "#]],
        diagnostics: expect![[r#"
            error: ambiguous name: 2 candidates
             --> src/lib.rs:6:5
              |
            6 |     value() //# ERROR
              |     ^^^^^"#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::direct_items_take_precedence_over_globs

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn direct_items_take_precedence_over_globs() {
    compile_test! {
        source: indoc! {r#"
            mod imported { pub fn value() -> u16 { 1 } }
            use imported::*;
            fn value() -> u16 { 2 }
            fn example() -> u16 {
                value() //# sym
            }
        "#},
        observations: expect![[r#"
            src/lib.rs: path `value`
              symbol: fn crate::value
        "#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::enum_glob_import_resolves_a_variant

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn enum_glob_import_resolves_a_variant() {
    compile_test! {
        source: indoc! {r#"
            enum Choice { Selected }
            use Choice::*;
            fn example() -> Choice {
                Selected //# sym
            }
        "#},
        observations: expect![[r#"
            src/lib.rs: path `Selected`
              symbol: variant crate::Choice::Selected
        "#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::explicit_imports_take_precedence_over_globs

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn explicit_imports_take_precedence_over_globs() {
    compile_test! {
        source: indoc! {r#"
            mod first { pub fn value() -> u16 { 1 } }
            mod second { pub fn value() -> u16 { 2 } }
            use first::*;
            use second::value as selected;
            use second::value;
            fn example() -> u16 {
                let first = selected(); //# sym
                value() //# sym
            }
        "#},
        observations: expect![[r#"
            src/lib.rs: path `selected`
              symbol: fn crate::second::value
            src/lib.rs: path `value`
              symbol: fn crate::second::value
        "#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::external_enum_glob_import_resolves_a_variant

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn external_enum_glob_import_resolves_a_variant() {
    compile_test! {
        source: indoc! {r#"
            use std::cmp::Ordering::*;
            fn example() -> std::cmp::Ordering {
                Less //# sym
            }
        "#},
        observations: expect![[r#"
            src/lib.rs: path `Less`
              symbol: variant std::cmp::Ordering::Less
        "#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::local_shadowing_does_not_change_qualified_lookup

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn local_shadowing_does_not_change_qualified_lookup() {
    compile_test! {
        source: indoc! {r#"
            fn value() -> u16 { 1 }
            fn example(value: u16) -> u16 {
                let before = value; //# sym
                let value = crate::value(); //# sym
                value //# sym
            }
        "#},
        observations: expect![[r#"
            src/lib.rs: path `value`
              symbol: local value#1
            src/lib.rs: path `crate::value`
              symbol: fn crate::value
            src/lib.rs: path `value`
              symbol: local value#2
        "#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::named_type_import_takes_precedence_over_the_standard_prelude

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn named_type_import_takes_precedence_over_the_standard_prelude() {
    compile_test! {
        source: indoc! {r#"
            mod custom { pub struct Option { field: u16 } }
            use custom::Option;
            fn example(value: Option) -> Option {
                value //# ty
            }
        "#},
        observations: expect![[r#"
            src/lib.rs: path `value`
              type: custom::Option
        "#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::nested_scope_shadowing_restores_the_outer_binding

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn nested_scope_shadowing_restores_the_outer_binding() {
    compile_test! {
        source: indoc! {r#"
            fn example(value: u16) -> u16 {
                let nested = {
                    let value = true;
                    value //# sym
                    //# ty
                };
                let after = value; //# sym
                //# ty
                after //# sym
                //# ty
            }
        "#},
        observations: expect![[r#"
            src/lib.rs: path `value`
              symbol: local value#2
              type: bool
            src/lib.rs: path `value`
              symbol: local value#1
              type: u16
            src/lib.rs: path `after`
              symbol: local after#1
              type: u16
        "#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::qualified_paths_select_the_named_module_scope

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn qualified_paths_select_the_named_module_scope() {
    compile_test! {
        source: indoc! {r#"
            fn value() -> u16 { 1 }
            mod outer {
                fn value() -> u16 { 2 }
                mod inner {
                    fn value() -> u16 { 3 }
                    fn example(outer: u16) -> u16 {
                        let here = self::value(); //# sym
                        let parent = super::value(); //# sym
                        let root = crate::value(); //# sym
                        crate::outer::value() //# sym
                    }
                }
            }
        "#},
        observations: expect![[r#"
            src/lib.rs: path `self::value`
              symbol: fn crate::outer::inner::value
            src/lib.rs: path `super::value`
              symbol: fn crate::outer::value
            src/lib.rs: path `crate::value`
              symbol: fn crate::value
            src/lib.rs: path `crate::outer::value`
              symbol: fn crate::outer::value
        "#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::repeated_glob_routes_to_one_definition_are_unambiguous

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn repeated_glob_routes_to_one_definition_are_unambiguous() {
    compile_test! {
        source: indoc! {r#"
            mod origin { pub fn value() -> u16 { 1 } }
            mod first { pub use crate::origin::value; }
            mod second { pub use crate::origin::value; }
            use first::*;
            use second::*;
            fn example() -> u16 {
                value() //# sym
            }
        "#},
        observations: expect![[r#"
            src/lib.rs: path `value`
              symbol: fn crate::origin::value
        "#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::rust_2018_prelude_does_not_supply_try_into

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn rust_2018_prelude_does_not_supply_try_into() {
    compile_test! {
        edition: "2018",
        source: "fn example<T: TryInto<u16>>(value: T) -> T { value } //# ERROR",
        diagnostics: expect![[r#"
            error: unresolved trait in type predicate
             --> src/lib.rs:1:15
              |
            1 | fn example<T: TryInto<u16>>(value: T) -> T { value } //# ERROR
              |               ^^^^^^^^^^^^"#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::rust_2021_prelude_does_not_supply_into_future

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn rust_2021_prelude_does_not_supply_into_future() {
    compile_test! {
        edition: "2021",
        source: "fn example<T: IntoFuture>(value: T) -> T { value } //# ERROR",
        diagnostics: expect![[r#"
            error: unresolved trait in type predicate
             --> src/lib.rs:1:15
              |
            1 | fn example<T: IntoFuture>(value: T) -> T { value } //# ERROR
              |               ^^^^^^^^^^"#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::rust_2021_prelude_supplies_try_into

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn rust_2021_prelude_supplies_try_into() {
    compile_test! {
        edition: "2021",
        source: indoc! {r#"
            fn example<T: TryInto<u16>>(value: T) -> T {
                value //# ty
            }
        "#},
        observations: expect![[r#"
            src/lib.rs: path `value`
              type: T
        "#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::rust_2024_prelude_supplies_into_future

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn rust_2024_prelude_supplies_into_future() {
    compile_test! {
        edition: "2024",
        source: indoc! {r#"
            fn example<T: IntoFuture>(value: T) -> T {
                value //# ty
            }
        "#},
        observations: expect![[r#"
            src/lib.rs: path `value`
              type: T
        "#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::sibling_scopes_do_not_share_bindings_or_local_type_slots

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn sibling_scopes_do_not_share_bindings_or_local_type_slots() {
    compile_test! {
        source: indoc! {r#"
            fn example(value: u16) -> u16 {
                let first = {
                    let value = true;
                    value //# sym
                    //# ty
                };
                let second = {
                    let value = 33u8;
                    value //# sym
                    //# ty
                };
                value //# sym
                //# ty
            }
        "#},
        observations: expect![[r#"
            src/lib.rs: path `value`
              symbol: local value#2
              type: bool
            src/lib.rs: path `value`
              symbol: local value#3
              type: u8
            src/lib.rs: path `value`
              symbol: local value#1
              type: u16
        "#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::transitive_cyclic_globs_resolve_a_value_definition

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn transitive_cyclic_globs_resolve_a_value_definition() {
    compile_test! {
        source: indoc! {r#"
            mod first { pub use crate::second::*; }
            mod second { pub use crate::third::*; }
            mod third { pub use crate::first::*; pub fn value() -> u16 { 3 } }
            use first::*;
            fn example() -> u16 {
                value() //# sym
            }
        "#},
        observations: expect![[r#"
            src/lib.rs: path `value`
              symbol: fn crate::third::value
        "#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::type_value_and_macro_namespaces_are_independent

crates/sage-test-harness/tests/lookup_precedence.rs · test:lookup_precedence

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
fn type_value_and_macro_namespaces_are_independent() {
    compile_test! {
        source: indoc! {r#"
            struct Same { field: u16 }
            fn Same() -> u16 { 1 }
            macro_rules! Same { () => { fn generated() -> u16 { Same() } } }
            Same!();
            fn example(value: Same) -> u16 {
                let result = Same(); //# sym
                let expanded = generated(); //# sym
                value.field //# ty
            }
        "#},
        observations: expect![[r#"
            src/lib.rs: path `Same`
              symbol: fn crate::Same
            src/lib.rs: path `generated`
              symbol: fn crate::generated
            src/lib.rs: path `value`
              type: Same
            src/lib.rs: field `value.field`
              type: u16
        "#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::generated_module_competes_with_glob_import_path

crates/sage-test-harness/tests/macro_glob_paths.rs · test:macro_glob_paths

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
#[sage::test(crates.sage_ir.resolution.lookup.expansion_import_ambiguity)]
fn generated_module_competes_with_glob_import_path() {
    // The imported contents are unused: validating the import itself must
    // reject the expansion-sensitive ambiguity in both compilers.
    compile_test! {
        source: indoc! {r#"
            mod first {
                pub struct Item { pub value: u16 }
            }
            mod second {
                pub struct Item { pub value: bool }
            }
            mod seed { pub(crate) use crate::first as path; }
            use seed::*;
            use path::*; //# ERROR
            macro_rules! build { () => { mod path { pub(crate) use crate::second::Item; } }; }
            build!();
        "#},
        diagnostics: expect![[r#"
            error: ambiguous import: macro-generated binding conflicts with glob import
             --> src/lib.rs:9:5
              |
            9 | use path::*; //# ERROR
              |     ^^^^^^^"#]],
    }
}
}

See more source ↗

Implemented sage_test_harness::qualified_glob_path_selects_generated_module

crates/sage-test-harness/tests/macro_glob_paths.rs · test:macro_glob_paths

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
#[sage::test(crates.sage_ir.resolution.lookup.expansion_import_ambiguity)]
fn qualified_glob_path_selects_generated_module() {
    compile_test! {
        source: indoc! {r#"
            mod first {
                pub struct Item { pub value: u16 }
            }
            mod second {
                pub struct Item { pub value: bool }
            }
            mod seed { pub(crate) use crate::first as path; }
            use seed::*;
            use crate::path::*;
            macro_rules! build { () => { mod path { pub(crate) use crate::second::Item; } }; }
            build!();
            fn example(item: Item) -> bool { item.value }
        "#},
    }
}
}

See more source ↗

Implemented sage_test_harness::source_written_module_takes_precedence_over_glob

crates/sage-test-harness/tests/macro_glob_paths.rs · test:macro_glob_paths

#![allow(unused)]
fn main() {
#[test]
#[sage::test(crates.sage_ir.resolution.lookup.precedence)]
#[sage::test(crates.sage_ir.resolution.lookup.expansion_import_ambiguity)]
fn source_written_module_takes_precedence_over_glob() {
    compile_test! {
        source: indoc! {r#"
            mod first {
                pub struct Item { pub value: u16 }
            }
            mod second {
                pub struct Item { pub value: bool }
            }
            mod seed { pub(crate) use crate::first as path; }
            use seed::*;
            use path::*;
            mod path { pub(crate) use crate::second::Item; }
            fn example(item: Item) -> bool { item.value }
        "#},
    }
}
}

See more source ↗

Review: Accepted · macro_fix_precedence.

Reviewed the complete precedence claim, seven ordinary implementation associations, and all 23 associated test entries (22 executable behavior tests and the explicit TODO). This is partial coverage, not a claim of complete Rust name-resolution conformance.

Implementation: resolve/mod.rs gives ribs priority for unqualified one-segment paths, resolves longer paths through Type namespace containers, distinguishes anchored self/super/crate/external paths, and searches named items before globs in normal mode, followed by external/edition/language preludes. MacroExpansion mode deliberately retains combined named/glob lookup. Lookup tracks module/name/namespace recursion and deduplicates definition identity after selecting a precedence bucket; module and enum globs use their respective child lookup. symbol/mod.rs supplies per-kind namespaces and external-child dispatch; scope.rs supplies ancestry and edition-specific prelude names. ribs.rs searches scopes and entries in reverse order. expr.rs clones block scope and pushes/pops ribs; infer_ctx.rs allocates body-global LocalIds and stores types by ID in each cloned scope, preserving sparse IDs and restored outer bindings. uses.rs now separately audits expansion-sensitive relative import roots after expansion. Generated binding provenance is determined on the binding item (including use declarations), rather than the eventual definition. Anchored imports are exempt, source-written bindings retain precedence, identical definitions do not conflict, and the in-flight root prevents self-rediscovery through cyclic routes. The captured span and local module helper fragments establish generated/file provenance and local-item conversion; the dedicated expansion_import_ambiguity anchor owns the detailed new algorithm contract and its larger test matrix.

Test adequacy: local_shadowing_does_not_change_qualified_lookup and qualified_paths_select_the_named_module_scope assert exact definition identities despite same types and a shadowing local. nested_scope_shadowing_restores_the_outer_binding and sibling_scopes_do_not_share_bindings_or_local_type_slots assert both identity and distinct bool/u8/u16 types across scope boundaries. explicit_imports_take_precedence_over_globs covers aliases and named imports; direct_items_take_precedence_over_globs covers direct definitions; named_type_import_takes_precedence_over_the_standard_prelude covers Type namespace priority. type_value_and_macro_namespaces_are_independent checks coexistence of type/function/bang macro names and a generated callable item. absolute_external_paths_bypass_a_shadowing_local_module distinguishes local and external symbols. transitive_cyclic_globs_resolve_a_value_definition and the library transitive_local_globs_resolve_and_glob_cycles_terminate check successful transitive resolution and finite missing-name lookup through a cycle. repeated_glob_routes_to_one_definition_are_unambiguous asserts deduplication, while competing_glob_definitions_remain_ambiguous_despite_equal_types requires a diagnostic and unresolved symbol. enum_glob_import_resolves_a_variant and external_enum_glob_import_resolves_a_variant cover both enum sources. Four edition tests assert TryInto availability in 2021 and absence in 2018, and IntoFuture availability in 2024 and absence in 2021. The three associated macro_glob_paths tests require an error for the generated competing import root even when unused, and require successful checking for explicitly qualified and directly source-written controls. The harness preparation code was captured and inspected: it runs rustc independently and requires both compiler results before returning observations; these compile fixtures therefore provide differential diagnostic evidence in addition to Sage snapshots.

Remaining deferral: semantic_spec::todo::resolution_lookup_precedence explicitly retains macro subnamespace distinctions and Rust2015 path rules. This is justified remaining work requiring corresponding fixtures and semantics, not executable evidence. No N/A entries exist. The new regression does not replace or erase that TODO. A normal-only import audit would miss the generated-root regression; treating every named binding as generated would fail the source-written control; ignoring path anchors would fail the qualified control. These meaningful positive/negative assertions address the changed behavior.

Executed cargo test -p sage-test-harness --test lookup_precedence --test macro_glob_paths with snapshot updating disabled: 18 and 10 tests passed respectively. The pre-existing library test was inspected but not rerun separately by this reviewer. No production or test files were modified by this review. No additional edits requested.

Browse crates anchors

139 anchors

Specification anchors and declared coverage
AnchorImplementationTests
crates (139)114 Implemented37 TODO2 N/A74 Implemented107 TODO
crates.sage_inspector (15)13 Implemented1 TODO2 N/A3 Implemented15 TODO
crates.sage_inspector.inspection (15)13 Implemented1 TODO2 N/A3 Implemented15 TODO
balanced_tracesImplementedTODO
canonical_ownershipImplementedImplementedTODO
derive_reflectionImplementedImplementedTODO
detail_free_indexImplementedTODO
deterministic_traceImplementedTODO
durable_navigationN/ATODO
generic_browserN/ATODO
owned_reflectionImplementedImplementedTODO
product_availabilityImplementedTODO
revision_and_demandImplementedTODO
semantic_phase_boundaryImplementedTODO
source_evidenceImplementedTODO
typed_serviceImplementedTODO
unknown_workImplementedTODOTODO
workspace_actorImplementedTODO
crates.sage_ir (90)67 Implemented34 TODO40 Implemented88 TODO
crates.sage_ir.checking (12)12 Implemented3 TODO5 Implemented12 TODO
crates.sage_ir.checking.body (5)5 Implemented2 TODO3 Implemented5 TODO
elaborationImplementedImplementedTODO
expected_typesImplementedTODOTODO
interface_dependenciesImplementedImplementedTODO
isolated_completionImplementedImplementedTODO
operator_callsImplementedTODOTODO
identity_mintingImplementedTODO
owned_productsImplementedImplementedTODO
crates.sage_ir.checking.signature (4)4 Implemented1 TODO1 Implemented4 TODO
body_independenceImplementedTODO
narrow_detailImplementedTODOTODO
owner_binderImplementedImplementedTODO
storageImplementedTODO
symbol_keyed_interfacesImplementedTODO
crates.sage_ir.crate (9)9 TODO9 TODO
explicit_restrictionsTODOTODO
identity_before_detailTODOTODO
incremental_evidenceTODOTODO
narrow_demandsTODOTODO
reexecution_and_invalidationTODOTODO
represented_completenessTODOTODO
restrictions_and_gapsTODOTODO
semantic_query_boundariesTODOTODO
terminal_incompletenessTODOTODO
crates.sage_ir.inference (8)8 Implemented6 Implemented8 TODO
atomic_checkingImplementedImplementedTODO
body_local_quiescenceImplementedImplementedTODO
canonical_boundaryImplementedImplementedTODO
completed_body_boundaryImplementedTODO
numeric_domainsImplementedImplementedTODO
subtyping_and_coercionImplementedImplementedTODO
terminal_obligationsImplementedTODO
transaction_isolationImplementedImplementedTODO
crates.sage_ir.metadata (4)4 Implemented1 TODO4 TODO
explicit_incompletenessImplementedTODO
keyed_reuseImplementedTODOTODO
product_boundariesImplementedTODO
provider_authorityImplementedTODO
crates.sage_ir.modules (8)7 Implemented1 TODO4 Implemented8 TODO
crates.sage_ir.modules.expand (4)4 Implemented2 Implemented4 TODO
completenessImplementedImplementedTODO
dependenciesImplementedTODO
direct_membersImplementedTODO
recursion_and_fixpointImplementedImplementedTODO
crates.sage_ir.modules.parse (4)3 Implemented1 TODO2 Implemented4 TODO
dependenciesImplementedTODO
detail_firewallImplementedImplementedTODO
recovery_completenessTODOTODO
syntax_identitiesImplementedImplementedTODO
crates.sage_ir.resolution (5)5 Implemented1 TODO3 Implemented4 TODO
crates.sage_ir.resolution.lookup (5)5 Implemented1 TODO3 Implemented4 TODO
completenessImplementedTODOImplementedTODO
dependenciesImplementedTODO
expansion_import_ambiguityImplementedImplemented
identity_onlyImplementedTODO
precedenceImplementedImplementedTODO
crates.sage_ir.solver (9)7 Implemented7 TODO5 Implemented9 TODO
alternative_isolationImplementedTODOImplementedTODO
bounded_completenessImplementedTODOTODO
candidate_completenessImplementedTODO
canonical_cyclesTODOTODO
canonical_outputsImplementedImplementedTODO
local_index_firewallTODOTODO
normalization_demandImplementedTODOImplementedTODO
schedule_independenceImplementedTODOImplementedTODO
shared_final_resultImplementedTODOImplementedTODO
crates.sage_ir.symbols (8)8 Implemented4 Implemented7 TODO
associated_identityImplementedImplemented
associated_interfacesImplementedTODO
body_interfacesImplementedImplementedTODO
definition_identityImplementedTODO
external_fact_queriesImplementedTODO
external_identityImplementedTODO
kind_wrappersImplementedImplementedTODO
local_identityImplementedImplementedTODO
crates.sage_ir.types (27)16 Implemented12 TODO13 Implemented27 TODO
crates.sage_ir.types.aliases (2)1 Implemented1 TODO1 Implemented2 TODO
identityImplementedImplementedTODO
revelationTODOTODO
crates.sage_ir.types.binder (1)1 Implemented1 TODO1 Implemented1 TODO
owner_parametersImplementedTODOImplementedTODO
crates.sage_ir.types.body (13)4 Implemented9 TODO3 Implemented13 TODO
awaitTODOTODO
closuresTODOTODO
conditional_patternsTODOTODO
coroutinesTODOTODO
diagnosed_recoveryImplementedImplementedTODO
elaboratedTODOImplementedTODO
for_iterationTODOTODO
indexingTODOTODO
macro_expansionTODOTODO
no_inferenceImplementedImplementedTODO
resolved_referencesImplementedTODO
try_residualTODOTODO
typed_provenanceImplementedTODO
crates.sage_ir.types.calls (2)1 Implemented1 TODO1 Implemented2 TODO
dispatch_familiesTODOTODO
selected_semanticsImplementedImplementedTODO
crates.sage_ir.types.lifetimes (2)2 Implemented2 Implemented2 TODO
dummyImplementedImplementedTODO
unchecked_borrowsImplementedImplementedTODO
crates.sage_ir.types.operators (2)2 Implemented1 Implemented2 TODO
lazy_control_flowImplementedTODO
trait_callsImplementedImplementedTODO
scoped_identitiesImplementedTODO
crates.sage_ir.types.spans (4)4 Implemented4 Implemented4 TODO
generated_identityImplementedImplementedTODO
item_originImplementedImplementedTODO
offset_reuseImplementedImplementedTODO
relative_compositionImplementedImplementedTODO
crates.sage_oracle_harness (4)4 Implemented2 TODO1 Implemented4 TODO
crates.sage_oracle_harness.crate (4)4 Implemented2 TODO1 Implemented4 TODO
deterministic_emissionImplementedTODO
exact_comparisonImplementedTODOImplementedTODO
fixed_projectionImplementedTODO
independent_coverageImplementedTODOTODO
crates.sage_stash (5)5 Implemented5 Implemented
crates.sage_stash.storage (5)5 Implemented5 Implemented
handle_ownershipImplementedImplemented
immutable_entriesImplementedImplemented
query_valueImplementedImplemented
rooted_equalityImplementedImplemented
typed_interningImplementedImplemented
crates.sage_test_harness (25)25 Implemented25 Implemented
crates.sage_test_harness.compile_tests (25)25 Implemented25 Implemented
annotation_validationImplementedImplemented
blessing_gateImplementedImplemented
callsite_updatesImplementedImplemented
checking_scopeImplementedImplemented
compiler_conditionsImplementedImplemented
completed_typesImplementedImplemented
coordinatesImplementedImplemented
dependenciesImplementedImplemented
diagnostic_countsImplementedImplemented
diagnostic_locationsImplementedImplemented
editionImplementedImplemented
fixturesImplementedImplemented
grouped_observationsImplementedImplemented
invocationImplementedImplemented
production_executionImplementedImplemented
project_isolationImplementedImplemented
query_captureImplementedImplemented
query_projectionImplementedImplemented
renderingImplementedImplemented
resolved_symbolsImplementedImplemented
review_visibilityImplementedImplemented
rustc_executionImplementedImplemented
rustc_lintsImplementedImplemented
starting_expressionsImplementedImplemented
target_lineImplementedImplemented