/// The resolution of a path or export. /// /// For every path or identifier in Rust, the compiler must determine /// what the path refers to. This process is called name resolution, /// and `Res` is the primary result of name resolution. /// /// For example, everything prefixed with `/* Res */` in this example has /// an associated `Res`: /// /// ``` /// fn str_to_string(s: & /* Res */ str) -> /* Res */ String { /// /* Res */ String::from(/* Res */ s) /// } /// /// /* Res */ str_to_string("hello"); /// ``` /// /// The associated `Res`s will be: /// /// - `str` will resolve to [`Res::PrimTy`]; /// - `String` will resolve to [`Res::Def`], and the `Res` will include the [`DefId`] /// for `String` as defined in the standard library; /// - `String::from` will also resolve to [`Res::Def`], with the [`DefId`] /// pointing to `String::from`; /// - `s` will resolve to [`Res::Local`]; /// - the call to `str_to_string` will resolve to [`Res::Def`], with the [`DefId`] /// pointing to the definition of `str_to_string` in the current crate. // #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)] #[derive(HashStable_Generic)] pubenumRes<Id = hir::HirId> { ... }
cratefncheck_reserved_macro_name(&mutself, ident: Ident, res: Res) { // Reserve some names that are not quite covered by the general check // performed on `Resolver::builtin_attrs`. if ident.name == sym::cfg || ident.name == sym::cfg_attr { letmacro_kind = self.get_macro(res).map(|ext| ext.macro_kind()); if macro_kind.is_some() && sub_namespace_match(macro_kind, Some(MacroKind::Attr)) { self.session.span_err( ident.span, &format!("name `{}` is reserved in attribute namespace", ident), ); } } }
好像也没啥特殊的,就是看看有没有用到保留关键字,先无视掉吧;
再看看第二行set_binding_parent_module:
1 2 3 4 5 6 7
fnset_binding_parent_module(&mutself, binding: &'a NameBinding<'a>, module: Module<'a>) { ifletSome(old_module) = self.binding_parent_modules.insert(PtrKey(binding), module) { if !ptr::eq(module, old_module) { span_bug!(binding.span, "parent module is reset for binding"); } } }
self.update_resolution(module, key, |this, resolution| { ifletSome(old_binding) = resolution.binding { if res == Res::Err { // Do not override real bindings with `Res::Err`s from error recovery. returnOk(()); } ...
这里如果之前返回的 res 本身就是 Err 的话,就直接返回,我们看一下 Err 的注释:
嗯,这部分直接无视吧,我们接着看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
letres = binding.res(); self.update_resolution(module, key, |this, resolution| { ifletSome(old_binding) = resolution.binding { ... match (old_binding.is_glob_import(), binding.is_glob_import()) { (true, true) => { if res != old_binding.res() { resolution.binding = Some(this.ambiguity( AmbiguityKind::GlobVsGlob, old_binding, binding, )); } elseif !old_binding.vis.is_at_least(binding.vis, &*this) { // We are glob-importing the same item but with greater visibility. resolution.binding = Some(binding); } } ...