Auto merge of #150729 - matthiaskrgr:rollup-an2m4zg, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - rust-lang/rust#150026 (Fix macro_metavar_expr_concat behavior with nested repetitions) - rust-lang/rust#150521 (resolve: Rename "name bindings" to "name declarations") - rust-lang/rust#150704 (MGCA: Const constructors support) - rust-lang/rust#150728 (Cleanup some ui tests for const-traits) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
0aced202c2
42 changed files with 948 additions and 940 deletions
|
|
@ -558,25 +558,20 @@ fn metavar_expr_concat<'tx>(
|
|||
MetaVarExprConcatElem::Ident(elem) => elem.name,
|
||||
MetaVarExprConcatElem::Literal(elem) => *elem,
|
||||
MetaVarExprConcatElem::Var(ident) => {
|
||||
match matched_from_ident(dcx, *ident, tscx.interp)? {
|
||||
NamedMatch::MatchedSeq(named_matches) => {
|
||||
let Some((curr_idx, _)) = tscx.repeats.last() else {
|
||||
return Err(dcx.struct_span_err(dspan.entire(), "invalid syntax"));
|
||||
};
|
||||
match &named_matches[*curr_idx] {
|
||||
// FIXME(c410-f3r) Nested repetitions are unimplemented
|
||||
MatchedSeq(_) => {
|
||||
return Err(dcx.struct_span_err(
|
||||
ident.span,
|
||||
"nested repetitions with `${concat(...)}` metavariable expressions are not yet supported",
|
||||
));
|
||||
}
|
||||
MatchedSingle(pnr) => extract_symbol_from_pnr(dcx, pnr, ident.span)?,
|
||||
}
|
||||
}
|
||||
NamedMatch::MatchedSingle(pnr) => {
|
||||
let key = MacroRulesNormalizedIdent::new(*ident);
|
||||
match lookup_cur_matched(key, tscx.interp, &tscx.repeats) {
|
||||
Some(NamedMatch::MatchedSingle(pnr)) => {
|
||||
extract_symbol_from_pnr(dcx, pnr, ident.span)?
|
||||
}
|
||||
Some(NamedMatch::MatchedSeq(..)) => {
|
||||
return Err(dcx.struct_span_err(
|
||||
ident.span,
|
||||
"`${concat(...)}` variable is still repeating at this depth",
|
||||
));
|
||||
}
|
||||
None => {
|
||||
return Err(dcx.create_err(MveUnrecognizedVar { span: ident.span, key }));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1415,9 +1415,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let ct = self.check_param_uses_if_mcg(ct, span, false);
|
||||
Ok(ct)
|
||||
}
|
||||
TypeRelativePath::Ctor { ctor_def_id, args } => {
|
||||
return Ok(ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, ctor_def_id, args)));
|
||||
}
|
||||
TypeRelativePath::Ctor { ctor_def_id, args } => match tcx.def_kind(ctor_def_id) {
|
||||
DefKind::Ctor(_, CtorKind::Fn) => {
|
||||
Ok(ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, ctor_def_id, args)))
|
||||
}
|
||||
DefKind::Ctor(ctor_of, CtorKind::Const) => {
|
||||
Ok(self.construct_const_ctor_value(ctor_def_id, ctor_of, args))
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
// FIXME(mgca): implement support for this once ready to support all adt ctor expressions,
|
||||
// not just const ctors
|
||||
TypeRelativePath::Variant { .. } => {
|
||||
|
|
@ -1452,7 +1458,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
// FIXME(mgca): do we want constructor resolutions to take priority over
|
||||
// other possible resolutions?
|
||||
if matches!(mode, LowerTypeRelativePathMode::Const)
|
||||
&& let Some((CtorKind::Fn, ctor_def_id)) = variant_def.ctor
|
||||
&& let Some((_, ctor_def_id)) = variant_def.ctor
|
||||
{
|
||||
tcx.check_stability(variant_def.def_id, Some(qpath_hir_id), span, None);
|
||||
let _ = self.prohibit_generic_args(
|
||||
|
|
@ -2597,7 +2603,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
);
|
||||
self.lower_const_param(def_id, hir_id)
|
||||
}
|
||||
Res::Def(DefKind::Const | DefKind::Ctor(_, CtorKind::Const), did) => {
|
||||
Res::Def(DefKind::Const, did) => {
|
||||
assert_eq!(opt_self_ty, None);
|
||||
let [leading_segments @ .., segment] = path.segments else { bug!() };
|
||||
let _ = self
|
||||
|
|
@ -2605,6 +2611,21 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let args = self.lower_generic_args_of_path_segment(span, did, segment);
|
||||
ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args))
|
||||
}
|
||||
Res::Def(DefKind::Ctor(ctor_of, CtorKind::Const), did) => {
|
||||
assert_eq!(opt_self_ty, None);
|
||||
let [leading_segments @ .., segment] = path.segments else { bug!() };
|
||||
let _ = self
|
||||
.prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);
|
||||
|
||||
let parent_did = tcx.parent(did);
|
||||
let generics_did = match ctor_of {
|
||||
CtorOf::Variant => tcx.parent(parent_did),
|
||||
CtorOf::Struct => parent_did,
|
||||
};
|
||||
let args = self.lower_generic_args_of_path_segment(span, generics_did, segment);
|
||||
|
||||
self.construct_const_ctor_value(did, ctor_of, args)
|
||||
}
|
||||
Res::Def(DefKind::Ctor(_, CtorKind::Fn), did) => {
|
||||
assert_eq!(opt_self_ty, None);
|
||||
let [leading_segments @ .., segment] = path.segments else { bug!() };
|
||||
|
|
@ -3174,4 +3195,31 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
}
|
||||
Some(r)
|
||||
}
|
||||
|
||||
fn construct_const_ctor_value(
|
||||
&self,
|
||||
ctor_def_id: DefId,
|
||||
ctor_of: CtorOf,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> Const<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
let parent_did = tcx.parent(ctor_def_id);
|
||||
|
||||
let adt_def = tcx.adt_def(match ctor_of {
|
||||
CtorOf::Variant => tcx.parent(parent_did),
|
||||
CtorOf::Struct => parent_did,
|
||||
});
|
||||
|
||||
let variant_idx = adt_def.variant_index_with_id(parent_did);
|
||||
|
||||
let valtree = if adt_def.is_enum() {
|
||||
let discr = ty::ValTree::from_scalar_int(tcx, variant_idx.as_u32().into());
|
||||
ty::ValTree::from_branches(tcx, [ty::Const::new_value(tcx, discr, tcx.types.u32)])
|
||||
} else {
|
||||
ty::ValTree::zst(tcx)
|
||||
};
|
||||
|
||||
let adt_ty = Ty::new_adt(tcx, adt_def, args);
|
||||
ty::Const::new_value(tcx, valtree, adt_ty)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ impl Reexport {
|
|||
}
|
||||
}
|
||||
|
||||
/// This structure is supposed to keep enough data to re-create `NameBinding`s for other crates
|
||||
/// This structure is supposed to keep enough data to re-create `Decl`s for other crates
|
||||
/// during name resolution. Right now the bindings are not recreated entirely precisely so we may
|
||||
/// need to add more data in the future to correctly support macros 2.0, for example.
|
||||
/// Module child can be either a proper item or a reexport (including private imports).
|
||||
|
|
|
|||
|
|
@ -33,31 +33,33 @@ use tracing::debug;
|
|||
use crate::Namespace::{MacroNS, TypeNS, ValueNS};
|
||||
use crate::def_collector::collect_definitions;
|
||||
use crate::imports::{ImportData, ImportKind};
|
||||
use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
|
||||
use crate::macros::{MacroRulesDecl, MacroRulesScope, MacroRulesScopeRef};
|
||||
use crate::ref_mut::CmCell;
|
||||
use crate::{
|
||||
BindingKey, ExternPreludeEntry, Finalize, MacroData, Module, ModuleKind, ModuleOrUniformRoot,
|
||||
NameBinding, NameBindingData, NameBindingKind, ParentScope, PathResult, ResolutionError,
|
||||
Resolver, Segment, Used, VisResolutionError, errors,
|
||||
BindingKey, Decl, DeclData, DeclKind, ExternPreludeEntry, Finalize, MacroData, Module,
|
||||
ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, ResolutionError, Resolver, Segment,
|
||||
Used, VisResolutionError, errors,
|
||||
};
|
||||
|
||||
type Res = def::Res<NodeId>;
|
||||
|
||||
impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
/// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
|
||||
/// otherwise, reports an error.
|
||||
pub(crate) fn define_binding_local(
|
||||
/// Attempt to put the declaration with the given name and namespace into the module,
|
||||
/// and report an error in case of a collision.
|
||||
pub(crate) fn plant_decl_into_local_module(
|
||||
&mut self,
|
||||
parent: Module<'ra>,
|
||||
ident: Ident,
|
||||
ns: Namespace,
|
||||
binding: NameBinding<'ra>,
|
||||
decl: Decl<'ra>,
|
||||
) {
|
||||
if let Err(old_binding) = self.try_define_local(parent, ident, ns, binding, false) {
|
||||
self.report_conflict(parent, ident, ns, old_binding, binding);
|
||||
if let Err(old_decl) = self.try_plant_decl_into_local_module(parent, ident, ns, decl, false)
|
||||
{
|
||||
self.report_conflict(parent, ident, ns, old_decl, decl);
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a name definitinon from the given components, and put it into the local module.
|
||||
fn define_local(
|
||||
&mut self,
|
||||
parent: Module<'ra>,
|
||||
|
|
@ -68,10 +70,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
span: Span,
|
||||
expn_id: LocalExpnId,
|
||||
) {
|
||||
let binding = self.arenas.new_res_binding(res, vis.to_def_id(), span, expn_id);
|
||||
self.define_binding_local(parent, ident, ns, binding);
|
||||
let decl = self.arenas.new_def_decl(res, vis.to_def_id(), span, expn_id);
|
||||
self.plant_decl_into_local_module(parent, ident, ns, decl);
|
||||
}
|
||||
|
||||
/// Create a name definitinon from the given components, and put it into the extern module.
|
||||
fn define_extern(
|
||||
&self,
|
||||
parent: Module<'ra>,
|
||||
|
|
@ -82,10 +85,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
vis: Visibility<DefId>,
|
||||
span: Span,
|
||||
expansion: LocalExpnId,
|
||||
ambiguity: Option<NameBinding<'ra>>,
|
||||
ambiguity: Option<Decl<'ra>>,
|
||||
) {
|
||||
let binding = self.arenas.alloc_name_binding(NameBindingData {
|
||||
kind: NameBindingKind::Res(res),
|
||||
let decl = self.arenas.alloc_decl(DeclData {
|
||||
kind: DeclKind::Def(res),
|
||||
ambiguity,
|
||||
// External ambiguities always report the `AMBIGUOUS_GLOB_IMPORTS` lint at the moment.
|
||||
warn_ambiguity: true,
|
||||
|
|
@ -101,8 +104,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
if self
|
||||
.resolution_or_default(parent, key)
|
||||
.borrow_mut_unchecked()
|
||||
.non_glob_binding
|
||||
.replace(binding)
|
||||
.non_glob_decl
|
||||
.replace(decl)
|
||||
.is_some()
|
||||
{
|
||||
span_bug!(span, "an external binding was already defined");
|
||||
|
|
@ -284,7 +287,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
let ModChild { ident: _, res, vis, ref reexport_chain } = *ambig_child;
|
||||
let span = child_span(self, reexport_chain, res);
|
||||
let res = res.expect_non_local();
|
||||
self.arenas.new_res_binding(res, vis, span, expansion)
|
||||
self.arenas.new_def_decl(res, vis, span, expansion)
|
||||
});
|
||||
|
||||
// Record primary definitions.
|
||||
|
|
@ -691,7 +694,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
|||
let kind = ImportKind::Single {
|
||||
source: source.ident,
|
||||
target: ident,
|
||||
bindings: Default::default(),
|
||||
decls: Default::default(),
|
||||
type_ns_only,
|
||||
nested,
|
||||
id,
|
||||
|
|
@ -977,7 +980,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
|||
let parent_scope = self.parent_scope;
|
||||
let expansion = parent_scope.expansion;
|
||||
|
||||
let (used, module, binding) = if orig_name.is_none() && ident.name == kw::SelfLower {
|
||||
let (used, module, decl) = if orig_name.is_none() && ident.name == kw::SelfLower {
|
||||
self.r.dcx().emit_err(errors::ExternCrateSelfRequiresRenaming { span: sp });
|
||||
return;
|
||||
} else if orig_name == Some(kw::SelfLower) {
|
||||
|
|
@ -997,10 +1000,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
|||
}
|
||||
.map(|module| {
|
||||
let used = self.process_macro_use_imports(item, module);
|
||||
let binding = self.r.arenas.new_pub_res_binding(module.res().unwrap(), sp, expansion);
|
||||
(used, Some(ModuleOrUniformRoot::Module(module)), binding)
|
||||
let decl = self.r.arenas.new_pub_def_decl(module.res().unwrap(), sp, expansion);
|
||||
(used, Some(ModuleOrUniformRoot::Module(module)), decl)
|
||||
})
|
||||
.unwrap_or((true, None, self.r.dummy_binding));
|
||||
.unwrap_or((true, None, self.r.dummy_decl));
|
||||
let import = self.r.arenas.alloc_import(ImportData {
|
||||
kind: ImportKind::ExternCrate { source: orig_name, target: ident, id: item.id },
|
||||
root_id: item.id,
|
||||
|
|
@ -1019,7 +1022,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
|||
self.r.import_use_map.insert(import, Used::Other);
|
||||
}
|
||||
self.r.potentially_unused_imports.push(import);
|
||||
let imported_binding = self.r.import(binding, import);
|
||||
let import_decl = self.r.new_import_decl(decl, import);
|
||||
if ident.name != kw::Underscore && parent == self.r.graph_root {
|
||||
let norm_ident = Macros20NormalizedIdent::new(ident);
|
||||
// FIXME: this error is technically unnecessary now when extern prelude is split into
|
||||
|
|
@ -1027,7 +1030,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
|||
if let Some(entry) = self.r.extern_prelude.get(&norm_ident)
|
||||
&& expansion != LocalExpnId::ROOT
|
||||
&& orig_name.is_some()
|
||||
&& entry.item_binding.is_none()
|
||||
&& entry.item_decl.is_none()
|
||||
{
|
||||
self.r.dcx().emit_err(
|
||||
errors::MacroExpandedExternCrateCannotShadowExternArguments { span: item.span },
|
||||
|
|
@ -1038,21 +1041,21 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
|||
match self.r.extern_prelude.entry(norm_ident) {
|
||||
Entry::Occupied(mut occupied) => {
|
||||
let entry = occupied.get_mut();
|
||||
if entry.item_binding.is_some() {
|
||||
if entry.item_decl.is_some() {
|
||||
let msg = format!("extern crate `{ident}` already in extern prelude");
|
||||
self.r.tcx.dcx().span_delayed_bug(item.span, msg);
|
||||
} else {
|
||||
entry.item_binding = Some((imported_binding, orig_name.is_some()));
|
||||
entry.item_decl = Some((import_decl, orig_name.is_some()));
|
||||
}
|
||||
entry
|
||||
}
|
||||
Entry::Vacant(vacant) => vacant.insert(ExternPreludeEntry {
|
||||
item_binding: Some((imported_binding, true)),
|
||||
flag_binding: None,
|
||||
item_decl: Some((import_decl, true)),
|
||||
flag_decl: None,
|
||||
}),
|
||||
};
|
||||
}
|
||||
self.r.define_binding_local(parent, ident, TypeNS, imported_binding);
|
||||
self.r.plant_decl_into_local_module(parent, ident, TypeNS, import_decl);
|
||||
}
|
||||
|
||||
/// Constructs the reduced graph for one foreign item.
|
||||
|
|
@ -1089,14 +1092,14 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn add_macro_use_binding(
|
||||
fn add_macro_use_decl(
|
||||
&mut self,
|
||||
name: Symbol,
|
||||
binding: NameBinding<'ra>,
|
||||
decl: Decl<'ra>,
|
||||
span: Span,
|
||||
allow_shadowing: bool,
|
||||
) {
|
||||
if self.r.macro_use_prelude.insert(name, binding).is_some() && !allow_shadowing {
|
||||
if self.r.macro_use_prelude.insert(name, decl).is_some() && !allow_shadowing {
|
||||
self.r.dcx().emit_err(errors::MacroUseNameAlreadyInUse { span, name });
|
||||
}
|
||||
}
|
||||
|
|
@ -1167,8 +1170,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
|||
}
|
||||
macro_use_import(this, span, true)
|
||||
};
|
||||
let import_binding = this.r.import(binding, import);
|
||||
this.add_macro_use_binding(ident.name, import_binding, span, allow_shadowing);
|
||||
let import_decl = this.r.new_import_decl(binding, import);
|
||||
this.add_macro_use_decl(ident.name, import_decl, span, allow_shadowing);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
|
@ -1183,13 +1186,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
|||
if let Ok(binding) = result {
|
||||
let import = macro_use_import(self, ident.span, false);
|
||||
self.r.potentially_unused_imports.push(import);
|
||||
let imported_binding = self.r.import(binding, import);
|
||||
self.add_macro_use_binding(
|
||||
ident.name,
|
||||
imported_binding,
|
||||
ident.span,
|
||||
allow_shadowing,
|
||||
);
|
||||
let import_decl = self.r.new_import_decl(binding, import);
|
||||
self.add_macro_use_decl(ident.name, import_decl, ident.span, allow_shadowing);
|
||||
} else {
|
||||
self.r.dcx().emit_err(errors::ImportedMacroNotFound { span: ident.span });
|
||||
}
|
||||
|
|
@ -1300,8 +1298,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
|||
} else {
|
||||
Visibility::Restricted(CRATE_DEF_ID)
|
||||
};
|
||||
let binding = self.r.arenas.new_res_binding(res, vis.to_def_id(), span, expansion);
|
||||
self.r.set_binding_parent_module(binding, parent_scope.module);
|
||||
let decl = self.r.arenas.new_def_decl(res, vis.to_def_id(), span, expansion);
|
||||
self.r.set_decl_parent_module(decl, parent_scope.module);
|
||||
self.r.all_macro_rules.insert(ident.name);
|
||||
if is_macro_export {
|
||||
let import = self.r.arenas.alloc_import(ImportData {
|
||||
|
|
@ -1319,17 +1317,17 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
|||
vis_span: item.vis.span,
|
||||
});
|
||||
self.r.import_use_map.insert(import, Used::Other);
|
||||
let import_binding = self.r.import(binding, import);
|
||||
self.r.define_binding_local(self.r.graph_root, ident, MacroNS, import_binding);
|
||||
let import_decl = self.r.new_import_decl(decl, import);
|
||||
self.r.plant_decl_into_local_module(self.r.graph_root, ident, MacroNS, import_decl);
|
||||
} else {
|
||||
self.r.check_reserved_macro_name(ident, res);
|
||||
self.insert_unused_macro(ident, def_id, item.id);
|
||||
}
|
||||
self.r.feed_visibility(feed, vis);
|
||||
let scope = self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Binding(
|
||||
self.r.arenas.alloc_macro_rules_binding(MacroRulesBinding {
|
||||
let scope = self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Def(
|
||||
self.r.arenas.alloc_macro_rules_decl(MacroRulesDecl {
|
||||
parent_macro_rules_scope: parent_scope.macro_rules,
|
||||
binding,
|
||||
decl,
|
||||
ident,
|
||||
}),
|
||||
));
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ use rustc_session::lint::builtin::{
|
|||
use rustc_span::{DUMMY_SP, Ident, Macros20NormalizedIdent, Span, kw};
|
||||
|
||||
use crate::imports::{Import, ImportKind};
|
||||
use crate::{LexicalScopeBinding, NameBindingKind, Resolver, module_to_string};
|
||||
use crate::{DeclKind, LateDecl, Resolver, module_to_string};
|
||||
|
||||
struct UnusedImport {
|
||||
use_tree: ast::UseTree,
|
||||
|
|
@ -514,8 +514,8 @@ impl Resolver<'_, '_> {
|
|||
let mut check_redundant_imports = FxIndexSet::default();
|
||||
for module in &self.local_modules {
|
||||
for (_key, resolution) in self.resolutions(*module).borrow().iter() {
|
||||
if let Some(binding) = resolution.borrow().best_binding()
|
||||
&& let NameBindingKind::Import { import, .. } = binding.kind
|
||||
if let Some(decl) = resolution.borrow().best_decl()
|
||||
&& let DeclKind::Import { import, .. } = decl.kind
|
||||
&& let ImportKind::Single { id, .. } = import.kind
|
||||
{
|
||||
if let Some(unused_import) = unused_imports.get(&import.root_id)
|
||||
|
|
@ -542,8 +542,8 @@ impl Resolver<'_, '_> {
|
|||
// Deleting both unused imports and unnecessary segments of an item may result
|
||||
// in the item not being found.
|
||||
for unn_qua in &self.potentially_unnecessary_qualifications {
|
||||
if let LexicalScopeBinding::Item(name_binding) = unn_qua.binding
|
||||
&& let NameBindingKind::Import { import, .. } = name_binding.kind
|
||||
if let LateDecl::Decl(decl) = unn_qua.decl
|
||||
&& let DeclKind::Import { import, .. } = decl.kind
|
||||
&& (is_unused_import(import, &unused_imports)
|
||||
|| is_redundant_import(import, &redundant_imports))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,11 +44,10 @@ use crate::errors::{
|
|||
use crate::imports::{Import, ImportKind};
|
||||
use crate::late::{DiagMetadata, PatternSource, Rib};
|
||||
use crate::{
|
||||
AmbiguityError, AmbiguityKind, BindingError, BindingKey, Finalize,
|
||||
ForwardGenericParamBanReason, HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module,
|
||||
ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult,
|
||||
PrivacyError, ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used,
|
||||
VisResolutionError, errors as errs, path_names_to_string,
|
||||
AmbiguityError, AmbiguityKind, BindingError, BindingKey, Decl, DeclKind, Finalize,
|
||||
ForwardGenericParamBanReason, HasGenericParams, LateDecl, MacroRulesScope, Module, ModuleKind,
|
||||
ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, ResolutionError, Resolver, Scope,
|
||||
ScopeSet, Segment, UseError, Used, VisResolutionError, errors as errs, path_names_to_string,
|
||||
};
|
||||
|
||||
type Res = def::Res<ast::NodeId>;
|
||||
|
|
@ -149,8 +148,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
|
||||
if ambiguity_error.warning {
|
||||
let node_id = match ambiguity_error.b1.0.kind {
|
||||
NameBindingKind::Import { import, .. } => import.root_id,
|
||||
NameBindingKind::Res(_) => CRATE_NODE_ID,
|
||||
DeclKind::Import { import, .. } => import.root_id,
|
||||
DeclKind::Def(_) => CRATE_NODE_ID,
|
||||
};
|
||||
self.lint_buffer.buffer_lint(
|
||||
AMBIGUOUS_GLOB_IMPORTS,
|
||||
|
|
@ -212,8 +211,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
parent: Module<'_>,
|
||||
ident: Ident,
|
||||
ns: Namespace,
|
||||
new_binding: NameBinding<'ra>,
|
||||
old_binding: NameBinding<'ra>,
|
||||
new_binding: Decl<'ra>,
|
||||
old_binding: Decl<'ra>,
|
||||
) {
|
||||
// Error on the second of two conflicting names
|
||||
if old_binding.span.lo() > new_binding.span.lo() {
|
||||
|
|
@ -288,8 +287,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
.with_code(code);
|
||||
|
||||
// See https://github.com/rust-lang/rust/issues/32354
|
||||
use NameBindingKind::Import;
|
||||
let can_suggest = |binding: NameBinding<'_>, import: self::Import<'_>| {
|
||||
use DeclKind::Import;
|
||||
let can_suggest = |binding: Decl<'_>, import: self::Import<'_>| {
|
||||
!binding.span.is_dummy()
|
||||
&& !matches!(import.kind, ImportKind::MacroUse { .. } | ImportKind::MacroExport)
|
||||
};
|
||||
|
|
@ -473,7 +472,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
&mut self,
|
||||
finalize: Finalize,
|
||||
path: &[Segment],
|
||||
second_binding: Option<NameBinding<'_>>,
|
||||
second_binding: Option<Decl<'_>>,
|
||||
) {
|
||||
let Finalize { node_id, root_span, .. } = finalize;
|
||||
|
||||
|
|
@ -506,7 +505,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
// `ExternCrate` (also used for `crate::...`) then no need to issue a
|
||||
// warning, this looks all good!
|
||||
if let Some(binding) = second_binding
|
||||
&& let NameBindingKind::Import { import, .. } = binding.kind
|
||||
&& let DeclKind::Import { import, .. } = binding.kind
|
||||
// Careful: we still want to rewrite paths from renamed extern crates.
|
||||
&& let ImportKind::ExternCrate { source: None, .. } = import.kind
|
||||
{
|
||||
|
|
@ -1196,13 +1195,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
// Never recommend deprecated helper attributes.
|
||||
}
|
||||
Scope::MacroRules(macro_rules_scope) => {
|
||||
if let MacroRulesScope::Binding(macro_rules_binding) = macro_rules_scope.get() {
|
||||
let res = macro_rules_binding.binding.res();
|
||||
if let MacroRulesScope::Def(macro_rules_def) = macro_rules_scope.get() {
|
||||
let res = macro_rules_def.decl.res();
|
||||
if filter_fn(res) {
|
||||
suggestions.push(TypoSuggestion::typo_from_ident(
|
||||
macro_rules_binding.ident,
|
||||
res,
|
||||
))
|
||||
suggestions
|
||||
.push(TypoSuggestion::typo_from_ident(macro_rules_def.ident, res))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1360,8 +1357,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
}
|
||||
|
||||
// #90113: Do not count an inaccessible reexported item as a candidate.
|
||||
if let NameBindingKind::Import { binding, .. } = name_binding.kind
|
||||
&& this.is_accessible_from(binding.vis, parent_scope.module)
|
||||
if let DeclKind::Import { source_decl, .. } = name_binding.kind
|
||||
&& this.is_accessible_from(source_decl.vis, parent_scope.module)
|
||||
&& !this.is_accessible_from(name_binding.vis, parent_scope.module)
|
||||
{
|
||||
return;
|
||||
|
|
@ -1469,8 +1466,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
let mut path_segments = path_segments.clone();
|
||||
path_segments.push(ast::PathSegment::from_ident(ident.0));
|
||||
|
||||
let alias_import = if let NameBindingKind::Import { import, .. } =
|
||||
name_binding.kind
|
||||
let alias_import = if let DeclKind::Import { import, .. } = name_binding.kind
|
||||
&& let ImportKind::ExternCrate { source: Some(_), .. } = import.kind
|
||||
&& import.parent_scope.expansion == parent_scope.expansion
|
||||
{
|
||||
|
|
@ -1583,9 +1579,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
|(key, name_resolution)| {
|
||||
if key.ns == TypeNS
|
||||
&& key.ident == ident
|
||||
&& let Some(binding) = name_resolution.borrow().best_binding()
|
||||
&& let Some(decl) = name_resolution.borrow().best_decl()
|
||||
{
|
||||
match binding.res() {
|
||||
match decl.res() {
|
||||
// No disambiguation needed if the identically named item we
|
||||
// found in scope actually refers to the crate in question.
|
||||
Res::Def(_, def_id) => def_id != crate_def_id,
|
||||
|
|
@ -1754,7 +1750,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
macro_kind.descr_expected(),
|
||||
),
|
||||
};
|
||||
if let crate::NameBindingKind::Import { import, .. } = binding.kind
|
||||
if let crate::DeclKind::Import { import, .. } = binding.kind
|
||||
&& !import.span.is_dummy()
|
||||
{
|
||||
let note = errors::IdentImporterHereButItIsDesc {
|
||||
|
|
@ -1971,7 +1967,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
true
|
||||
}
|
||||
|
||||
fn binding_description(&self, b: NameBinding<'_>, ident: Ident, scope: Scope<'_>) -> String {
|
||||
fn decl_description(&self, b: Decl<'_>, ident: Ident, scope: Scope<'_>) -> String {
|
||||
let res = b.res();
|
||||
if b.span.is_dummy() || !self.tcx.sess.source_map().is_span_accessible(b.span) {
|
||||
let (built_in, from) = match scope {
|
||||
|
|
@ -2007,7 +2003,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
&& self
|
||||
.extern_prelude
|
||||
.get(&Macros20NormalizedIdent::new(ident))
|
||||
.is_some_and(|entry| entry.item_binding.map(|(b, _)| b) == Some(b1))
|
||||
.is_some_and(|entry| entry.item_decl.map(|(b, _)| b) == Some(b1))
|
||||
};
|
||||
let (b1, b2, scope1, scope2, swapped) = if b2.span.is_dummy() && !b1.span.is_dummy() {
|
||||
// We have to print the span-less alternative first, otherwise formatting looks bad.
|
||||
|
|
@ -2016,8 +2012,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
(b1, b2, scope1, scope2, false)
|
||||
};
|
||||
|
||||
let could_refer_to = |b: NameBinding<'_>, scope: Scope<'ra>, also: &str| {
|
||||
let what = self.binding_description(b, ident, scope);
|
||||
let could_refer_to = |b: Decl<'_>, scope: Scope<'ra>, also: &str| {
|
||||
let what = self.decl_description(b, ident, scope);
|
||||
let note_msg = format!("`{ident}` could{also} refer to {what}");
|
||||
|
||||
let thing = b.res().descr();
|
||||
|
|
@ -2075,11 +2071,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
|
||||
/// If the binding refers to a tuple struct constructor with fields,
|
||||
/// returns the span of its fields.
|
||||
fn ctor_fields_span(&self, binding: NameBinding<'_>) -> Option<Span> {
|
||||
let NameBindingKind::Res(Res::Def(
|
||||
DefKind::Ctor(CtorOf::Struct, CtorKind::Fn),
|
||||
ctor_def_id,
|
||||
)) = binding.kind
|
||||
fn ctor_fields_span(&self, decl: Decl<'_>) -> Option<Span> {
|
||||
let DeclKind::Def(Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), ctor_def_id)) =
|
||||
decl.kind
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
|
|
@ -2091,7 +2085,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
fn report_privacy_error(&mut self, privacy_error: &PrivacyError<'ra>) {
|
||||
let PrivacyError {
|
||||
ident,
|
||||
binding,
|
||||
decl,
|
||||
outermost_res,
|
||||
parent_scope,
|
||||
single_nested,
|
||||
|
|
@ -2099,17 +2093,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
ref source,
|
||||
} = *privacy_error;
|
||||
|
||||
let res = binding.res();
|
||||
let ctor_fields_span = self.ctor_fields_span(binding);
|
||||
let res = decl.res();
|
||||
let ctor_fields_span = self.ctor_fields_span(decl);
|
||||
let plain_descr = res.descr().to_string();
|
||||
let nonimport_descr =
|
||||
if ctor_fields_span.is_some() { plain_descr + " constructor" } else { plain_descr };
|
||||
let import_descr = nonimport_descr.clone() + " import";
|
||||
let get_descr =
|
||||
|b: NameBinding<'_>| if b.is_import() { &import_descr } else { &nonimport_descr };
|
||||
let get_descr = |b: Decl<'_>| if b.is_import() { &import_descr } else { &nonimport_descr };
|
||||
|
||||
// Print the primary message.
|
||||
let ident_descr = get_descr(binding);
|
||||
let ident_descr = get_descr(decl);
|
||||
let mut err =
|
||||
self.dcx().create_err(errors::IsPrivate { span: ident.span, ident_descr, ident });
|
||||
|
||||
|
|
@ -2209,30 +2202,30 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
}
|
||||
|
||||
// Print the whole import chain to make it easier to see what happens.
|
||||
let first_binding = binding;
|
||||
let mut next_binding = Some(binding);
|
||||
let first_binding = decl;
|
||||
let mut next_binding = Some(decl);
|
||||
let mut next_ident = ident;
|
||||
let mut path = vec![];
|
||||
while let Some(binding) = next_binding {
|
||||
let name = next_ident;
|
||||
next_binding = match binding.kind {
|
||||
_ if res == Res::Err => None,
|
||||
NameBindingKind::Import { binding, import, .. } => match import.kind {
|
||||
_ if binding.span.is_dummy() => None,
|
||||
DeclKind::Import { source_decl, import, .. } => match import.kind {
|
||||
_ if source_decl.span.is_dummy() => None,
|
||||
ImportKind::Single { source, .. } => {
|
||||
next_ident = source;
|
||||
Some(binding)
|
||||
Some(source_decl)
|
||||
}
|
||||
ImportKind::Glob { .. }
|
||||
| ImportKind::MacroUse { .. }
|
||||
| ImportKind::MacroExport => Some(binding),
|
||||
| ImportKind::MacroExport => Some(source_decl),
|
||||
ImportKind::ExternCrate { .. } => None,
|
||||
},
|
||||
_ => None,
|
||||
};
|
||||
|
||||
match binding.kind {
|
||||
NameBindingKind::Import { import, .. } => {
|
||||
DeclKind::Import { import, .. } => {
|
||||
for segment in import.module_path.iter().skip(1) {
|
||||
// Don't include `{{root}}` in suggestions - it's an internal symbol
|
||||
// that should never be shown to users.
|
||||
|
|
@ -2245,14 +2238,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
true, // re-export
|
||||
));
|
||||
}
|
||||
NameBindingKind::Res(_) => {}
|
||||
DeclKind::Def(_) => {}
|
||||
}
|
||||
let first = binding == first_binding;
|
||||
let def_span = self.tcx.sess.source_map().guess_head_span(binding.span);
|
||||
let mut note_span = MultiSpan::from_span(def_span);
|
||||
if !first && binding.vis.is_public() {
|
||||
let desc = match binding.kind {
|
||||
NameBindingKind::Import { .. } => "re-export",
|
||||
DeclKind::Import { .. } => "re-export",
|
||||
_ => "directly",
|
||||
};
|
||||
note_span.push_span_label(def_span, format!("you could import this {desc}"));
|
||||
|
|
@ -2418,7 +2411,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
opt_ns: Option<Namespace>, // `None` indicates a module path in import
|
||||
parent_scope: &ParentScope<'ra>,
|
||||
ribs: Option<&PerNS<Vec<Rib<'ra>>>>,
|
||||
ignore_binding: Option<NameBinding<'ra>>,
|
||||
ignore_decl: Option<Decl<'ra>>,
|
||||
ignore_import: Option<Import<'ra>>,
|
||||
module: Option<ModuleOrUniformRoot<'ra>>,
|
||||
failed_segment_idx: usize,
|
||||
|
|
@ -2514,7 +2507,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
ns_to_try,
|
||||
parent_scope,
|
||||
None,
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
)
|
||||
.ok()
|
||||
|
|
@ -2528,11 +2521,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
parent_scope,
|
||||
None,
|
||||
&ribs[ns_to_try],
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
diag_metadata,
|
||||
) {
|
||||
// we found a locally-imported or available item/module
|
||||
Some(LexicalScopeBinding::Item(binding)) => Some(binding),
|
||||
Some(LateDecl::Decl(binding)) => Some(binding),
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
|
|
@ -2543,7 +2536,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
parent_scope,
|
||||
None,
|
||||
false,
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
)
|
||||
.ok()
|
||||
|
|
@ -2579,7 +2572,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
parent_scope,
|
||||
None,
|
||||
&ribs[ValueNS],
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
diag_metadata,
|
||||
)
|
||||
} else {
|
||||
|
|
@ -2594,7 +2587,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
// // variable `Foo`.
|
||||
// }
|
||||
// ```
|
||||
Some(LexicalScopeBinding::Res(Res::Local(id))) => {
|
||||
Some(LateDecl::RibDef(Res::Local(id))) => {
|
||||
Some(*self.pat_span_map.get(&id).unwrap())
|
||||
}
|
||||
// Name matches item from a local name binding
|
||||
|
|
@ -2608,7 +2601,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
// // binding `Foo`.
|
||||
// }
|
||||
// ```
|
||||
Some(LexicalScopeBinding::Item(name_binding)) => Some(name_binding.span),
|
||||
Some(LateDecl::Decl(name_binding)) => Some(name_binding.span),
|
||||
_ => None,
|
||||
};
|
||||
let suggestion = match_span.map(|span| {
|
||||
|
|
@ -2647,7 +2640,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
parent_scope,
|
||||
None,
|
||||
false,
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
) {
|
||||
let descr = binding.res().descr();
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility,
|
|||
use rustc_middle::ty::Visibility;
|
||||
use tracing::info;
|
||||
|
||||
use crate::{NameBinding, NameBindingKind, Resolver};
|
||||
use crate::{Decl, DeclKind, Resolver};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum ParentId<'ra> {
|
||||
Def(LocalDefId),
|
||||
Import(NameBinding<'ra>),
|
||||
Import(Decl<'ra>),
|
||||
}
|
||||
|
||||
impl ParentId<'_> {
|
||||
|
|
@ -28,10 +28,10 @@ impl ParentId<'_> {
|
|||
pub(crate) struct EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
|
||||
r: &'a mut Resolver<'ra, 'tcx>,
|
||||
def_effective_visibilities: EffectiveVisibilities,
|
||||
/// While walking import chains we need to track effective visibilities per-binding, and def id
|
||||
/// While walking import chains we need to track effective visibilities per-decl, and def id
|
||||
/// keys in `Resolver::effective_visibilities` are not enough for that, because multiple
|
||||
/// bindings can correspond to a single def id in imports. So we keep a separate table.
|
||||
import_effective_visibilities: EffectiveVisibilities<NameBinding<'ra>>,
|
||||
/// declarations can correspond to a single def id in imports. So we keep a separate table.
|
||||
import_effective_visibilities: EffectiveVisibilities<Decl<'ra>>,
|
||||
// It's possible to recalculate this at any point, but it's relatively expensive.
|
||||
current_private_vis: Visibility,
|
||||
changed: bool,
|
||||
|
|
@ -42,8 +42,8 @@ impl Resolver<'_, '_> {
|
|||
self.get_nearest_non_block_module(def_id.to_def_id()).nearest_parent_mod().expect_local()
|
||||
}
|
||||
|
||||
fn private_vis_import(&self, binding: NameBinding<'_>) -> Visibility {
|
||||
let NameBindingKind::Import { import, .. } = binding.kind else { unreachable!() };
|
||||
fn private_vis_import(&self, decl: Decl<'_>) -> Visibility {
|
||||
let DeclKind::Import { import, .. } = decl.kind else { unreachable!() };
|
||||
Visibility::Restricted(
|
||||
import
|
||||
.id()
|
||||
|
|
@ -70,7 +70,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
|
|||
pub(crate) fn compute_effective_visibilities<'c>(
|
||||
r: &'a mut Resolver<'ra, 'tcx>,
|
||||
krate: &'c Crate,
|
||||
) -> FxHashSet<NameBinding<'ra>> {
|
||||
) -> FxHashSet<Decl<'ra>> {
|
||||
let mut visitor = EffectiveVisibilitiesVisitor {
|
||||
r,
|
||||
def_effective_visibilities: Default::default(),
|
||||
|
|
@ -91,17 +91,17 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
|
|||
let mut exported_ambiguities = FxHashSet::default();
|
||||
|
||||
// Update visibilities for import def ids. These are not used during the
|
||||
// `EffectiveVisibilitiesVisitor` pass, because we have more detailed binding-based
|
||||
// `EffectiveVisibilitiesVisitor` pass, because we have more detailed declaration-based
|
||||
// information, but are used by later passes. Effective visibility of an import def id
|
||||
// is the maximum value among visibilities of bindings corresponding to that def id.
|
||||
for (binding, eff_vis) in visitor.import_effective_visibilities.iter() {
|
||||
let NameBindingKind::Import { import, .. } = binding.kind else { unreachable!() };
|
||||
if !binding.is_ambiguity_recursive() {
|
||||
// is the maximum value among visibilities of declarations corresponding to that def id.
|
||||
for (decl, eff_vis) in visitor.import_effective_visibilities.iter() {
|
||||
let DeclKind::Import { import, .. } = decl.kind else { unreachable!() };
|
||||
if !decl.is_ambiguity_recursive() {
|
||||
if let Some(node_id) = import.id() {
|
||||
r.effective_visibilities.update_eff_vis(r.local_def_id(node_id), eff_vis, r.tcx)
|
||||
}
|
||||
} else if binding.ambiguity.is_some() && eff_vis.is_public_at_level(Level::Reexported) {
|
||||
exported_ambiguities.insert(*binding);
|
||||
} else if decl.ambiguity.is_some() && eff_vis.is_public_at_level(Level::Reexported) {
|
||||
exported_ambiguities.insert(*decl);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -110,12 +110,12 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
|
|||
exported_ambiguities
|
||||
}
|
||||
|
||||
/// Update effective visibilities of bindings in the given module,
|
||||
/// Update effective visibilities of name declarations in the given module,
|
||||
/// including their whole reexport chains.
|
||||
fn set_bindings_effective_visibilities(&mut self, module_id: LocalDefId) {
|
||||
let module = self.r.expect_module(module_id.to_def_id());
|
||||
for (_, name_resolution) in self.r.resolutions(module).borrow().iter() {
|
||||
let Some(mut binding) = name_resolution.borrow().binding() else {
|
||||
let Some(mut decl) = name_resolution.borrow().binding() else {
|
||||
continue;
|
||||
};
|
||||
// Set the given effective visibility level to `Level::Direct` and
|
||||
|
|
@ -125,28 +125,27 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
|
|||
// If the binding is ambiguous, put the root ambiguity binding and all reexports
|
||||
// leading to it into the table. They are used by the `ambiguous_glob_reexports`
|
||||
// lint. For all bindings added to the table this way `is_ambiguity` returns true.
|
||||
let is_ambiguity =
|
||||
|binding: NameBinding<'ra>, warn: bool| binding.ambiguity.is_some() && !warn;
|
||||
let is_ambiguity = |decl: Decl<'ra>, warn: bool| decl.ambiguity.is_some() && !warn;
|
||||
let mut parent_id = ParentId::Def(module_id);
|
||||
let mut warn_ambiguity = binding.warn_ambiguity;
|
||||
while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind {
|
||||
self.update_import(binding, parent_id);
|
||||
let mut warn_ambiguity = decl.warn_ambiguity;
|
||||
while let DeclKind::Import { source_decl, .. } = decl.kind {
|
||||
self.update_import(decl, parent_id);
|
||||
|
||||
if is_ambiguity(binding, warn_ambiguity) {
|
||||
if is_ambiguity(decl, warn_ambiguity) {
|
||||
// Stop at the root ambiguity, further bindings in the chain should not
|
||||
// be reexported because the root ambiguity blocks any access to them.
|
||||
// (Those further bindings are most likely not ambiguities themselves.)
|
||||
break;
|
||||
}
|
||||
|
||||
parent_id = ParentId::Import(binding);
|
||||
binding = nested_binding;
|
||||
warn_ambiguity |= nested_binding.warn_ambiguity;
|
||||
parent_id = ParentId::Import(decl);
|
||||
decl = source_decl;
|
||||
warn_ambiguity |= source_decl.warn_ambiguity;
|
||||
}
|
||||
if !is_ambiguity(binding, warn_ambiguity)
|
||||
&& let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local())
|
||||
if !is_ambiguity(decl, warn_ambiguity)
|
||||
&& let Some(def_id) = decl.res().opt_def_id().and_then(|id| id.as_local())
|
||||
{
|
||||
self.update_def(def_id, binding.vis.expect_local(), parent_id);
|
||||
self.update_def(def_id, decl.vis.expect_local(), parent_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -188,15 +187,15 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn update_import(&mut self, binding: NameBinding<'ra>, parent_id: ParentId<'ra>) {
|
||||
let nominal_vis = binding.vis.expect_local();
|
||||
fn update_import(&mut self, decl: Decl<'ra>, parent_id: ParentId<'ra>) {
|
||||
let nominal_vis = decl.vis.expect_local();
|
||||
let Some(cheap_private_vis) = self.may_update(nominal_vis, parent_id) else { return };
|
||||
let inherited_eff_vis = self.effective_vis_or_private(parent_id);
|
||||
let tcx = self.r.tcx;
|
||||
self.changed |= self.import_effective_visibilities.update(
|
||||
binding,
|
||||
decl,
|
||||
Some(nominal_vis),
|
||||
|| cheap_private_vis.unwrap_or_else(|| self.r.private_vis_import(binding)),
|
||||
|| cheap_private_vis.unwrap_or_else(|| self.r.private_vis_import(decl)),
|
||||
inherited_eff_vis,
|
||||
parent_id.level(),
|
||||
tcx,
|
||||
|
|
|
|||
|
|
@ -19,10 +19,9 @@ use crate::late::{
|
|||
};
|
||||
use crate::macros::{MacroRulesScope, sub_namespace_match};
|
||||
use crate::{
|
||||
AmbiguityError, AmbiguityKind, BindingKey, CmResolver, Determinacy, Finalize, ImportKind,
|
||||
LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind,
|
||||
ParentScope, PathResult, PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet,
|
||||
Segment, Stage, Used, errors,
|
||||
AmbiguityError, AmbiguityKind, BindingKey, CmResolver, Decl, DeclKind, Determinacy, Finalize,
|
||||
ImportKind, LateDecl, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult,
|
||||
PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet, Segment, Stage, Used, errors,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
|
@ -183,7 +182,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
}
|
||||
Scope::DeriveHelpersCompat => Scope::MacroRules(parent_scope.macro_rules),
|
||||
Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
|
||||
MacroRulesScope::Binding(binding) => {
|
||||
MacroRulesScope::Def(binding) => {
|
||||
Scope::MacroRules(binding.parent_macro_rules_scope)
|
||||
}
|
||||
MacroRulesScope::Invocation(invoc_id) => {
|
||||
|
|
@ -305,9 +304,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
parent_scope: &ParentScope<'ra>,
|
||||
finalize: Option<Finalize>,
|
||||
ribs: &[Rib<'ra>],
|
||||
ignore_binding: Option<NameBinding<'ra>>,
|
||||
ignore_decl: Option<Decl<'ra>>,
|
||||
diag_metadata: Option<&DiagMetadata<'_>>,
|
||||
) -> Option<LexicalScopeBinding<'ra>> {
|
||||
) -> Option<LateDecl<'ra>> {
|
||||
let orig_ident = ident;
|
||||
let (general_span, normalized_span) = if ident.name == kw::SelfUpper {
|
||||
// FIXME(jseyfried) improve `Self` hygiene
|
||||
|
|
@ -330,7 +329,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
let rib_ident = if rib.kind.contains_params() { normalized_ident } else { ident };
|
||||
if let Some((original_rib_ident_def, res)) = rib.bindings.get_key_value(&rib_ident) {
|
||||
// The ident resolves to a type parameter or local variable.
|
||||
return Some(LexicalScopeBinding::Res(self.validate_res_from_ribs(
|
||||
return Some(LateDecl::RibDef(self.validate_res_from_ribs(
|
||||
i,
|
||||
rib_ident,
|
||||
*res,
|
||||
|
|
@ -346,12 +345,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
parent_scope,
|
||||
finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
|
||||
finalize.is_some(),
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
None,
|
||||
)
|
||||
{
|
||||
// The ident resolves to an item in a block.
|
||||
return Some(LexicalScopeBinding::Item(binding));
|
||||
return Some(LateDecl::Decl(binding));
|
||||
} else if let RibKind::Module(module) = rib.kind {
|
||||
// Encountered a module item, abandon ribs and look into that module and preludes.
|
||||
let parent_scope = &ParentScope { module, ..*parent_scope };
|
||||
|
|
@ -364,11 +363,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
parent_scope,
|
||||
finalize,
|
||||
finalize.is_some(),
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
None,
|
||||
)
|
||||
.ok()
|
||||
.map(LexicalScopeBinding::Item);
|
||||
.map(LateDecl::Decl);
|
||||
}
|
||||
|
||||
if let RibKind::MacroDefinition(def) = rib.kind
|
||||
|
|
@ -392,9 +391,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
parent_scope: &ParentScope<'ra>,
|
||||
finalize: Option<Finalize>,
|
||||
force: bool,
|
||||
ignore_binding: Option<NameBinding<'ra>>,
|
||||
ignore_decl: Option<Decl<'ra>>,
|
||||
ignore_import: Option<Import<'ra>>,
|
||||
) -> Result<NameBinding<'ra>, Determinacy> {
|
||||
) -> Result<Decl<'ra>, Determinacy> {
|
||||
assert!(force || finalize.is_none()); // `finalize` implies `force`
|
||||
|
||||
// Make sure `self`, `super` etc produce an error when passed to here.
|
||||
|
|
@ -425,7 +424,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
// }
|
||||
// So we have to save the innermost solution and continue searching in outer scopes
|
||||
// to detect potential ambiguities.
|
||||
let mut innermost_results: Vec<(NameBinding<'_>, Scope<'_>)> = Vec::new();
|
||||
let mut innermost_results: Vec<(Decl<'_>, Scope<'_>)> = Vec::new();
|
||||
let mut determinacy = Determinacy::Determined;
|
||||
|
||||
// Go through all the scopes and try to resolve the name.
|
||||
|
|
@ -443,13 +442,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
ctxt,
|
||||
scope_set,
|
||||
parent_scope,
|
||||
// Shadowed bindings don't need to be marked as used or non-speculatively loaded.
|
||||
// Shadowed decls don't need to be marked as used or non-speculatively loaded.
|
||||
if innermost_results.is_empty() { finalize } else { None },
|
||||
force,
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
) {
|
||||
Ok(binding) => Ok(binding),
|
||||
Ok(decl) => Ok(decl),
|
||||
// We can break with an error at this step, it means we cannot determine the
|
||||
// resolution right now, but we must block and wait until we can, instead of
|
||||
// considering outer scopes. Although there's no need to do that if we already
|
||||
|
|
@ -460,32 +459,32 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
Err(determinacy) => Err(determinacy.into_value()),
|
||||
};
|
||||
match res {
|
||||
Ok(binding) if sub_namespace_match(binding.macro_kinds(), macro_kind) => {
|
||||
Ok(decl) if sub_namespace_match(decl.macro_kinds(), macro_kind) => {
|
||||
// Below we report various ambiguity errors.
|
||||
// We do not need to report them if we are either in speculative resolution,
|
||||
// or in late resolution when everything is already imported and expanded
|
||||
// and no ambiguities exist.
|
||||
if matches!(finalize, None | Some(Finalize { stage: Stage::Late, .. })) {
|
||||
return ControlFlow::Break(Ok(binding));
|
||||
return ControlFlow::Break(Ok(decl));
|
||||
}
|
||||
|
||||
if let Some(&(innermost_binding, _)) = innermost_results.first() {
|
||||
if let Some(&(innermost_decl, _)) = innermost_results.first() {
|
||||
// Found another solution, if the first one was "weak", report an error.
|
||||
if this.get_mut().maybe_push_ambiguity(
|
||||
orig_ident,
|
||||
ns,
|
||||
scope_set,
|
||||
parent_scope,
|
||||
binding,
|
||||
decl,
|
||||
scope,
|
||||
&innermost_results,
|
||||
) {
|
||||
// No need to search for more potential ambiguities, one is enough.
|
||||
return ControlFlow::Break(Ok(innermost_binding));
|
||||
return ControlFlow::Break(Ok(innermost_decl));
|
||||
}
|
||||
}
|
||||
|
||||
innermost_results.push((binding, scope));
|
||||
innermost_results.push((decl, scope));
|
||||
}
|
||||
Ok(_) | Err(Determinacy::Determined) => {}
|
||||
Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined,
|
||||
|
|
@ -502,7 +501,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
|
||||
// Scope visiting walked all the scopes and maybe found something in one of them.
|
||||
match innermost_results.first() {
|
||||
Some(&(binding, ..)) => Ok(binding),
|
||||
Some(&(decl, ..)) => Ok(decl),
|
||||
None => Err(Determinacy::determined(determinacy == Determinacy::Determined || force)),
|
||||
}
|
||||
}
|
||||
|
|
@ -518,16 +517,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
parent_scope: &ParentScope<'ra>,
|
||||
finalize: Option<Finalize>,
|
||||
force: bool,
|
||||
ignore_binding: Option<NameBinding<'ra>>,
|
||||
ignore_decl: Option<Decl<'ra>>,
|
||||
ignore_import: Option<Import<'ra>>,
|
||||
) -> Result<NameBinding<'ra>, ControlFlow<Determinacy, Determinacy>> {
|
||||
) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {
|
||||
let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt));
|
||||
let ret = match scope {
|
||||
Scope::DeriveHelpers(expn_id) => {
|
||||
if let Some(binding) = self.helper_attrs.get(&expn_id).and_then(|attrs| {
|
||||
attrs.iter().rfind(|(i, _)| ident == *i).map(|(_, binding)| *binding)
|
||||
}) {
|
||||
Ok(binding)
|
||||
if let Some(decl) = self
|
||||
.helper_attrs
|
||||
.get(&expn_id)
|
||||
.and_then(|attrs| attrs.iter().rfind(|(i, _)| ident == *i).map(|(_, d)| *d))
|
||||
{
|
||||
Ok(decl)
|
||||
} else {
|
||||
Err(Determinacy::Determined)
|
||||
}
|
||||
|
|
@ -544,12 +545,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
) {
|
||||
Ok((Some(ext), _)) => {
|
||||
if ext.helper_attrs.contains(&ident.name) {
|
||||
let binding = self.arenas.new_pub_res_binding(
|
||||
let decl = self.arenas.new_pub_def_decl(
|
||||
Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat),
|
||||
derive.span,
|
||||
LocalExpnId::ROOT,
|
||||
);
|
||||
result = Ok(binding);
|
||||
result = Ok(decl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -560,10 +561,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
result
|
||||
}
|
||||
Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() {
|
||||
MacroRulesScope::Binding(macro_rules_binding)
|
||||
if ident == macro_rules_binding.ident =>
|
||||
{
|
||||
Ok(macro_rules_binding.binding)
|
||||
MacroRulesScope::Def(macro_rules_def) if ident == macro_rules_def.ident => {
|
||||
Ok(macro_rules_def.decl)
|
||||
}
|
||||
MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined),
|
||||
_ => Err(Determinacy::Determined),
|
||||
|
|
@ -580,7 +579,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
finalize.map(|f| Finalize { used: Used::Scope, ..f }),
|
||||
)
|
||||
};
|
||||
let binding = self.reborrow().resolve_ident_in_module_non_globs_unadjusted(
|
||||
let decl = self.reborrow().resolve_ident_in_module_non_globs_unadjusted(
|
||||
module,
|
||||
ident,
|
||||
ns,
|
||||
|
|
@ -591,11 +590,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
Shadowing::Restricted
|
||||
},
|
||||
adjusted_finalize,
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
);
|
||||
match binding {
|
||||
Ok(binding) => {
|
||||
match decl {
|
||||
Ok(decl) => {
|
||||
if let Some(lint_id) = derive_fallback_lint_id {
|
||||
self.get_mut().lint_buffer.buffer_lint(
|
||||
PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
|
||||
|
|
@ -608,7 +607,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
},
|
||||
);
|
||||
}
|
||||
Ok(binding)
|
||||
Ok(decl)
|
||||
}
|
||||
Err(ControlFlow::Continue(determinacy)) => Err(determinacy),
|
||||
Err(ControlFlow::Break(determinacy)) => {
|
||||
|
|
@ -641,7 +640,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
Shadowing::Restricted
|
||||
},
|
||||
adjusted_finalize,
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
);
|
||||
match binding {
|
||||
|
|
@ -669,18 +668,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
}
|
||||
}
|
||||
Scope::MacroUsePrelude => match self.macro_use_prelude.get(&ident.name).cloned() {
|
||||
Some(binding) => Ok(binding),
|
||||
Some(decl) => Ok(decl),
|
||||
None => Err(Determinacy::determined(
|
||||
self.graph_root.unexpanded_invocations.borrow().is_empty(),
|
||||
)),
|
||||
},
|
||||
Scope::BuiltinAttrs => match self.builtin_attrs_bindings.get(&ident.name) {
|
||||
Some(binding) => Ok(*binding),
|
||||
Scope::BuiltinAttrs => match self.builtin_attr_decls.get(&ident.name) {
|
||||
Some(decl) => Ok(*decl),
|
||||
None => Err(Determinacy::Determined),
|
||||
},
|
||||
Scope::ExternPreludeItems => {
|
||||
match self.reborrow().extern_prelude_get_item(ident, finalize.is_some()) {
|
||||
Some(binding) => Ok(binding),
|
||||
Some(decl) => Ok(decl),
|
||||
None => Err(Determinacy::determined(
|
||||
self.graph_root.unexpanded_invocations.borrow().is_empty(),
|
||||
)),
|
||||
|
|
@ -688,36 +687,35 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
}
|
||||
Scope::ExternPreludeFlags => {
|
||||
match self.extern_prelude_get_flag(ident, finalize.is_some()) {
|
||||
Some(binding) => Ok(binding),
|
||||
Some(decl) => Ok(decl),
|
||||
None => Err(Determinacy::Determined),
|
||||
}
|
||||
}
|
||||
Scope::ToolPrelude => match self.registered_tool_bindings.get(&ident) {
|
||||
Some(binding) => Ok(*binding),
|
||||
Scope::ToolPrelude => match self.registered_tool_decls.get(&ident) {
|
||||
Some(decl) => Ok(*decl),
|
||||
None => Err(Determinacy::Determined),
|
||||
},
|
||||
Scope::StdLibPrelude => {
|
||||
let mut result = Err(Determinacy::Determined);
|
||||
if let Some(prelude) = self.prelude
|
||||
&& let Ok(binding) = self.reborrow().resolve_ident_in_scope_set(
|
||||
&& let Ok(decl) = self.reborrow().resolve_ident_in_scope_set(
|
||||
ident,
|
||||
ScopeSet::Module(ns, prelude),
|
||||
parent_scope,
|
||||
None,
|
||||
false,
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
)
|
||||
&& (matches!(use_prelude, UsePrelude::Yes)
|
||||
|| self.is_builtin_macro(binding.res()))
|
||||
&& (matches!(use_prelude, UsePrelude::Yes) || self.is_builtin_macro(decl.res()))
|
||||
{
|
||||
result = Ok(binding)
|
||||
result = Ok(decl)
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
Scope::BuiltinTypes => match self.builtin_types_bindings.get(&ident.name) {
|
||||
Some(binding) => {
|
||||
Scope::BuiltinTypes => match self.builtin_type_decls.get(&ident.name) {
|
||||
Some(decl) => {
|
||||
if matches!(ident.name, sym::f16)
|
||||
&& !self.tcx.features().f16()
|
||||
&& !ident.span.allows_unstable(sym::f16)
|
||||
|
|
@ -744,7 +742,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
)
|
||||
.emit();
|
||||
}
|
||||
Ok(*binding)
|
||||
Ok(*decl)
|
||||
}
|
||||
None => Err(Determinacy::Determined),
|
||||
},
|
||||
|
|
@ -759,12 +757,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
ns: Namespace,
|
||||
scope_set: ScopeSet<'ra>,
|
||||
parent_scope: &ParentScope<'ra>,
|
||||
binding: NameBinding<'ra>,
|
||||
decl: Decl<'ra>,
|
||||
scope: Scope<'ra>,
|
||||
innermost_results: &[(NameBinding<'ra>, Scope<'ra>)],
|
||||
innermost_results: &[(Decl<'ra>, Scope<'ra>)],
|
||||
) -> bool {
|
||||
let (innermost_binding, innermost_scope) = *innermost_results.first().unwrap();
|
||||
let (res, innermost_res) = (binding.res(), innermost_binding.res());
|
||||
let (innermost_decl, innermost_scope) = innermost_results[0];
|
||||
let (res, innermost_res) = (decl.res(), innermost_decl.res());
|
||||
if res == innermost_res {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -784,7 +782,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
span_bug!(orig_ident.span, "impossible inner resolution kind")
|
||||
} else if matches!(innermost_scope, Scope::MacroRules(_))
|
||||
&& matches!(scope, Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..))
|
||||
&& !self.disambiguate_macro_rules_vs_modularized(innermost_binding, binding)
|
||||
&& !self.disambiguate_macro_rules_vs_modularized(innermost_decl, decl)
|
||||
{
|
||||
Some(AmbiguityKind::MacroRulesVsModularized)
|
||||
} else if matches!(scope, Scope::MacroRules(_))
|
||||
|
|
@ -800,13 +798,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
"ambiguous scoped macro resolutions with path-based \
|
||||
scope resolution as first candidate"
|
||||
)
|
||||
} else if innermost_binding.is_glob_import() {
|
||||
} else if innermost_decl.is_glob_import() {
|
||||
Some(AmbiguityKind::GlobVsOuter)
|
||||
} else if !module_only
|
||||
&& innermost_binding.may_appear_after(parent_scope.expansion, binding)
|
||||
{
|
||||
} else if !module_only && innermost_decl.may_appear_after(parent_scope.expansion, decl) {
|
||||
Some(AmbiguityKind::MoreExpandedVsOuter)
|
||||
} else if innermost_binding.expansion != LocalExpnId::ROOT
|
||||
} else if innermost_decl.expansion != LocalExpnId::ROOT
|
||||
&& (!module_only || ns == MacroNS)
|
||||
&& let Scope::ModuleGlobs(m1, _) = scope
|
||||
&& let Scope::ModuleNonGlobs(m2, _) = innermost_scope
|
||||
|
|
@ -825,9 +821,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
// by extern item bindings.
|
||||
// FIXME: Remove with lang team approval.
|
||||
let issue_145575_hack = matches!(scope, Scope::ExternPreludeFlags)
|
||||
&& innermost_results[1..].iter().any(|(b, s)| {
|
||||
matches!(s, Scope::ExternPreludeItems) && *b != innermost_binding
|
||||
});
|
||||
&& innermost_results[1..]
|
||||
.iter()
|
||||
.any(|(b, s)| matches!(s, Scope::ExternPreludeItems) && *b != innermost_decl);
|
||||
// Skip ambiguity errors for nonglob module bindings "overridden"
|
||||
// by glob module bindings in the same module.
|
||||
// FIXME: Remove with lang team approval.
|
||||
|
|
@ -848,8 +844,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
self.ambiguity_errors.push(AmbiguityError {
|
||||
kind,
|
||||
ident: orig_ident,
|
||||
b1: innermost_binding,
|
||||
b2: binding,
|
||||
b1: innermost_decl,
|
||||
b2: decl,
|
||||
scope1: innermost_scope,
|
||||
scope2: scope,
|
||||
warning: false,
|
||||
|
|
@ -869,7 +865,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
ns: Namespace,
|
||||
parent_scope: &ParentScope<'ra>,
|
||||
ignore_import: Option<Import<'ra>>,
|
||||
) -> Result<NameBinding<'ra>, Determinacy> {
|
||||
) -> Result<Decl<'ra>, Determinacy> {
|
||||
self.resolve_ident_in_module(module, ident, ns, parent_scope, None, None, ignore_import)
|
||||
}
|
||||
|
||||
|
|
@ -881,9 +877,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
ns: Namespace,
|
||||
parent_scope: &ParentScope<'ra>,
|
||||
finalize: Option<Finalize>,
|
||||
ignore_binding: Option<NameBinding<'ra>>,
|
||||
ignore_decl: Option<Decl<'ra>>,
|
||||
ignore_import: Option<Import<'ra>>,
|
||||
) -> Result<NameBinding<'ra>, Determinacy> {
|
||||
) -> Result<Decl<'ra>, Determinacy> {
|
||||
let tmp_parent_scope;
|
||||
let mut adjusted_parent_scope = parent_scope;
|
||||
match module {
|
||||
|
|
@ -907,7 +903,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
ns,
|
||||
adjusted_parent_scope,
|
||||
finalize,
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
)
|
||||
}
|
||||
|
|
@ -921,9 +917,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
ns: Namespace,
|
||||
parent_scope: &ParentScope<'ra>,
|
||||
finalize: Option<Finalize>,
|
||||
ignore_binding: Option<NameBinding<'ra>>,
|
||||
ignore_decl: Option<Decl<'ra>>,
|
||||
ignore_import: Option<Import<'ra>>,
|
||||
) -> Result<NameBinding<'ra>, Determinacy> {
|
||||
) -> Result<Decl<'ra>, Determinacy> {
|
||||
match module {
|
||||
ModuleOrUniformRoot::Module(module) => self.resolve_ident_in_scope_set(
|
||||
ident,
|
||||
|
|
@ -931,7 +927,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
parent_scope,
|
||||
finalize,
|
||||
finalize.is_some(),
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
),
|
||||
ModuleOrUniformRoot::ModuleAndExternPrelude(module) => self.resolve_ident_in_scope_set(
|
||||
|
|
@ -940,7 +936,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
parent_scope,
|
||||
finalize,
|
||||
finalize.is_some(),
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
),
|
||||
ModuleOrUniformRoot::ExternPrelude => {
|
||||
|
|
@ -953,7 +949,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
parent_scope,
|
||||
finalize,
|
||||
finalize.is_some(),
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
)
|
||||
}
|
||||
|
|
@ -962,7 +958,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
if ns == TypeNS {
|
||||
if ident.name == kw::Crate || ident.name == kw::DollarCrate {
|
||||
let module = self.resolve_crate_root(ident);
|
||||
return Ok(module.self_binding.unwrap());
|
||||
return Ok(module.self_decl.unwrap());
|
||||
} else if ident.name == kw::Super || ident.name == kw::SelfLower {
|
||||
// FIXME: Implement these with renaming requirements so that e.g.
|
||||
// `use super;` doesn't work, but `use super as name;` does.
|
||||
|
|
@ -976,7 +972,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
parent_scope,
|
||||
finalize,
|
||||
finalize.is_some(),
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
)
|
||||
}
|
||||
|
|
@ -994,9 +990,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
finalize: Option<Finalize>,
|
||||
// This binding should be ignored during in-module resolution, so that we don't get
|
||||
// "self-confirming" import resolutions during import validation and checking.
|
||||
ignore_binding: Option<NameBinding<'ra>>,
|
||||
ignore_decl: Option<Decl<'ra>>,
|
||||
ignore_import: Option<Import<'ra>>,
|
||||
) -> Result<NameBinding<'ra>, ControlFlow<Determinacy, Determinacy>> {
|
||||
) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {
|
||||
let key = BindingKey::new(ident, ns);
|
||||
// `try_borrow_mut` is required to ensure exclusive access, even if the resulting binding
|
||||
// doesn't need to be mutable. It will fail when there is a cycle of imports, and without
|
||||
|
|
@ -1006,7 +1002,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
.try_borrow_mut_unchecked()
|
||||
.map_err(|_| ControlFlow::Continue(Determined))?;
|
||||
|
||||
let binding = resolution.non_glob_binding.filter(|b| Some(*b) != ignore_binding);
|
||||
let binding = resolution.non_glob_decl.filter(|b| Some(*b) != ignore_decl);
|
||||
|
||||
if let Some(finalize) = finalize {
|
||||
return self.get_mut().finalize_module_binding(
|
||||
|
|
@ -1031,7 +1027,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
None,
|
||||
ns,
|
||||
ignore_import,
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
parent_scope,
|
||||
) {
|
||||
return Err(ControlFlow::Break(Undetermined));
|
||||
|
|
@ -1055,9 +1051,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
parent_scope: &ParentScope<'ra>,
|
||||
shadowing: Shadowing,
|
||||
finalize: Option<Finalize>,
|
||||
ignore_binding: Option<NameBinding<'ra>>,
|
||||
ignore_decl: Option<Decl<'ra>>,
|
||||
ignore_import: Option<Import<'ra>>,
|
||||
) -> Result<NameBinding<'ra>, ControlFlow<Determinacy, Determinacy>> {
|
||||
) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {
|
||||
let key = BindingKey::new(ident, ns);
|
||||
// `try_borrow_mut` is required to ensure exclusive access, even if the resulting binding
|
||||
// doesn't need to be mutable. It will fail when there is a cycle of imports, and without
|
||||
|
|
@ -1067,7 +1063,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
.try_borrow_mut_unchecked()
|
||||
.map_err(|_| ControlFlow::Continue(Determined))?;
|
||||
|
||||
let binding = resolution.glob_binding.filter(|b| Some(*b) != ignore_binding);
|
||||
let binding = resolution.glob_decl.filter(|b| Some(*b) != ignore_decl);
|
||||
|
||||
if let Some(finalize) = finalize {
|
||||
return self.get_mut().finalize_module_binding(
|
||||
|
|
@ -1087,7 +1083,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
binding,
|
||||
ns,
|
||||
ignore_import,
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
parent_scope,
|
||||
) {
|
||||
return Err(ControlFlow::Break(Undetermined));
|
||||
|
|
@ -1157,7 +1153,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
adjusted_parent_scope,
|
||||
None,
|
||||
false,
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
);
|
||||
|
||||
|
|
@ -1179,12 +1175,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
fn finalize_module_binding(
|
||||
&mut self,
|
||||
ident: Ident,
|
||||
binding: Option<NameBinding<'ra>>,
|
||||
binding: Option<Decl<'ra>>,
|
||||
parent_scope: &ParentScope<'ra>,
|
||||
module: Module<'ra>,
|
||||
finalize: Finalize,
|
||||
shadowing: Shadowing,
|
||||
) -> Result<NameBinding<'ra>, ControlFlow<Determinacy, Determinacy>> {
|
||||
) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {
|
||||
let Finalize { path_span, report_private, used, root_span, .. } = finalize;
|
||||
|
||||
let Some(binding) = binding else {
|
||||
|
|
@ -1195,7 +1191,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
if report_private {
|
||||
self.privacy_errors.push(PrivacyError {
|
||||
ident,
|
||||
binding,
|
||||
decl: binding,
|
||||
dedup_span: path_span,
|
||||
outermost_res: None,
|
||||
source: None,
|
||||
|
|
@ -1209,7 +1205,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
|
||||
if shadowing == Shadowing::Unrestricted
|
||||
&& binding.expansion != LocalExpnId::ROOT
|
||||
&& let NameBindingKind::Import { import, .. } = binding.kind
|
||||
&& let DeclKind::Import { import, .. } = binding.kind
|
||||
&& matches!(import.kind, ImportKind::MacroExport)
|
||||
{
|
||||
self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
|
||||
|
|
@ -1255,15 +1251,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
fn single_import_can_define_name<'r>(
|
||||
mut self: CmResolver<'r, 'ra, 'tcx>,
|
||||
resolution: &NameResolution<'ra>,
|
||||
binding: Option<NameBinding<'ra>>,
|
||||
binding: Option<Decl<'ra>>,
|
||||
ns: Namespace,
|
||||
ignore_import: Option<Import<'ra>>,
|
||||
ignore_binding: Option<NameBinding<'ra>>,
|
||||
ignore_decl: Option<Decl<'ra>>,
|
||||
parent_scope: &ParentScope<'ra>,
|
||||
) -> bool {
|
||||
for single_import in &resolution.single_imports {
|
||||
if let Some(binding) = resolution.non_glob_binding
|
||||
&& let NameBindingKind::Import { import, .. } = binding.kind
|
||||
if let Some(decl) = resolution.non_glob_decl
|
||||
&& let DeclKind::Import { import, .. } = decl.kind
|
||||
&& import == *single_import
|
||||
{
|
||||
// Single import has already defined the name and we are aware of it,
|
||||
|
|
@ -1276,8 +1272,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
if !self.is_accessible_from(single_import.vis, parent_scope.module) {
|
||||
continue;
|
||||
}
|
||||
if let Some(ignored) = ignore_binding
|
||||
&& let NameBindingKind::Import { import, .. } = ignored.kind
|
||||
if let Some(ignored) = ignore_decl
|
||||
&& let DeclKind::Import { import, .. } = ignored.kind
|
||||
&& import == *single_import
|
||||
{
|
||||
continue;
|
||||
|
|
@ -1286,13 +1282,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
let Some(module) = single_import.imported_module.get() else {
|
||||
return true;
|
||||
};
|
||||
let ImportKind::Single { source, target, bindings, .. } = &single_import.kind else {
|
||||
let ImportKind::Single { source, target, decls, .. } = &single_import.kind else {
|
||||
unreachable!();
|
||||
};
|
||||
if source != target {
|
||||
if bindings.iter().all(|binding| binding.get().binding().is_none()) {
|
||||
if decls.iter().all(|d| d.get().decl().is_none()) {
|
||||
return true;
|
||||
} else if bindings[ns].get().binding().is_none() && binding.is_some() {
|
||||
} else if decls[ns].get().decl().is_none() && binding.is_some() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1303,7 +1299,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
ns,
|
||||
&single_import.parent_scope,
|
||||
None,
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
) {
|
||||
Err(Determined) => continue,
|
||||
|
|
@ -1668,7 +1664,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
opt_ns: Option<Namespace>, // `None` indicates a module path in import
|
||||
parent_scope: &ParentScope<'ra>,
|
||||
finalize: Option<Finalize>,
|
||||
ignore_binding: Option<NameBinding<'ra>>,
|
||||
ignore_decl: Option<Decl<'ra>>,
|
||||
ignore_import: Option<Import<'ra>>,
|
||||
) -> PathResult<'ra> {
|
||||
self.resolve_path_with_ribs(
|
||||
|
|
@ -1678,7 +1674,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
None,
|
||||
finalize,
|
||||
None,
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
None,
|
||||
)
|
||||
|
|
@ -1692,7 +1688,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
source: Option<PathSource<'_, '_, '_>>,
|
||||
finalize: Option<Finalize>,
|
||||
ribs: Option<&PerNS<Vec<Rib<'ra>>>>,
|
||||
ignore_binding: Option<NameBinding<'ra>>,
|
||||
ignore_decl: Option<Decl<'ra>>,
|
||||
ignore_import: Option<Import<'ra>>,
|
||||
diag_metadata: Option<&DiagMetadata<'_>>,
|
||||
) -> PathResult<'ra> {
|
||||
|
|
@ -1819,7 +1815,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
ns,
|
||||
parent_scope,
|
||||
finalize,
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
)
|
||||
} else if let Some(ribs) = ribs
|
||||
|
|
@ -1832,13 +1828,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
parent_scope,
|
||||
finalize,
|
||||
&ribs[ns],
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
diag_metadata,
|
||||
) {
|
||||
// we found a locally-imported or available item/module
|
||||
Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
|
||||
Some(LateDecl::Decl(binding)) => Ok(binding),
|
||||
// we found a local variable or type param
|
||||
Some(LexicalScopeBinding::Res(res)) => {
|
||||
Some(LateDecl::RibDef(res)) => {
|
||||
record_segment_res(self.reborrow(), finalize, res, id);
|
||||
return PathResult::NonModule(PartialRes::with_unresolved_segments(
|
||||
res,
|
||||
|
|
@ -1854,7 +1850,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
parent_scope,
|
||||
finalize,
|
||||
finalize.is_some(),
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
)
|
||||
};
|
||||
|
|
@ -1954,7 +1950,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
opt_ns,
|
||||
parent_scope,
|
||||
ribs,
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
ignore_import,
|
||||
module,
|
||||
segment_idx,
|
||||
|
|
|
|||
|
|
@ -32,26 +32,27 @@ use crate::errors::{
|
|||
};
|
||||
use crate::ref_mut::CmCell;
|
||||
use crate::{
|
||||
AmbiguityError, BindingKey, CmResolver, Determinacy, Finalize, ImportSuggestion, Module,
|
||||
ModuleOrUniformRoot, NameBinding, NameBindingData, NameBindingKind, ParentScope, PathResult,
|
||||
PerNS, ResolutionError, Resolver, ScopeSet, Segment, Used, module_to_string, names_to_string,
|
||||
AmbiguityError, BindingKey, CmResolver, Decl, DeclData, DeclKind, Determinacy, Finalize,
|
||||
ImportSuggestion, Module, ModuleOrUniformRoot, ParentScope, PathResult, PerNS, ResolutionError,
|
||||
Resolver, ScopeSet, Segment, Used, module_to_string, names_to_string,
|
||||
};
|
||||
|
||||
type Res = def::Res<NodeId>;
|
||||
|
||||
/// A [`NameBinding`] in the process of being resolved.
|
||||
/// A potential import declaration in the process of being planted into a module.
|
||||
/// Also used for lazily planting names from `--extern` flags to extern prelude.
|
||||
#[derive(Clone, Copy, Default, PartialEq)]
|
||||
pub(crate) enum PendingBinding<'ra> {
|
||||
Ready(Option<NameBinding<'ra>>),
|
||||
pub(crate) enum PendingDecl<'ra> {
|
||||
Ready(Option<Decl<'ra>>),
|
||||
#[default]
|
||||
Pending,
|
||||
}
|
||||
|
||||
impl<'ra> PendingBinding<'ra> {
|
||||
pub(crate) fn binding(self) -> Option<NameBinding<'ra>> {
|
||||
impl<'ra> PendingDecl<'ra> {
|
||||
pub(crate) fn decl(self) -> Option<Decl<'ra>> {
|
||||
match self {
|
||||
PendingBinding::Ready(binding) => binding,
|
||||
PendingBinding::Pending => None,
|
||||
PendingDecl::Ready(decl) => decl,
|
||||
PendingDecl::Pending => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -65,8 +66,8 @@ pub(crate) enum ImportKind<'ra> {
|
|||
/// `target` in `use prefix::source as target`.
|
||||
/// It will directly use `source` when the format is `use prefix::source`.
|
||||
target: Ident,
|
||||
/// Bindings introduced by the import.
|
||||
bindings: PerNS<CmCell<PendingBinding<'ra>>>,
|
||||
/// Name declarations introduced by the import.
|
||||
decls: PerNS<CmCell<PendingDecl<'ra>>>,
|
||||
/// `true` for `...::{self [as target]}` imports, `false` otherwise.
|
||||
type_ns_only: bool,
|
||||
/// Did this import result from a nested import? ie. `use foo::{bar, baz};`
|
||||
|
|
@ -109,14 +110,14 @@ impl<'ra> std::fmt::Debug for ImportKind<'ra> {
|
|||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
use ImportKind::*;
|
||||
match self {
|
||||
Single { source, target, bindings, type_ns_only, nested, id, .. } => f
|
||||
Single { source, target, decls, type_ns_only, nested, id, .. } => f
|
||||
.debug_struct("Single")
|
||||
.field("source", source)
|
||||
.field("target", target)
|
||||
// Ignore the nested bindings to avoid an infinite loop while printing.
|
||||
.field(
|
||||
"bindings",
|
||||
&bindings.clone().map(|b| b.into_inner().binding().map(|_| format_args!(".."))),
|
||||
"decls",
|
||||
&decls.clone().map(|b| b.into_inner().decl().map(|_| format_args!(".."))),
|
||||
)
|
||||
.field("type_ns_only", type_ns_only)
|
||||
.field("nested", nested)
|
||||
|
|
@ -243,16 +244,16 @@ pub(crate) struct NameResolution<'ra> {
|
|||
/// Single imports that may define the name in the namespace.
|
||||
/// Imports are arena-allocated, so it's ok to use pointers as keys.
|
||||
pub single_imports: FxIndexSet<Import<'ra>>,
|
||||
/// The non-glob binding for this name, if it is known to exist.
|
||||
pub non_glob_binding: Option<NameBinding<'ra>>,
|
||||
/// The glob binding for this name, if it is known to exist.
|
||||
pub glob_binding: Option<NameBinding<'ra>>,
|
||||
/// The non-glob declaration for this name, if it is known to exist.
|
||||
pub non_glob_decl: Option<Decl<'ra>>,
|
||||
/// The glob declaration for this name, if it is known to exist.
|
||||
pub glob_decl: Option<Decl<'ra>>,
|
||||
}
|
||||
|
||||
impl<'ra> NameResolution<'ra> {
|
||||
/// Returns the binding for the name if it is known or None if it not known.
|
||||
pub(crate) fn binding(&self) -> Option<NameBinding<'ra>> {
|
||||
self.best_binding().and_then(|binding| {
|
||||
pub(crate) fn binding(&self) -> Option<Decl<'ra>> {
|
||||
self.best_decl().and_then(|binding| {
|
||||
if !binding.is_glob_import() || self.single_imports.is_empty() {
|
||||
Some(binding)
|
||||
} else {
|
||||
|
|
@ -261,8 +262,8 @@ impl<'ra> NameResolution<'ra> {
|
|||
})
|
||||
}
|
||||
|
||||
pub(crate) fn best_binding(&self) -> Option<NameBinding<'ra>> {
|
||||
self.non_glob_binding.or(self.glob_binding)
|
||||
pub(crate) fn best_decl(&self) -> Option<Decl<'ra>> {
|
||||
self.non_glob_decl.or(self.glob_decl)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -282,13 +283,10 @@ struct UnresolvedImportError {
|
|||
|
||||
// Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;`
|
||||
// are permitted for backward-compatibility under a deprecation lint.
|
||||
fn pub_use_of_private_extern_crate_hack(
|
||||
import: Import<'_>,
|
||||
binding: NameBinding<'_>,
|
||||
) -> Option<NodeId> {
|
||||
match (&import.kind, &binding.kind) {
|
||||
(ImportKind::Single { .. }, NameBindingKind::Import { import: binding_import, .. })
|
||||
if let ImportKind::ExternCrate { id, .. } = binding_import.kind
|
||||
fn pub_use_of_private_extern_crate_hack(import: Import<'_>, decl: Decl<'_>) -> Option<NodeId> {
|
||||
match (&import.kind, &decl.kind) {
|
||||
(ImportKind::Single { .. }, DeclKind::Import { import: decl_import, .. })
|
||||
if let ImportKind::ExternCrate { id, .. } = decl_import.kind
|
||||
&& import.vis.is_public() =>
|
||||
{
|
||||
Some(id)
|
||||
|
|
@ -298,20 +296,16 @@ fn pub_use_of_private_extern_crate_hack(
|
|||
}
|
||||
|
||||
impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
/// Given a binding and an import that resolves to it,
|
||||
/// return the corresponding binding defined by the import.
|
||||
pub(crate) fn import(
|
||||
&self,
|
||||
binding: NameBinding<'ra>,
|
||||
import: Import<'ra>,
|
||||
) -> NameBinding<'ra> {
|
||||
/// Given an import and the declaration that it points to,
|
||||
/// create the corresponding import declaration.
|
||||
pub(crate) fn new_import_decl(&self, decl: Decl<'ra>, import: Import<'ra>) -> Decl<'ra> {
|
||||
let import_vis = import.vis.to_def_id();
|
||||
let vis = if binding.vis.is_at_least(import_vis, self.tcx)
|
||||
|| pub_use_of_private_extern_crate_hack(import, binding).is_some()
|
||||
let vis = if decl.vis.is_at_least(import_vis, self.tcx)
|
||||
|| pub_use_of_private_extern_crate_hack(import, decl).is_some()
|
||||
{
|
||||
import_vis
|
||||
} else {
|
||||
binding.vis
|
||||
decl.vis
|
||||
};
|
||||
|
||||
if let ImportKind::Glob { ref max_vis, .. } = import.kind
|
||||
|
|
@ -321,8 +315,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
max_vis.set_unchecked(Some(vis.expect_local()))
|
||||
}
|
||||
|
||||
self.arenas.alloc_name_binding(NameBindingData {
|
||||
kind: NameBindingKind::Import { binding, import },
|
||||
self.arenas.alloc_decl(DeclData {
|
||||
kind: DeclKind::Import { source_decl: decl, import },
|
||||
ambiguity: None,
|
||||
warn_ambiguity: false,
|
||||
span: import.span,
|
||||
|
|
@ -331,18 +325,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Define the name or return the existing binding if there is a collision.
|
||||
pub(crate) fn try_define_local(
|
||||
/// Attempt to put the declaration with the given name and namespace into the module,
|
||||
/// and return existing declaration if there is a collision.
|
||||
pub(crate) fn try_plant_decl_into_local_module(
|
||||
&mut self,
|
||||
module: Module<'ra>,
|
||||
ident: Ident,
|
||||
ns: Namespace,
|
||||
binding: NameBinding<'ra>,
|
||||
decl: Decl<'ra>,
|
||||
warn_ambiguity: bool,
|
||||
) -> Result<(), NameBinding<'ra>> {
|
||||
let res = binding.res();
|
||||
) -> Result<(), Decl<'ra>> {
|
||||
let res = decl.res();
|
||||
self.check_reserved_macro_name(ident, res);
|
||||
self.set_binding_parent_module(binding, module);
|
||||
self.set_decl_parent_module(decl, module);
|
||||
// Even if underscore names cannot be looked up, we still need to add them to modules,
|
||||
// because they can be fetched by glob imports from those modules, and bring traits
|
||||
// into scope both directly and through glob imports.
|
||||
|
|
@ -351,67 +346,66 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
module.underscore_disambiguator.get()
|
||||
});
|
||||
self.update_local_resolution(module, key, warn_ambiguity, |this, resolution| {
|
||||
if let Some(old_binding) = resolution.best_binding() {
|
||||
if res == Res::Err && old_binding.res() != Res::Err {
|
||||
// Do not override real bindings with `Res::Err`s from error recovery.
|
||||
if let Some(old_decl) = resolution.best_decl() {
|
||||
if res == Res::Err && old_decl.res() != Res::Err {
|
||||
// Do not override real declarations with `Res::Err`s from error recovery.
|
||||
return Ok(());
|
||||
}
|
||||
match (old_binding.is_glob_import(), binding.is_glob_import()) {
|
||||
match (old_decl.is_glob_import(), decl.is_glob_import()) {
|
||||
(true, true) => {
|
||||
let (glob_binding, old_glob_binding) = (binding, old_binding);
|
||||
// FIXME: remove `!binding.is_ambiguity_recursive()` after delete the warning ambiguity.
|
||||
if !binding.is_ambiguity_recursive()
|
||||
&& let NameBindingKind::Import { import: old_import, .. } =
|
||||
old_glob_binding.kind
|
||||
&& let NameBindingKind::Import { import, .. } = glob_binding.kind
|
||||
let (glob_decl, old_glob_decl) = (decl, old_decl);
|
||||
// FIXME: remove `!decl.is_ambiguity_recursive()` after delete the warning ambiguity.
|
||||
if !decl.is_ambiguity_recursive()
|
||||
&& let DeclKind::Import { import: old_import, .. } = old_glob_decl.kind
|
||||
&& let DeclKind::Import { import, .. } = glob_decl.kind
|
||||
&& old_import == import
|
||||
{
|
||||
// When imported from the same glob-import statement, we should replace
|
||||
// `old_glob_binding` with `glob_binding`, regardless of whether
|
||||
// `old_glob_decl` with `glob_decl`, regardless of whether
|
||||
// they have the same resolution or not.
|
||||
resolution.glob_binding = Some(glob_binding);
|
||||
} else if res != old_glob_binding.res() {
|
||||
resolution.glob_binding = Some(this.new_ambiguity_binding(
|
||||
old_glob_binding,
|
||||
glob_binding,
|
||||
resolution.glob_decl = Some(glob_decl);
|
||||
} else if res != old_glob_decl.res() {
|
||||
resolution.glob_decl = Some(this.new_decl_with_ambiguity(
|
||||
old_glob_decl,
|
||||
glob_decl,
|
||||
warn_ambiguity,
|
||||
));
|
||||
} else if !old_binding.vis.is_at_least(binding.vis, this.tcx) {
|
||||
} else if !old_decl.vis.is_at_least(decl.vis, this.tcx) {
|
||||
// We are glob-importing the same item but with greater visibility.
|
||||
resolution.glob_binding = Some(glob_binding);
|
||||
} else if binding.is_ambiguity_recursive() {
|
||||
resolution.glob_binding =
|
||||
Some(this.new_warn_ambiguity_binding(glob_binding));
|
||||
resolution.glob_decl = Some(glob_decl);
|
||||
} else if decl.is_ambiguity_recursive() {
|
||||
resolution.glob_decl =
|
||||
Some(this.new_decl_with_warn_ambiguity(glob_decl));
|
||||
}
|
||||
}
|
||||
(old_glob @ true, false) | (old_glob @ false, true) => {
|
||||
let (glob_binding, non_glob_binding) =
|
||||
if old_glob { (old_binding, binding) } else { (binding, old_binding) };
|
||||
resolution.non_glob_binding = Some(non_glob_binding);
|
||||
if let Some(old_glob_binding) = resolution.glob_binding {
|
||||
assert!(old_glob_binding.is_glob_import());
|
||||
if glob_binding.res() != old_glob_binding.res() {
|
||||
resolution.glob_binding = Some(this.new_ambiguity_binding(
|
||||
old_glob_binding,
|
||||
glob_binding,
|
||||
let (glob_decl, non_glob_decl) =
|
||||
if old_glob { (old_decl, decl) } else { (decl, old_decl) };
|
||||
resolution.non_glob_decl = Some(non_glob_decl);
|
||||
if let Some(old_glob_decl) = resolution.glob_decl {
|
||||
assert!(old_glob_decl.is_glob_import());
|
||||
if glob_decl.res() != old_glob_decl.res() {
|
||||
resolution.glob_decl = Some(this.new_decl_with_ambiguity(
|
||||
old_glob_decl,
|
||||
glob_decl,
|
||||
false,
|
||||
));
|
||||
} else if !old_glob_binding.vis.is_at_least(binding.vis, this.tcx) {
|
||||
resolution.glob_binding = Some(glob_binding);
|
||||
} else if !old_glob_decl.vis.is_at_least(decl.vis, this.tcx) {
|
||||
resolution.glob_decl = Some(glob_decl);
|
||||
}
|
||||
} else {
|
||||
resolution.glob_binding = Some(glob_binding);
|
||||
resolution.glob_decl = Some(glob_decl);
|
||||
}
|
||||
}
|
||||
(false, false) => {
|
||||
return Err(old_binding);
|
||||
return Err(old_decl);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if binding.is_glob_import() {
|
||||
resolution.glob_binding = Some(binding);
|
||||
if decl.is_glob_import() {
|
||||
resolution.glob_decl = Some(decl);
|
||||
} else {
|
||||
resolution.non_glob_binding = Some(binding);
|
||||
resolution.non_glob_decl = Some(decl);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -419,20 +413,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
fn new_ambiguity_binding(
|
||||
fn new_decl_with_ambiguity(
|
||||
&self,
|
||||
primary_binding: NameBinding<'ra>,
|
||||
secondary_binding: NameBinding<'ra>,
|
||||
primary_decl: Decl<'ra>,
|
||||
secondary_decl: Decl<'ra>,
|
||||
warn_ambiguity: bool,
|
||||
) -> NameBinding<'ra> {
|
||||
let ambiguity = Some(secondary_binding);
|
||||
let data = NameBindingData { ambiguity, warn_ambiguity, ..*primary_binding };
|
||||
self.arenas.alloc_name_binding(data)
|
||||
) -> Decl<'ra> {
|
||||
let ambiguity = Some(secondary_decl);
|
||||
let data = DeclData { ambiguity, warn_ambiguity, ..*primary_decl };
|
||||
self.arenas.alloc_decl(data)
|
||||
}
|
||||
|
||||
fn new_warn_ambiguity_binding(&self, binding: NameBinding<'ra>) -> NameBinding<'ra> {
|
||||
assert!(binding.is_ambiguity_recursive());
|
||||
self.arenas.alloc_name_binding(NameBindingData { warn_ambiguity: true, ..*binding })
|
||||
fn new_decl_with_warn_ambiguity(&self, decl: Decl<'ra>) -> Decl<'ra> {
|
||||
assert!(decl.is_ambiguity_recursive());
|
||||
self.arenas.alloc_decl(DeclData { warn_ambiguity: true, ..*decl })
|
||||
}
|
||||
|
||||
// Use `f` to mutate the resolution of the name in the module.
|
||||
|
|
@ -451,14 +445,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
// during which the resolution might end up getting re-defined via a glob cycle.
|
||||
let (binding, t, warn_ambiguity) = {
|
||||
let resolution = &mut *self.resolution_or_default(module, key).borrow_mut_unchecked();
|
||||
let old_binding = resolution.binding();
|
||||
let old_decl = resolution.binding();
|
||||
|
||||
let t = f(self, resolution);
|
||||
|
||||
if let Some(binding) = resolution.binding()
|
||||
&& old_binding != Some(binding)
|
||||
&& old_decl != Some(binding)
|
||||
{
|
||||
(binding, t, warn_ambiguity || old_binding.is_some())
|
||||
(binding, t, warn_ambiguity || old_decl.is_some())
|
||||
} else {
|
||||
return t;
|
||||
}
|
||||
|
|
@ -477,12 +471,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
None => continue,
|
||||
};
|
||||
if self.is_accessible_from(binding.vis, scope) {
|
||||
let imported_binding = self.import(binding, *import);
|
||||
let _ = self.try_define_local(
|
||||
let import_decl = self.new_import_decl(binding, *import);
|
||||
let _ = self.try_plant_decl_into_local_module(
|
||||
import.parent_scope.module,
|
||||
ident.0,
|
||||
key.ns,
|
||||
imported_binding,
|
||||
import_decl,
|
||||
warn_ambiguity,
|
||||
);
|
||||
}
|
||||
|
|
@ -494,17 +488,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
// Define a dummy resolution containing a `Res::Err` as a placeholder for a failed
|
||||
// or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics.
|
||||
fn import_dummy_binding(&mut self, import: Import<'ra>, is_indeterminate: bool) {
|
||||
if let ImportKind::Single { target, ref bindings, .. } = import.kind {
|
||||
if !(is_indeterminate
|
||||
|| bindings.iter().all(|binding| binding.get().binding().is_none()))
|
||||
{
|
||||
if let ImportKind::Single { target, ref decls, .. } = import.kind {
|
||||
if !(is_indeterminate || decls.iter().all(|d| d.get().decl().is_none())) {
|
||||
return; // Has resolution, do not create the dummy binding
|
||||
}
|
||||
let dummy_binding = self.dummy_binding;
|
||||
let dummy_binding = self.import(dummy_binding, import);
|
||||
let dummy_decl = self.dummy_decl;
|
||||
let dummy_decl = self.new_import_decl(dummy_decl, import);
|
||||
self.per_ns(|this, ns| {
|
||||
let module = import.parent_scope.module;
|
||||
let _ = this.try_define_local(module, target, ns, dummy_binding, false);
|
||||
let _ =
|
||||
this.try_plant_decl_into_local_module(module, target, ns, dummy_decl, false);
|
||||
// Don't remove underscores from `single_imports`, they were never added.
|
||||
if target.name != kw::Underscore {
|
||||
let key = BindingKey::new(target, ns);
|
||||
|
|
@ -513,7 +506,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
})
|
||||
}
|
||||
});
|
||||
self.record_use(target, dummy_binding, Used::Other);
|
||||
self.record_use(target, dummy_decl, Used::Other);
|
||||
} else if import.imported_module.get().is_none() {
|
||||
self.import_use_map.insert(import, Used::Other);
|
||||
if let Some(id) = import.id() {
|
||||
|
|
@ -581,10 +574,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
|
||||
glob_error |= import.is_glob();
|
||||
|
||||
if let ImportKind::Single { source, ref bindings, .. } = import.kind
|
||||
if let ImportKind::Single { source, ref decls, .. } = import.kind
|
||||
&& source.name == kw::SelfLower
|
||||
// Silence `unresolved import` error if E0429 is already emitted
|
||||
&& let PendingBinding::Ready(None) = bindings.value_ns.get()
|
||||
&& let PendingDecl::Ready(None) = decls.value_ns.get()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -634,13 +627,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn lint_reexports(&mut self, exported_ambiguities: FxHashSet<NameBinding<'ra>>) {
|
||||
pub(crate) fn lint_reexports(&mut self, exported_ambiguities: FxHashSet<Decl<'ra>>) {
|
||||
for module in &self.local_modules {
|
||||
for (key, resolution) in self.resolutions(*module).borrow().iter() {
|
||||
let resolution = resolution.borrow();
|
||||
let Some(binding) = resolution.best_binding() else { continue };
|
||||
let Some(binding) = resolution.best_decl() else { continue };
|
||||
|
||||
if let NameBindingKind::Import { import, .. } = binding.kind
|
||||
if let DeclKind::Import { import, .. } = binding.kind
|
||||
&& let Some(amb_binding) = binding.ambiguity
|
||||
&& binding.res() != Res::Err
|
||||
&& exported_ambiguities.contains(&binding)
|
||||
|
|
@ -658,24 +651,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
if let Some(glob_binding) = resolution.glob_binding
|
||||
&& resolution.non_glob_binding.is_some()
|
||||
if let Some(glob_decl) = resolution.glob_decl
|
||||
&& resolution.non_glob_decl.is_some()
|
||||
{
|
||||
if binding.res() != Res::Err
|
||||
&& glob_binding.res() != Res::Err
|
||||
&& let NameBindingKind::Import { import: glob_import, .. } =
|
||||
glob_binding.kind
|
||||
&& glob_decl.res() != Res::Err
|
||||
&& let DeclKind::Import { import: glob_import, .. } = glob_decl.kind
|
||||
&& let Some(glob_import_id) = glob_import.id()
|
||||
&& let glob_import_def_id = self.local_def_id(glob_import_id)
|
||||
&& self.effective_visibilities.is_exported(glob_import_def_id)
|
||||
&& glob_binding.vis.is_public()
|
||||
&& glob_decl.vis.is_public()
|
||||
&& !binding.vis.is_public()
|
||||
{
|
||||
let binding_id = match binding.kind {
|
||||
NameBindingKind::Res(res) => {
|
||||
DeclKind::Def(res) => {
|
||||
Some(self.def_id_to_node_id(res.def_id().expect_local()))
|
||||
}
|
||||
NameBindingKind::Import { import, .. } => import.id(),
|
||||
DeclKind::Import { import, .. } => import.id(),
|
||||
};
|
||||
if let Some(binding_id) = binding_id {
|
||||
self.lint_buffer.buffer_lint(
|
||||
|
|
@ -685,7 +677,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
BuiltinLintDiag::HiddenGlobReexports {
|
||||
name: key.ident.name.to_string(),
|
||||
namespace: key.ns.descr().to_owned(),
|
||||
glob_reexport_span: glob_binding.span,
|
||||
glob_reexport_span: glob_decl.span,
|
||||
private_item_span: binding.span,
|
||||
},
|
||||
);
|
||||
|
|
@ -693,7 +685,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
if let NameBindingKind::Import { import, .. } = binding.kind
|
||||
if let DeclKind::Import { import, .. } = binding.kind
|
||||
&& let Some(binding_id) = import.id()
|
||||
&& let import_def_id = self.local_def_id(binding_id)
|
||||
&& self.effective_visibilities.is_exported(import_def_id)
|
||||
|
|
@ -846,8 +838,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
|
||||
import.imported_module.set_unchecked(Some(module));
|
||||
let (source, target, bindings, type_ns_only) = match import.kind {
|
||||
ImportKind::Single { source, target, ref bindings, type_ns_only, .. } => {
|
||||
(source, target, bindings, type_ns_only)
|
||||
ImportKind::Single { source, target, ref decls, type_ns_only, .. } => {
|
||||
(source, target, decls, type_ns_only)
|
||||
}
|
||||
ImportKind::Glob { .. } => {
|
||||
self.get_mut_unchecked().resolve_glob_import(import);
|
||||
|
|
@ -859,7 +851,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
let mut indeterminate_count = 0;
|
||||
self.per_ns_cm(|this, ns| {
|
||||
if !type_ns_only || ns == TypeNS {
|
||||
if bindings[ns].get() != PendingBinding::Pending {
|
||||
if bindings[ns].get() != PendingDecl::Pending {
|
||||
return;
|
||||
};
|
||||
let binding_result = this.reborrow().maybe_resolve_ident_in_module(
|
||||
|
|
@ -884,14 +876,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
.emit();
|
||||
}
|
||||
// We need the `target`, `source` can be extracted.
|
||||
let imported_binding = this.import(binding, import);
|
||||
this.get_mut_unchecked().define_binding_local(
|
||||
let import_decl = this.new_import_decl(binding, import);
|
||||
this.get_mut_unchecked().plant_decl_into_local_module(
|
||||
parent,
|
||||
target,
|
||||
ns,
|
||||
imported_binding,
|
||||
import_decl,
|
||||
);
|
||||
PendingBinding::Ready(Some(imported_binding))
|
||||
PendingDecl::Ready(Some(import_decl))
|
||||
}
|
||||
Err(Determinacy::Determined) => {
|
||||
// Don't remove underscores from `single_imports`, they were never added.
|
||||
|
|
@ -906,11 +898,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
},
|
||||
);
|
||||
}
|
||||
PendingBinding::Ready(None)
|
||||
PendingDecl::Ready(None)
|
||||
}
|
||||
Err(Determinacy::Undetermined) => {
|
||||
indeterminate_count += 1;
|
||||
PendingBinding::Pending
|
||||
PendingDecl::Pending
|
||||
}
|
||||
};
|
||||
bindings[ns].set_unchecked(binding);
|
||||
|
|
@ -925,8 +917,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
/// Optionally returns an unresolved import error. This error is buffered and used to
|
||||
/// consolidate multiple unresolved import errors into a single diagnostic.
|
||||
fn finalize_import(&mut self, import: Import<'ra>) -> Option<UnresolvedImportError> {
|
||||
let ignore_binding = match &import.kind {
|
||||
ImportKind::Single { bindings, .. } => bindings[TypeNS].get().binding(),
|
||||
let ignore_decl = match &import.kind {
|
||||
ImportKind::Single { decls, .. } => decls[TypeNS].get().decl(),
|
||||
_ => None,
|
||||
};
|
||||
let ambiguity_errors_len =
|
||||
|
|
@ -942,7 +934,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
None,
|
||||
&import.parent_scope,
|
||||
Some(finalize),
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
Some(import),
|
||||
);
|
||||
|
||||
|
|
@ -1045,8 +1037,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
};
|
||||
|
||||
let (ident, target, bindings, type_ns_only, import_id) = match import.kind {
|
||||
ImportKind::Single { source, target, ref bindings, type_ns_only, id, .. } => {
|
||||
(source, target, bindings, type_ns_only, id)
|
||||
ImportKind::Single { source, target, ref decls, type_ns_only, id, .. } => {
|
||||
(source, target, decls, type_ns_only, id)
|
||||
}
|
||||
ImportKind::Glob { ref max_vis, id } => {
|
||||
if import.module_path.len() <= 1 {
|
||||
|
|
@ -1102,7 +1094,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
None,
|
||||
&import.parent_scope,
|
||||
Some(finalize),
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
None,
|
||||
) {
|
||||
let res = module.res().map(|r| (r, ident));
|
||||
|
|
@ -1121,14 +1113,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
ns,
|
||||
&import.parent_scope,
|
||||
Some(Finalize { report_private: false, ..finalize }),
|
||||
bindings[ns].get().binding(),
|
||||
bindings[ns].get().decl(),
|
||||
Some(import),
|
||||
);
|
||||
|
||||
match binding {
|
||||
Ok(binding) => {
|
||||
// Consistency checks, analogous to `finalize_macro_resolutions`.
|
||||
let initial_res = bindings[ns].get().binding().map(|binding| {
|
||||
let initial_res = bindings[ns].get().decl().map(|binding| {
|
||||
let initial_binding = binding.import_source();
|
||||
all_ns_err = false;
|
||||
if target.name == kw::Underscore
|
||||
|
|
@ -1205,13 +1197,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
} // Never suggest the same name
|
||||
|
||||
let resolution = resolution.borrow();
|
||||
if let Some(name_binding) = resolution.best_binding() {
|
||||
if let Some(name_binding) = resolution.best_decl() {
|
||||
match name_binding.kind {
|
||||
NameBindingKind::Import { binding, .. } => {
|
||||
match binding.kind {
|
||||
// Never suggest the name that has binding error
|
||||
// i.e., the name that cannot be previously resolved
|
||||
NameBindingKind::Res(Res::Err) => None,
|
||||
DeclKind::Import { source_decl, .. } => {
|
||||
match source_decl.kind {
|
||||
// Never suggest names that previously could not
|
||||
// be resolved.
|
||||
DeclKind::Def(Res::Err) => None,
|
||||
_ => Some(i.name),
|
||||
}
|
||||
}
|
||||
|
|
@ -1295,7 +1287,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
let mut any_successful_reexport = false;
|
||||
let mut crate_private_reexport = false;
|
||||
self.per_ns(|this, ns| {
|
||||
let Some(binding) = bindings[ns].get().binding().map(|b| b.import_source()) else {
|
||||
let Some(binding) = bindings[ns].get().decl().map(|b| b.import_source()) else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
|
@ -1342,7 +1334,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
};
|
||||
|
||||
match binding.kind {
|
||||
NameBindingKind::Res(Res::Def(DefKind::Macro(_), def_id))
|
||||
DeclKind::Def(Res::Def(DefKind::Macro(_), def_id))
|
||||
// exclude decl_macro
|
||||
if self.get_macro_by_def_id(def_id).macro_rules =>
|
||||
{
|
||||
|
|
@ -1370,7 +1362,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
let mut full_path = import.module_path.clone();
|
||||
full_path.push(Segment::from_ident(ident));
|
||||
self.per_ns(|this, ns| {
|
||||
if let Some(binding) = bindings[ns].get().binding().map(|b| b.import_source()) {
|
||||
if let Some(binding) = bindings[ns].get().decl().map(|b| b.import_source()) {
|
||||
this.lint_if_path_starts_with_module(finalize, &full_path, Some(binding));
|
||||
}
|
||||
});
|
||||
|
|
@ -1380,7 +1372,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
// this may resolve to either a value or a type, but for documentation
|
||||
// purposes it's good enough to just favor one over the other.
|
||||
self.per_ns(|this, ns| {
|
||||
if let Some(binding) = bindings[ns].get().binding().map(|b| b.import_source()) {
|
||||
if let Some(binding) = bindings[ns].get().decl().map(|b| b.import_source()) {
|
||||
this.import_res_map.entry(import_id).or_default()[ns] = Some(binding.res());
|
||||
}
|
||||
});
|
||||
|
|
@ -1391,7 +1383,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
|
||||
pub(crate) fn check_for_redundant_imports(&mut self, import: Import<'ra>) -> bool {
|
||||
// This function is only called for single imports.
|
||||
let ImportKind::Single { source, target, ref bindings, id, .. } = import.kind else {
|
||||
let ImportKind::Single { source, target, ref decls, id, .. } = import.kind else {
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
|
|
@ -1418,7 +1410,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
let mut is_redundant = true;
|
||||
let mut redundant_span = PerNS { value_ns: None, type_ns: None, macro_ns: None };
|
||||
self.per_ns(|this, ns| {
|
||||
let binding = bindings[ns].get().binding().map(|b| b.import_source());
|
||||
let binding = decls[ns].get().decl().map(|b| b.import_source());
|
||||
if is_redundant && let Some(binding) = binding {
|
||||
if binding.res() == Res::Err {
|
||||
return;
|
||||
|
|
@ -1430,7 +1422,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
&import.parent_scope,
|
||||
None,
|
||||
false,
|
||||
bindings[ns].get().binding(),
|
||||
decls[ns].get().decl(),
|
||||
None,
|
||||
) {
|
||||
Ok(other_binding) => {
|
||||
|
|
@ -1505,16 +1497,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
None => continue,
|
||||
};
|
||||
if self.is_accessible_from(binding.vis, scope) {
|
||||
let imported_binding = self.import(binding, import);
|
||||
let import_decl = self.new_import_decl(binding, import);
|
||||
let warn_ambiguity = self
|
||||
.resolution(import.parent_scope.module, key)
|
||||
.and_then(|r| r.binding())
|
||||
.is_some_and(|binding| binding.warn_ambiguity_recursive());
|
||||
let _ = self.try_define_local(
|
||||
let _ = self.try_plant_decl_into_local_module(
|
||||
import.parent_scope.module,
|
||||
key.ident.0,
|
||||
key.ns,
|
||||
imported_binding,
|
||||
import_decl,
|
||||
warn_ambiguity,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,9 +43,9 @@ use thin_vec::ThinVec;
|
|||
use tracing::{debug, instrument, trace};
|
||||
|
||||
use crate::{
|
||||
BindingError, BindingKey, Finalize, LexicalScopeBinding, Module, ModuleOrUniformRoot,
|
||||
NameBinding, ParentScope, PathResult, ResolutionError, Resolver, Segment, Stage, TyCtxt,
|
||||
UseError, Used, errors, path_names_to_string, rustdoc,
|
||||
BindingError, BindingKey, Decl, Finalize, LateDecl, Module, ModuleOrUniformRoot, ParentScope,
|
||||
PathResult, ResolutionError, Resolver, Segment, Stage, TyCtxt, UseError, Used, errors,
|
||||
path_names_to_string, rustdoc,
|
||||
};
|
||||
|
||||
mod diagnostics;
|
||||
|
|
@ -677,7 +677,7 @@ impl MaybeExported<'_> {
|
|||
/// Used for recording UnnecessaryQualification.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct UnnecessaryQualification<'ra> {
|
||||
pub binding: LexicalScopeBinding<'ra>,
|
||||
pub decl: LateDecl<'ra>,
|
||||
pub node_id: NodeId,
|
||||
pub path_span: Span,
|
||||
pub removal_span: Span,
|
||||
|
|
@ -1472,7 +1472,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
&mut self,
|
||||
ident: Ident,
|
||||
ns: Namespace,
|
||||
) -> Option<LexicalScopeBinding<'ra>> {
|
||||
) -> Option<LateDecl<'ra>> {
|
||||
self.r.resolve_ident_in_lexical_scope(
|
||||
ident,
|
||||
ns,
|
||||
|
|
@ -1489,15 +1489,15 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
ident: Ident,
|
||||
ns: Namespace,
|
||||
finalize: Option<Finalize>,
|
||||
ignore_binding: Option<NameBinding<'ra>>,
|
||||
) -> Option<LexicalScopeBinding<'ra>> {
|
||||
ignore_decl: Option<Decl<'ra>>,
|
||||
) -> Option<LateDecl<'ra>> {
|
||||
self.r.resolve_ident_in_lexical_scope(
|
||||
ident,
|
||||
ns,
|
||||
&self.parent_scope,
|
||||
finalize,
|
||||
&self.ribs[ns],
|
||||
ignore_binding,
|
||||
ignore_decl,
|
||||
Some(&self.diag_metadata),
|
||||
)
|
||||
}
|
||||
|
|
@ -2685,11 +2685,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
|
||||
for &ns in nss {
|
||||
match self.maybe_resolve_ident_in_lexical_scope(ident, ns) {
|
||||
Some(LexicalScopeBinding::Res(..)) => {
|
||||
Some(LateDecl::RibDef(..)) => {
|
||||
report_error(self, ns);
|
||||
}
|
||||
Some(LexicalScopeBinding::Item(binding)) => {
|
||||
if let Some(LexicalScopeBinding::Res(..)) =
|
||||
Some(LateDecl::Decl(binding)) => {
|
||||
if let Some(LateDecl::RibDef(..)) =
|
||||
self.resolve_ident_in_lexical_scope(ident, ns, None, Some(binding))
|
||||
{
|
||||
report_error(self, ns);
|
||||
|
|
@ -3630,9 +3630,9 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
};
|
||||
ident.span.normalize_to_macros_2_0_and_adjust(module.expansion);
|
||||
let key = BindingKey::new(ident, ns);
|
||||
let mut binding = self.r.resolution(module, key).and_then(|r| r.best_binding());
|
||||
debug!(?binding);
|
||||
if binding.is_none() {
|
||||
let mut decl = self.r.resolution(module, key).and_then(|r| r.best_decl());
|
||||
debug!(?decl);
|
||||
if decl.is_none() {
|
||||
// We could not find the trait item in the correct namespace.
|
||||
// Check the other namespace to report an error.
|
||||
let ns = match ns {
|
||||
|
|
@ -3641,8 +3641,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
_ => ns,
|
||||
};
|
||||
let key = BindingKey::new(ident, ns);
|
||||
binding = self.r.resolution(module, key).and_then(|r| r.best_binding());
|
||||
debug!(?binding);
|
||||
decl = self.r.resolution(module, key).and_then(|r| r.best_decl());
|
||||
debug!(?decl);
|
||||
}
|
||||
|
||||
let feed_visibility = |this: &mut Self, def_id| {
|
||||
|
|
@ -3659,7 +3659,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
this.r.feed_visibility(this.r.feed(id), vis);
|
||||
};
|
||||
|
||||
let Some(binding) = binding else {
|
||||
let Some(decl) = decl else {
|
||||
// We could not find the method: report an error.
|
||||
let candidate = self.find_similarly_named_assoc_item(ident.name, kind);
|
||||
let path = &self.current_trait_ref.as_ref().unwrap().1.path;
|
||||
|
|
@ -3669,7 +3669,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
return;
|
||||
};
|
||||
|
||||
let res = binding.res();
|
||||
let res = decl.res();
|
||||
let Res::Def(def_kind, id_in_trait) = res else { bug!() };
|
||||
feed_visibility(self, id_in_trait);
|
||||
|
||||
|
|
@ -3680,7 +3680,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
ResolutionError::TraitImplDuplicate {
|
||||
name: ident,
|
||||
old_span: *entry.get(),
|
||||
trait_item_span: binding.span,
|
||||
trait_item_span: decl.span,
|
||||
},
|
||||
);
|
||||
return;
|
||||
|
|
@ -3720,7 +3720,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
kind,
|
||||
code,
|
||||
trait_path,
|
||||
trait_item_span: binding.span,
|
||||
trait_item_span: decl.span,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
@ -4257,7 +4257,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
|
||||
let ls_binding = self.maybe_resolve_ident_in_lexical_scope(ident, ValueNS)?;
|
||||
let (res, binding) = match ls_binding {
|
||||
LexicalScopeBinding::Item(binding)
|
||||
LateDecl::Decl(binding)
|
||||
if is_syntactic_ambiguity && binding.is_ambiguity_recursive() =>
|
||||
{
|
||||
// For ambiguous bindings we don't know all their definitions and cannot check
|
||||
|
|
@ -4267,8 +4267,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
self.r.record_use(ident, binding, Used::Other);
|
||||
return None;
|
||||
}
|
||||
LexicalScopeBinding::Item(binding) => (binding.res(), Some(binding)),
|
||||
LexicalScopeBinding::Res(res) => (res, None),
|
||||
LateDecl::Decl(binding) => (binding.res(), Some(binding)),
|
||||
LateDecl::RibDef(res) => (res, None),
|
||||
};
|
||||
|
||||
match res {
|
||||
|
|
@ -4641,13 +4641,13 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
fn self_type_is_available(&mut self) -> bool {
|
||||
let binding = self
|
||||
.maybe_resolve_ident_in_lexical_scope(Ident::with_dummy_span(kw::SelfUpper), TypeNS);
|
||||
if let Some(LexicalScopeBinding::Res(res)) = binding { res != Res::Err } else { false }
|
||||
if let Some(LateDecl::RibDef(res)) = binding { res != Res::Err } else { false }
|
||||
}
|
||||
|
||||
fn self_value_is_available(&mut self, self_span: Span) -> bool {
|
||||
let ident = Ident::new(kw::SelfLower, self_span);
|
||||
let binding = self.maybe_resolve_ident_in_lexical_scope(ident, ValueNS);
|
||||
if let Some(LexicalScopeBinding::Res(res)) = binding { res != Res::Err } else { false }
|
||||
if let Some(LateDecl::RibDef(res)) = binding { res != Res::Err } else { false }
|
||||
}
|
||||
|
||||
/// A wrapper around [`Resolver::report_error`].
|
||||
|
|
@ -5356,9 +5356,9 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
(res == binding.res()).then_some((seg, binding))
|
||||
});
|
||||
|
||||
if let Some((seg, binding)) = unqualified {
|
||||
if let Some((seg, decl)) = unqualified {
|
||||
self.r.potentially_unnecessary_qualifications.push(UnnecessaryQualification {
|
||||
binding,
|
||||
decl,
|
||||
node_id: finalize.node_id,
|
||||
path_span: finalize.path_span,
|
||||
removal_span: path[0].ident.span.until(seg.ident.span),
|
||||
|
|
|
|||
|
|
@ -891,10 +891,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
|||
fn lookup_doc_alias_name(&mut self, path: &[Segment], ns: Namespace) -> Option<(DefId, Ident)> {
|
||||
let find_doc_alias_name = |r: &mut Resolver<'ra, '_>, m: Module<'ra>, item_name: Symbol| {
|
||||
for resolution in r.resolutions(m).borrow().values() {
|
||||
let Some(did) = resolution
|
||||
.borrow()
|
||||
.best_binding()
|
||||
.and_then(|binding| binding.res().opt_def_id())
|
||||
let Some(did) =
|
||||
resolution.borrow().best_decl().and_then(|binding| binding.res().opt_def_id())
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
|
@ -1589,19 +1587,17 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
|||
if let PathResult::Module(ModuleOrUniformRoot::Module(module)) =
|
||||
self.resolve_path(mod_path, None, None, *source)
|
||||
{
|
||||
let targets: Vec<_> = self
|
||||
.r
|
||||
.resolutions(module)
|
||||
.borrow()
|
||||
.iter()
|
||||
.filter_map(|(key, resolution)| {
|
||||
resolution
|
||||
.borrow()
|
||||
.best_binding()
|
||||
.map(|binding| binding.res())
|
||||
.and_then(|res| if filter_fn(res) { Some((*key, res)) } else { None })
|
||||
})
|
||||
.collect();
|
||||
let targets: Vec<_> =
|
||||
self.r
|
||||
.resolutions(module)
|
||||
.borrow()
|
||||
.iter()
|
||||
.filter_map(|(key, resolution)| {
|
||||
resolution.borrow().best_decl().map(|binding| binding.res()).and_then(
|
||||
|res| if filter_fn(res) { Some((*key, res)) } else { None },
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
if let [target] = targets.as_slice() {
|
||||
return Some(TypoSuggestion::single_item_from_ident(
|
||||
target.0.ident.0,
|
||||
|
|
@ -2486,9 +2482,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
|||
.resolutions(*module)
|
||||
.borrow()
|
||||
.iter()
|
||||
.filter_map(|(key, res)| {
|
||||
res.borrow().best_binding().map(|binding| (key, binding.res()))
|
||||
})
|
||||
.filter_map(|(key, res)| res.borrow().best_decl().map(|binding| (key, binding.res())))
|
||||
.filter(|(_, res)| match (kind, res) {
|
||||
(AssocItemKind::Const(..), Res::Def(DefKind::AssocConst, _)) => true,
|
||||
(AssocItemKind::Fn(_), Res::Def(DefKind::AssocFn, _)) => true,
|
||||
|
|
|
|||
|
|
@ -33,12 +33,12 @@ use std::sync::Arc;
|
|||
use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
|
||||
use effective_visibilities::EffectiveVisibilitiesVisitor;
|
||||
use errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
|
||||
use imports::{Import, ImportData, ImportKind, NameResolution, PendingBinding};
|
||||
use imports::{Import, ImportData, ImportKind, NameResolution, PendingDecl};
|
||||
use late::{
|
||||
ForwardGenericParamBanReason, HasGenericParams, PathSource, PatternSource,
|
||||
UnnecessaryQualification,
|
||||
};
|
||||
use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
|
||||
use macros::{MacroRulesDecl, MacroRulesScope, MacroRulesScopeRef};
|
||||
use rustc_arena::{DroplessArena, TypedArena};
|
||||
use rustc_ast::node_id::NodeMap;
|
||||
use rustc_ast::{
|
||||
|
|
@ -424,22 +424,21 @@ impl<'a> From<&'a ast::PathSegment> for Segment {
|
|||
}
|
||||
}
|
||||
|
||||
/// An intermediate resolution result.
|
||||
///
|
||||
/// This refers to the thing referred by a name. The difference between `Res` and `Item` is that
|
||||
/// items are visible in their whole block, while `Res`es only from the place they are defined
|
||||
/// forward.
|
||||
/// Name declaration used during late resolution.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
enum LexicalScopeBinding<'ra> {
|
||||
Item(NameBinding<'ra>),
|
||||
Res(Res),
|
||||
enum LateDecl<'ra> {
|
||||
/// A regular name declaration.
|
||||
Decl(Decl<'ra>),
|
||||
/// A name definition from a rib, e.g. a local variable.
|
||||
/// Omits most of the data from regular `Decl` for performance reasons.
|
||||
RibDef(Res),
|
||||
}
|
||||
|
||||
impl<'ra> LexicalScopeBinding<'ra> {
|
||||
impl<'ra> LateDecl<'ra> {
|
||||
fn res(self) -> Res {
|
||||
match self {
|
||||
LexicalScopeBinding::Item(binding) => binding.res(),
|
||||
LexicalScopeBinding::Res(res) => res,
|
||||
LateDecl::Decl(binding) => binding.res(),
|
||||
LateDecl::RibDef(res) => res,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -624,17 +623,16 @@ struct ModuleData<'ra> {
|
|||
globs: CmRefCell<Vec<Import<'ra>>>,
|
||||
|
||||
/// Used to memoize the traits in this module for faster searches through all traits in scope.
|
||||
traits:
|
||||
CmRefCell<Option<Box<[(Macros20NormalizedIdent, NameBinding<'ra>, Option<Module<'ra>>)]>>>,
|
||||
traits: CmRefCell<Option<Box<[(Macros20NormalizedIdent, Decl<'ra>, Option<Module<'ra>>)]>>>,
|
||||
|
||||
/// Span of the module itself. Used for error reporting.
|
||||
span: Span,
|
||||
|
||||
expansion: ExpnId,
|
||||
|
||||
/// Binding for implicitly declared names that come with a module,
|
||||
/// Declaration for implicitly declared names that come with a module,
|
||||
/// like `self` (not yet used), or `crate`/`$crate` (for root modules).
|
||||
self_binding: Option<NameBinding<'ra>>,
|
||||
self_decl: Option<Decl<'ra>>,
|
||||
}
|
||||
|
||||
/// All modules are unique and allocated on a same arena,
|
||||
|
|
@ -663,7 +661,7 @@ impl<'ra> ModuleData<'ra> {
|
|||
expansion: ExpnId,
|
||||
span: Span,
|
||||
no_implicit_prelude: bool,
|
||||
self_binding: Option<NameBinding<'ra>>,
|
||||
self_decl: Option<Decl<'ra>>,
|
||||
) -> Self {
|
||||
let is_foreign = match kind {
|
||||
ModuleKind::Def(_, def_id, _) => !def_id.is_local(),
|
||||
|
|
@ -682,7 +680,7 @@ impl<'ra> ModuleData<'ra> {
|
|||
traits: CmRefCell::new(None),
|
||||
span,
|
||||
expansion,
|
||||
self_binding,
|
||||
self_decl,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -691,11 +689,11 @@ impl<'ra> Module<'ra> {
|
|||
fn for_each_child<'tcx, R: AsRef<Resolver<'ra, 'tcx>>>(
|
||||
self,
|
||||
resolver: &R,
|
||||
mut f: impl FnMut(&R, Macros20NormalizedIdent, Namespace, NameBinding<'ra>),
|
||||
mut f: impl FnMut(&R, Macros20NormalizedIdent, Namespace, Decl<'ra>),
|
||||
) {
|
||||
for (key, name_resolution) in resolver.as_ref().resolutions(self).borrow().iter() {
|
||||
if let Some(binding) = name_resolution.borrow().best_binding() {
|
||||
f(resolver, key.ident, key.ns, binding);
|
||||
if let Some(decl) = name_resolution.borrow().best_decl() {
|
||||
f(resolver, key.ident, key.ns, decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -703,11 +701,11 @@ impl<'ra> Module<'ra> {
|
|||
fn for_each_child_mut<'tcx, R: AsMut<Resolver<'ra, 'tcx>>>(
|
||||
self,
|
||||
resolver: &mut R,
|
||||
mut f: impl FnMut(&mut R, Macros20NormalizedIdent, Namespace, NameBinding<'ra>),
|
||||
mut f: impl FnMut(&mut R, Macros20NormalizedIdent, Namespace, Decl<'ra>),
|
||||
) {
|
||||
for (key, name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() {
|
||||
if let Some(binding) = name_resolution.borrow().best_binding() {
|
||||
f(resolver, key.ident, key.ns, binding);
|
||||
if let Some(decl) = name_resolution.borrow().best_decl() {
|
||||
f(resolver, key.ident, key.ns, decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -803,11 +801,11 @@ impl<'ra> fmt::Debug for Module<'ra> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Records a possibly-private value, type, or module definition.
|
||||
/// Data associated with any name declaration.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
struct NameBindingData<'ra> {
|
||||
kind: NameBindingKind<'ra>,
|
||||
ambiguity: Option<NameBinding<'ra>>,
|
||||
struct DeclData<'ra> {
|
||||
kind: DeclKind<'ra>,
|
||||
ambiguity: Option<Decl<'ra>>,
|
||||
/// Produce a warning instead of an error when reporting ambiguities inside this binding.
|
||||
/// May apply to indirect ambiguities under imports, so `ambiguity.is_some()` is not required.
|
||||
warn_ambiguity: bool,
|
||||
|
|
@ -816,15 +814,15 @@ struct NameBindingData<'ra> {
|
|||
vis: Visibility<DefId>,
|
||||
}
|
||||
|
||||
/// All name bindings are unique and allocated on a same arena,
|
||||
/// All name declarations are unique and allocated on a same arena,
|
||||
/// so we can use referential equality to compare them.
|
||||
type NameBinding<'ra> = Interned<'ra, NameBindingData<'ra>>;
|
||||
type Decl<'ra> = Interned<'ra, DeclData<'ra>>;
|
||||
|
||||
// Allows us to use Interned without actually enforcing (via Hash/PartialEq/...) uniqueness of the
|
||||
// contained data.
|
||||
// FIXME: We may wish to actually have at least debug-level assertions that Interned's guarantees
|
||||
// are upheld.
|
||||
impl std::hash::Hash for NameBindingData<'_> {
|
||||
impl std::hash::Hash for DeclData<'_> {
|
||||
fn hash<H>(&self, _: &mut H)
|
||||
where
|
||||
H: std::hash::Hasher,
|
||||
|
|
@ -833,23 +831,27 @@ impl std::hash::Hash for NameBindingData<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Name declaration kind.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
enum NameBindingKind<'ra> {
|
||||
Res(Res),
|
||||
Import { binding: NameBinding<'ra>, import: Import<'ra> },
|
||||
enum DeclKind<'ra> {
|
||||
/// The name declaration is a definition (possibly without a `DefId`),
|
||||
/// can be provided by source code or built into the language.
|
||||
Def(Res),
|
||||
/// The name declaration is a link to another name declaration.
|
||||
Import { source_decl: Decl<'ra>, import: Import<'ra> },
|
||||
}
|
||||
|
||||
impl<'ra> NameBindingKind<'ra> {
|
||||
/// Is this a name binding of an import?
|
||||
impl<'ra> DeclKind<'ra> {
|
||||
/// Is this an import declaration?
|
||||
fn is_import(&self) -> bool {
|
||||
matches!(*self, NameBindingKind::Import { .. })
|
||||
matches!(*self, DeclKind::Import { .. })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct PrivacyError<'ra> {
|
||||
ident: Ident,
|
||||
binding: NameBinding<'ra>,
|
||||
decl: Decl<'ra>,
|
||||
dedup_span: Span,
|
||||
outermost_res: Option<(Res, Ident)>,
|
||||
parent_scope: ParentScope<'ra>,
|
||||
|
|
@ -912,36 +914,34 @@ impl AmbiguityKind {
|
|||
struct AmbiguityError<'ra> {
|
||||
kind: AmbiguityKind,
|
||||
ident: Ident,
|
||||
b1: NameBinding<'ra>,
|
||||
b2: NameBinding<'ra>,
|
||||
b1: Decl<'ra>,
|
||||
b2: Decl<'ra>,
|
||||
// `empty_module` in module scope serves as an unknown module here.
|
||||
scope1: Scope<'ra>,
|
||||
scope2: Scope<'ra>,
|
||||
warning: bool,
|
||||
}
|
||||
|
||||
impl<'ra> NameBindingData<'ra> {
|
||||
impl<'ra> DeclData<'ra> {
|
||||
fn res(&self) -> Res {
|
||||
match self.kind {
|
||||
NameBindingKind::Res(res) => res,
|
||||
NameBindingKind::Import { binding, .. } => binding.res(),
|
||||
DeclKind::Def(res) => res,
|
||||
DeclKind::Import { source_decl, .. } => source_decl.res(),
|
||||
}
|
||||
}
|
||||
|
||||
fn import_source(&self) -> NameBinding<'ra> {
|
||||
fn import_source(&self) -> Decl<'ra> {
|
||||
match self.kind {
|
||||
NameBindingKind::Import { binding, .. } => binding,
|
||||
DeclKind::Import { source_decl, .. } => source_decl,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn descent_to_ambiguity(
|
||||
self: NameBinding<'ra>,
|
||||
) -> Option<(NameBinding<'ra>, NameBinding<'ra>)> {
|
||||
fn descent_to_ambiguity(self: Decl<'ra>) -> Option<(Decl<'ra>, Decl<'ra>)> {
|
||||
match self.ambiguity {
|
||||
Some(ambig_binding) => Some((self, ambig_binding)),
|
||||
None => match self.kind {
|
||||
NameBindingKind::Import { binding, .. } => binding.descent_to_ambiguity(),
|
||||
DeclKind::Import { source_decl, .. } => source_decl.descent_to_ambiguity(),
|
||||
_ => None,
|
||||
},
|
||||
}
|
||||
|
|
@ -950,7 +950,7 @@ impl<'ra> NameBindingData<'ra> {
|
|||
fn is_ambiguity_recursive(&self) -> bool {
|
||||
self.ambiguity.is_some()
|
||||
|| match self.kind {
|
||||
NameBindingKind::Import { binding, .. } => binding.is_ambiguity_recursive(),
|
||||
DeclKind::Import { source_decl, .. } => source_decl.is_ambiguity_recursive(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -958,46 +958,45 @@ impl<'ra> NameBindingData<'ra> {
|
|||
fn warn_ambiguity_recursive(&self) -> bool {
|
||||
self.warn_ambiguity
|
||||
|| match self.kind {
|
||||
NameBindingKind::Import { binding, .. } => binding.warn_ambiguity_recursive(),
|
||||
DeclKind::Import { source_decl, .. } => source_decl.warn_ambiguity_recursive(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_possibly_imported_variant(&self) -> bool {
|
||||
match self.kind {
|
||||
NameBindingKind::Import { binding, .. } => binding.is_possibly_imported_variant(),
|
||||
NameBindingKind::Res(Res::Def(
|
||||
DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..),
|
||||
_,
|
||||
)) => true,
|
||||
NameBindingKind::Res(..) => false,
|
||||
DeclKind::Import { source_decl, .. } => source_decl.is_possibly_imported_variant(),
|
||||
DeclKind::Def(Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..), _)) => {
|
||||
true
|
||||
}
|
||||
DeclKind::Def(..) => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_extern_crate(&self) -> bool {
|
||||
match self.kind {
|
||||
NameBindingKind::Import { import, .. } => {
|
||||
DeclKind::Import { import, .. } => {
|
||||
matches!(import.kind, ImportKind::ExternCrate { .. })
|
||||
}
|
||||
NameBindingKind::Res(Res::Def(_, def_id)) => def_id.is_crate_root(),
|
||||
DeclKind::Def(Res::Def(_, def_id)) => def_id.is_crate_root(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_import(&self) -> bool {
|
||||
matches!(self.kind, NameBindingKind::Import { .. })
|
||||
matches!(self.kind, DeclKind::Import { .. })
|
||||
}
|
||||
|
||||
/// The binding introduced by `#[macro_export] macro_rules` is a public import, but it might
|
||||
/// not be perceived as such by users, so treat it as a non-import in some diagnostics.
|
||||
fn is_import_user_facing(&self) -> bool {
|
||||
matches!(self.kind, NameBindingKind::Import { import, .. }
|
||||
matches!(self.kind, DeclKind::Import { import, .. }
|
||||
if !matches!(import.kind, ImportKind::MacroExport))
|
||||
}
|
||||
|
||||
fn is_glob_import(&self) -> bool {
|
||||
match self.kind {
|
||||
NameBindingKind::Import { import, .. } => import.is_glob(),
|
||||
DeclKind::Import { import, .. } => import.is_glob(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -1010,12 +1009,12 @@ impl<'ra> NameBindingData<'ra> {
|
|||
self.res().macro_kinds()
|
||||
}
|
||||
|
||||
fn reexport_chain(self: NameBinding<'ra>, r: &Resolver<'_, '_>) -> SmallVec<[Reexport; 2]> {
|
||||
fn reexport_chain(self: Decl<'ra>, r: &Resolver<'_, '_>) -> SmallVec<[Reexport; 2]> {
|
||||
let mut reexport_chain = SmallVec::new();
|
||||
let mut next_binding = self;
|
||||
while let NameBindingKind::Import { binding, import, .. } = next_binding.kind {
|
||||
while let DeclKind::Import { source_decl, import, .. } = next_binding.kind {
|
||||
reexport_chain.push(import.simplify(r));
|
||||
next_binding = binding;
|
||||
next_binding = source_decl;
|
||||
}
|
||||
reexport_chain
|
||||
}
|
||||
|
|
@ -1026,16 +1025,12 @@ impl<'ra> NameBindingData<'ra> {
|
|||
// in some later round and screw up our previously found resolution.
|
||||
// See more detailed explanation in
|
||||
// https://github.com/rust-lang/rust/pull/53778#issuecomment-419224049
|
||||
fn may_appear_after(
|
||||
&self,
|
||||
invoc_parent_expansion: LocalExpnId,
|
||||
binding: NameBinding<'_>,
|
||||
) -> bool {
|
||||
// self > max(invoc, binding) => !(self <= invoc || self <= binding)
|
||||
fn may_appear_after(&self, invoc_parent_expansion: LocalExpnId, decl: Decl<'_>) -> bool {
|
||||
// self > max(invoc, decl) => !(self <= invoc || self <= decl)
|
||||
// Expansions are partially ordered, so "may appear after" is an inversion of
|
||||
// "certainly appears before or simultaneously" and includes unordered cases.
|
||||
let self_parent_expansion = self.expansion;
|
||||
let other_parent_expansion = binding.expansion;
|
||||
let other_parent_expansion = decl.expansion;
|
||||
let certainly_before_other_or_simultaneously =
|
||||
other_parent_expansion.is_descendant_of(self_parent_expansion);
|
||||
let certainly_before_invoc_or_simultaneously =
|
||||
|
|
@ -1048,9 +1043,9 @@ impl<'ra> NameBindingData<'ra> {
|
|||
// FIXME: How can we integrate it with the `update_resolution`?
|
||||
fn determined(&self) -> bool {
|
||||
match &self.kind {
|
||||
NameBindingKind::Import { binding, import, .. } if import.is_glob() => {
|
||||
DeclKind::Import { source_decl, import, .. } if import.is_glob() => {
|
||||
import.parent_scope.module.unexpanded_invocations.borrow().is_empty()
|
||||
&& binding.determined()
|
||||
&& source_decl.determined()
|
||||
}
|
||||
_ => true,
|
||||
}
|
||||
|
|
@ -1058,23 +1053,23 @@ impl<'ra> NameBindingData<'ra> {
|
|||
}
|
||||
|
||||
struct ExternPreludeEntry<'ra> {
|
||||
/// Binding from an `extern crate` item.
|
||||
/// The boolean flag is true is `item_binding` is non-redundant, happens either when
|
||||
/// `flag_binding` is `None`, or when `extern crate` introducing `item_binding` used renaming.
|
||||
item_binding: Option<(NameBinding<'ra>, /* introduced by item */ bool)>,
|
||||
/// Binding from an `--extern` flag, lazily populated on first use.
|
||||
flag_binding: Option<CacheCell<(PendingBinding<'ra>, /* finalized */ bool)>>,
|
||||
/// Name declaration from an `extern crate` item.
|
||||
/// The boolean flag is true is `item_decl` is non-redundant, happens either when
|
||||
/// `flag_decl` is `None`, or when `extern crate` introducing `item_decl` used renaming.
|
||||
item_decl: Option<(Decl<'ra>, /* introduced by item */ bool)>,
|
||||
/// Name declaration from an `--extern` flag, lazily populated on first use.
|
||||
flag_decl: Option<CacheCell<(PendingDecl<'ra>, /* finalized */ bool)>>,
|
||||
}
|
||||
|
||||
impl ExternPreludeEntry<'_> {
|
||||
fn introduced_by_item(&self) -> bool {
|
||||
matches!(self.item_binding, Some((_, true)))
|
||||
matches!(self.item_decl, Some((_, true)))
|
||||
}
|
||||
|
||||
fn flag() -> Self {
|
||||
ExternPreludeEntry {
|
||||
item_binding: None,
|
||||
flag_binding: Some(CacheCell::new((PendingBinding::Pending, false))),
|
||||
item_decl: None,
|
||||
flag_decl: Some(CacheCell::new((PendingDecl::Pending, false))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1181,7 +1176,7 @@ pub struct Resolver<'ra, 'tcx> {
|
|||
local_module_map: FxIndexMap<LocalDefId, Module<'ra>>,
|
||||
/// Lazily populated cache of modules loaded from external crates.
|
||||
extern_module_map: CacheRefCell<FxIndexMap<DefId, Module<'ra>>>,
|
||||
binding_parent_modules: FxHashMap<NameBinding<'ra>, Module<'ra>>,
|
||||
decl_parent_modules: FxHashMap<Decl<'ra>, Module<'ra>>,
|
||||
|
||||
/// Maps glob imports to the names of items actually imported.
|
||||
glob_map: FxIndexMap<LocalDefId, FxIndexSet<Symbol>>,
|
||||
|
|
@ -1206,14 +1201,14 @@ pub struct Resolver<'ra, 'tcx> {
|
|||
inaccessible_ctor_reexport: FxHashMap<Span, Span>,
|
||||
|
||||
arenas: &'ra ResolverArenas<'ra>,
|
||||
dummy_binding: NameBinding<'ra>,
|
||||
builtin_types_bindings: FxHashMap<Symbol, NameBinding<'ra>>,
|
||||
builtin_attrs_bindings: FxHashMap<Symbol, NameBinding<'ra>>,
|
||||
registered_tool_bindings: FxHashMap<Ident, NameBinding<'ra>>,
|
||||
dummy_decl: Decl<'ra>,
|
||||
builtin_type_decls: FxHashMap<Symbol, Decl<'ra>>,
|
||||
builtin_attr_decls: FxHashMap<Symbol, Decl<'ra>>,
|
||||
registered_tool_decls: FxHashMap<Ident, Decl<'ra>>,
|
||||
macro_names: FxHashSet<Ident>,
|
||||
builtin_macros: FxHashMap<Symbol, SyntaxExtensionKind>,
|
||||
registered_tools: &'tcx RegisteredTools,
|
||||
macro_use_prelude: FxIndexMap<Symbol, NameBinding<'ra>>,
|
||||
macro_use_prelude: FxIndexMap<Symbol, Decl<'ra>>,
|
||||
/// Eagerly populated map of all local macro definitions.
|
||||
local_macro_map: FxHashMap<LocalDefId, &'ra MacroData>,
|
||||
/// Lazily populated cache of macro definitions loaded from external crates.
|
||||
|
|
@ -1229,7 +1224,7 @@ pub struct Resolver<'ra, 'tcx> {
|
|||
proc_macro_stubs: FxHashSet<LocalDefId>,
|
||||
/// Traces collected during macro resolution and validated when it's complete.
|
||||
single_segment_macro_resolutions:
|
||||
CmRefCell<Vec<(Ident, MacroKind, ParentScope<'ra>, Option<NameBinding<'ra>>, Option<Span>)>>,
|
||||
CmRefCell<Vec<(Ident, MacroKind, ParentScope<'ra>, Option<Decl<'ra>>, Option<Span>)>>,
|
||||
multi_segment_macro_resolutions:
|
||||
CmRefCell<Vec<(Vec<Segment>, Span, MacroKind, ParentScope<'ra>, Option<Res>, Namespace)>>,
|
||||
builtin_attrs: Vec<(Ident, ParentScope<'ra>)>,
|
||||
|
|
@ -1246,7 +1241,7 @@ pub struct Resolver<'ra, 'tcx> {
|
|||
/// `macro_rules` scopes produced by `macro_rules` item definitions.
|
||||
macro_rules_scopes: FxHashMap<LocalDefId, MacroRulesScopeRef<'ra>>,
|
||||
/// Helper attributes that are in scope for the given expansion.
|
||||
helper_attrs: FxHashMap<LocalExpnId, Vec<(Ident, NameBinding<'ra>)>>,
|
||||
helper_attrs: FxHashMap<LocalExpnId, Vec<(Ident, Decl<'ra>)>>,
|
||||
/// Ready or in-progress results of resolving paths inside the `#[derive(...)]` attribute
|
||||
/// with the given `ExpnId`.
|
||||
derive_data: FxHashMap<LocalExpnId, DeriveData>,
|
||||
|
|
@ -1338,15 +1333,15 @@ pub struct ResolverArenas<'ra> {
|
|||
}
|
||||
|
||||
impl<'ra> ResolverArenas<'ra> {
|
||||
fn new_res_binding(
|
||||
fn new_def_decl(
|
||||
&'ra self,
|
||||
res: Res,
|
||||
vis: Visibility<DefId>,
|
||||
span: Span,
|
||||
expansion: LocalExpnId,
|
||||
) -> NameBinding<'ra> {
|
||||
self.alloc_name_binding(NameBindingData {
|
||||
kind: NameBindingKind::Res(res),
|
||||
) -> Decl<'ra> {
|
||||
self.alloc_decl(DeclData {
|
||||
kind: DeclKind::Def(res),
|
||||
ambiguity: None,
|
||||
warn_ambiguity: false,
|
||||
vis,
|
||||
|
|
@ -1355,13 +1350,8 @@ impl<'ra> ResolverArenas<'ra> {
|
|||
})
|
||||
}
|
||||
|
||||
fn new_pub_res_binding(
|
||||
&'ra self,
|
||||
res: Res,
|
||||
span: Span,
|
||||
expn_id: LocalExpnId,
|
||||
) -> NameBinding<'ra> {
|
||||
self.new_res_binding(res, Visibility::Public, span, expn_id)
|
||||
fn new_pub_def_decl(&'ra self, res: Res, span: Span, expn_id: LocalExpnId) -> Decl<'ra> {
|
||||
self.new_def_decl(res, Visibility::Public, span, expn_id)
|
||||
}
|
||||
|
||||
fn new_module(
|
||||
|
|
@ -1372,9 +1362,9 @@ impl<'ra> ResolverArenas<'ra> {
|
|||
span: Span,
|
||||
no_implicit_prelude: bool,
|
||||
) -> Module<'ra> {
|
||||
let self_binding = match kind {
|
||||
let self_decl = match kind {
|
||||
ModuleKind::Def(def_kind, def_id, _) => {
|
||||
Some(self.new_pub_res_binding(Res::Def(def_kind, def_id), span, LocalExpnId::ROOT))
|
||||
Some(self.new_pub_def_decl(Res::Def(def_kind, def_id), span, LocalExpnId::ROOT))
|
||||
}
|
||||
ModuleKind::Block => None,
|
||||
};
|
||||
|
|
@ -1384,11 +1374,11 @@ impl<'ra> ResolverArenas<'ra> {
|
|||
expn_id,
|
||||
span,
|
||||
no_implicit_prelude,
|
||||
self_binding,
|
||||
self_decl,
|
||||
))))
|
||||
}
|
||||
fn alloc_name_binding(&'ra self, name_binding: NameBindingData<'ra>) -> NameBinding<'ra> {
|
||||
Interned::new_unchecked(self.dropless.alloc(name_binding))
|
||||
fn alloc_decl(&'ra self, data: DeclData<'ra>) -> Decl<'ra> {
|
||||
Interned::new_unchecked(self.dropless.alloc(data))
|
||||
}
|
||||
fn alloc_import(&'ra self, import: ImportData<'ra>) -> Import<'ra> {
|
||||
Interned::new_unchecked(self.imports.alloc(import))
|
||||
|
|
@ -1399,11 +1389,8 @@ impl<'ra> ResolverArenas<'ra> {
|
|||
fn alloc_macro_rules_scope(&'ra self, scope: MacroRulesScope<'ra>) -> MacroRulesScopeRef<'ra> {
|
||||
self.dropless.alloc(CacheCell::new(scope))
|
||||
}
|
||||
fn alloc_macro_rules_binding(
|
||||
&'ra self,
|
||||
binding: MacroRulesBinding<'ra>,
|
||||
) -> &'ra MacroRulesBinding<'ra> {
|
||||
self.dropless.alloc(binding)
|
||||
fn alloc_macro_rules_decl(&'ra self, decl: MacroRulesDecl<'ra>) -> &'ra MacroRulesDecl<'ra> {
|
||||
self.dropless.alloc(decl)
|
||||
}
|
||||
fn alloc_ast_paths(&'ra self, paths: &[ast::Path]) -> &'ra [ast::Path] {
|
||||
self.ast_paths.alloc_from_iter(paths.iter().cloned())
|
||||
|
|
@ -1619,7 +1606,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
local_module_map,
|
||||
extern_module_map: Default::default(),
|
||||
block_map: Default::default(),
|
||||
binding_parent_modules: FxHashMap::default(),
|
||||
decl_parent_modules: FxHashMap::default(),
|
||||
ast_transform_scopes: FxHashMap::default(),
|
||||
|
||||
glob_map: Default::default(),
|
||||
|
|
@ -1628,29 +1615,29 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
inaccessible_ctor_reexport: Default::default(),
|
||||
|
||||
arenas,
|
||||
dummy_binding: arenas.new_pub_res_binding(Res::Err, DUMMY_SP, LocalExpnId::ROOT),
|
||||
builtin_types_bindings: PrimTy::ALL
|
||||
dummy_decl: arenas.new_pub_def_decl(Res::Err, DUMMY_SP, LocalExpnId::ROOT),
|
||||
builtin_type_decls: PrimTy::ALL
|
||||
.iter()
|
||||
.map(|prim_ty| {
|
||||
let res = Res::PrimTy(*prim_ty);
|
||||
let binding = arenas.new_pub_res_binding(res, DUMMY_SP, LocalExpnId::ROOT);
|
||||
(prim_ty.name(), binding)
|
||||
let decl = arenas.new_pub_def_decl(res, DUMMY_SP, LocalExpnId::ROOT);
|
||||
(prim_ty.name(), decl)
|
||||
})
|
||||
.collect(),
|
||||
builtin_attrs_bindings: BUILTIN_ATTRIBUTES
|
||||
builtin_attr_decls: BUILTIN_ATTRIBUTES
|
||||
.iter()
|
||||
.map(|builtin_attr| {
|
||||
let res = Res::NonMacroAttr(NonMacroAttrKind::Builtin(builtin_attr.name));
|
||||
let binding = arenas.new_pub_res_binding(res, DUMMY_SP, LocalExpnId::ROOT);
|
||||
(builtin_attr.name, binding)
|
||||
let decl = arenas.new_pub_def_decl(res, DUMMY_SP, LocalExpnId::ROOT);
|
||||
(builtin_attr.name, decl)
|
||||
})
|
||||
.collect(),
|
||||
registered_tool_bindings: registered_tools
|
||||
registered_tool_decls: registered_tools
|
||||
.iter()
|
||||
.map(|ident| {
|
||||
let res = Res::ToolMod;
|
||||
let binding = arenas.new_pub_res_binding(res, ident.span, LocalExpnId::ROOT);
|
||||
(*ident, binding)
|
||||
let decl = arenas.new_pub_def_decl(res, ident.span, LocalExpnId::ROOT);
|
||||
(*ident, decl)
|
||||
})
|
||||
.collect(),
|
||||
macro_names: FxHashSet::default(),
|
||||
|
|
@ -1994,18 +1981,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
|
||||
fn find_transitive_imports(
|
||||
&mut self,
|
||||
mut kind: &NameBindingKind<'_>,
|
||||
mut kind: &DeclKind<'_>,
|
||||
trait_name: Ident,
|
||||
) -> SmallVec<[LocalDefId; 1]> {
|
||||
let mut import_ids = smallvec![];
|
||||
while let NameBindingKind::Import { import, binding, .. } = kind {
|
||||
while let DeclKind::Import { import, source_decl, .. } = kind {
|
||||
if let Some(node_id) = import.id() {
|
||||
let def_id = self.local_def_id(node_id);
|
||||
self.maybe_unused_trait_imports.insert(def_id);
|
||||
import_ids.push(def_id);
|
||||
}
|
||||
self.add_to_glob_map(*import, trait_name);
|
||||
kind = &binding.kind;
|
||||
kind = &source_decl.kind;
|
||||
}
|
||||
import_ids
|
||||
}
|
||||
|
|
@ -2053,22 +2040,22 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
false
|
||||
}
|
||||
|
||||
fn record_use(&mut self, ident: Ident, used_binding: NameBinding<'ra>, used: Used) {
|
||||
self.record_use_inner(ident, used_binding, used, used_binding.warn_ambiguity);
|
||||
fn record_use(&mut self, ident: Ident, used_decl: Decl<'ra>, used: Used) {
|
||||
self.record_use_inner(ident, used_decl, used, used_decl.warn_ambiguity);
|
||||
}
|
||||
|
||||
fn record_use_inner(
|
||||
&mut self,
|
||||
ident: Ident,
|
||||
used_binding: NameBinding<'ra>,
|
||||
used_decl: Decl<'ra>,
|
||||
used: Used,
|
||||
warn_ambiguity: bool,
|
||||
) {
|
||||
if let Some(b2) = used_binding.ambiguity {
|
||||
if let Some(b2) = used_decl.ambiguity {
|
||||
let ambiguity_error = AmbiguityError {
|
||||
kind: AmbiguityKind::GlobVsGlob,
|
||||
ident,
|
||||
b1: used_binding,
|
||||
b1: used_decl,
|
||||
b2,
|
||||
scope1: Scope::ModuleGlobs(self.empty_module, None),
|
||||
scope2: Scope::ModuleGlobs(self.empty_module, None),
|
||||
|
|
@ -2079,7 +2066,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
self.ambiguity_errors.push(ambiguity_error);
|
||||
}
|
||||
}
|
||||
if let NameBindingKind::Import { import, binding } = used_binding.kind {
|
||||
if let DeclKind::Import { import, source_decl } = used_decl.kind {
|
||||
if let ImportKind::MacroUse { warn_private: true } = import.kind {
|
||||
// Do not report the lint if the macro name resolves in stdlib prelude
|
||||
// even without the problematic `macro_use` import.
|
||||
|
|
@ -2109,7 +2096,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
// but not introduce it, as used if they are accessed from lexical scope.
|
||||
if used == Used::Scope
|
||||
&& let Some(entry) = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident))
|
||||
&& entry.item_binding == Some((used_binding, false))
|
||||
&& entry.item_decl == Some((used_decl, false))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -2123,9 +2110,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
self.add_to_glob_map(import, ident);
|
||||
self.record_use_inner(
|
||||
ident,
|
||||
binding,
|
||||
source_decl,
|
||||
Used::Other,
|
||||
warn_ambiguity || binding.warn_ambiguity,
|
||||
warn_ambiguity || source_decl.warn_ambiguity,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -2236,18 +2223,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
vis.is_accessible_from(module.nearest_parent_mod(), self.tcx)
|
||||
}
|
||||
|
||||
fn set_binding_parent_module(&mut self, binding: NameBinding<'ra>, module: Module<'ra>) {
|
||||
if let Some(old_module) = self.binding_parent_modules.insert(binding, module) {
|
||||
fn set_decl_parent_module(&mut self, decl: Decl<'ra>, module: Module<'ra>) {
|
||||
if let Some(old_module) = self.decl_parent_modules.insert(decl, module) {
|
||||
if module != old_module {
|
||||
span_bug!(binding.span, "parent module is reset for binding");
|
||||
span_bug!(decl.span, "parent module is reset for a name declaration");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn disambiguate_macro_rules_vs_modularized(
|
||||
&self,
|
||||
macro_rules: NameBinding<'ra>,
|
||||
modularized: NameBinding<'ra>,
|
||||
macro_rules: Decl<'ra>,
|
||||
modularized: Decl<'ra>,
|
||||
) -> bool {
|
||||
// Some non-controversial subset of ambiguities "modularized macro name" vs "macro_rules"
|
||||
// is disambiguated to mitigate regressions from macro modularization.
|
||||
|
|
@ -2256,8 +2243,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
// panic on index should be impossible, the only name_bindings passed in should be from
|
||||
// `resolve_ident_in_scope_set` which will always refer to a local binding from an
|
||||
// import or macro definition
|
||||
let macro_rules = &self.binding_parent_modules[¯o_rules];
|
||||
let modularized = &self.binding_parent_modules[&modularized];
|
||||
let macro_rules = &self.decl_parent_modules[¯o_rules];
|
||||
let modularized = &self.decl_parent_modules[&modularized];
|
||||
macro_rules.nearest_parent_mod() == modularized.nearest_parent_mod()
|
||||
&& modularized.is_ancestor_of(*macro_rules)
|
||||
}
|
||||
|
|
@ -2266,9 +2253,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
mut self: CmResolver<'r, 'ra, 'tcx>,
|
||||
ident: Ident,
|
||||
finalize: bool,
|
||||
) -> Option<NameBinding<'ra>> {
|
||||
) -> Option<Decl<'ra>> {
|
||||
let entry = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident));
|
||||
entry.and_then(|entry| entry.item_binding).map(|(binding, _)| {
|
||||
entry.and_then(|entry| entry.item_decl).map(|(binding, _)| {
|
||||
if finalize {
|
||||
self.get_mut().record_use(ident, binding, Used::Scope);
|
||||
}
|
||||
|
|
@ -2276,18 +2263,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
fn extern_prelude_get_flag(&self, ident: Ident, finalize: bool) -> Option<NameBinding<'ra>> {
|
||||
fn extern_prelude_get_flag(&self, ident: Ident, finalize: bool) -> Option<Decl<'ra>> {
|
||||
let entry = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident));
|
||||
entry.and_then(|entry| entry.flag_binding.as_ref()).and_then(|flag_binding| {
|
||||
let (pending_binding, finalized) = flag_binding.get();
|
||||
let binding = match pending_binding {
|
||||
PendingBinding::Ready(binding) => {
|
||||
entry.and_then(|entry| entry.flag_decl.as_ref()).and_then(|flag_decl| {
|
||||
let (pending_decl, finalized) = flag_decl.get();
|
||||
let decl = match pending_decl {
|
||||
PendingDecl::Ready(decl) => {
|
||||
if finalize && !finalized {
|
||||
self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span);
|
||||
}
|
||||
binding
|
||||
decl
|
||||
}
|
||||
PendingBinding::Pending => {
|
||||
PendingDecl::Pending => {
|
||||
debug_assert!(!finalized);
|
||||
let crate_id = if finalize {
|
||||
self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span)
|
||||
|
|
@ -2296,12 +2283,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
};
|
||||
crate_id.map(|crate_id| {
|
||||
let res = Res::Def(DefKind::Mod, crate_id.as_def_id());
|
||||
self.arenas.new_pub_res_binding(res, DUMMY_SP, LocalExpnId::ROOT)
|
||||
self.arenas.new_pub_def_decl(res, DUMMY_SP, LocalExpnId::ROOT)
|
||||
})
|
||||
}
|
||||
};
|
||||
flag_binding.set((PendingBinding::Ready(binding), finalize || finalized));
|
||||
binding.or_else(|| finalize.then_some(self.dummy_binding))
|
||||
flag_decl.set((PendingDecl::Ready(decl), finalize || finalized));
|
||||
decl.or_else(|| finalize.then_some(self.dummy_decl))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,18 +38,18 @@ use crate::errors::{
|
|||
};
|
||||
use crate::imports::Import;
|
||||
use crate::{
|
||||
BindingKey, CacheCell, CmResolver, DeriveData, Determinacy, Finalize, InvocationParent,
|
||||
MacroData, ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope,
|
||||
PathResult, ResolutionError, Resolver, ScopeSet, Segment, Used,
|
||||
BindingKey, CacheCell, CmResolver, Decl, DeclKind, DeriveData, Determinacy, Finalize,
|
||||
InvocationParent, MacroData, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult,
|
||||
ResolutionError, Resolver, ScopeSet, Segment, Used,
|
||||
};
|
||||
|
||||
type Res = def::Res<NodeId>;
|
||||
|
||||
/// Binding produced by a `macro_rules` item.
|
||||
/// Not modularized, can shadow previous `macro_rules` bindings, etc.
|
||||
/// Name declaration produced by a `macro_rules` item definition.
|
||||
/// Not modularized, can shadow previous `macro_rules` definitions, etc.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct MacroRulesBinding<'ra> {
|
||||
pub(crate) binding: NameBinding<'ra>,
|
||||
pub(crate) struct MacroRulesDecl<'ra> {
|
||||
pub(crate) decl: Decl<'ra>,
|
||||
/// `macro_rules` scope into which the `macro_rules` item was planted.
|
||||
pub(crate) parent_macro_rules_scope: MacroRulesScopeRef<'ra>,
|
||||
pub(crate) ident: Ident,
|
||||
|
|
@ -65,7 +65,7 @@ pub(crate) enum MacroRulesScope<'ra> {
|
|||
/// Empty "root" scope at the crate start containing no names.
|
||||
Empty,
|
||||
/// The scope introduced by a `macro_rules!` macro definition.
|
||||
Binding(&'ra MacroRulesBinding<'ra>),
|
||||
Def(&'ra MacroRulesDecl<'ra>),
|
||||
/// The scope introduced by a macro invocation that can potentially
|
||||
/// create a `macro_rules!` macro definition.
|
||||
Invocation(LocalExpnId),
|
||||
|
|
@ -431,8 +431,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
|
|||
.iter()
|
||||
.map(|(_, ident)| {
|
||||
let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
|
||||
let binding = self.arenas.new_pub_res_binding(res, ident.span, expn_id);
|
||||
(*ident, binding)
|
||||
(*ident, self.arenas.new_pub_def_decl(res, ident.span, expn_id))
|
||||
})
|
||||
.collect();
|
||||
self.helper_attrs.insert(expn_id, helper_attrs);
|
||||
|
|
@ -1062,18 +1061,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
|
||||
fn prohibit_imported_non_macro_attrs(
|
||||
&self,
|
||||
binding: Option<NameBinding<'ra>>,
|
||||
decl: Option<Decl<'ra>>,
|
||||
res: Option<Res>,
|
||||
span: Span,
|
||||
) {
|
||||
if let Some(Res::NonMacroAttr(kind)) = res {
|
||||
if kind != NonMacroAttrKind::Tool && binding.is_none_or(|b| b.is_import()) {
|
||||
let binding_span = binding.map(|binding| binding.span);
|
||||
if kind != NonMacroAttrKind::Tool && decl.is_none_or(|b| b.is_import()) {
|
||||
self.dcx().emit_err(errors::CannotUseThroughAnImport {
|
||||
span,
|
||||
article: kind.article(),
|
||||
descr: kind.descr(),
|
||||
binding_span,
|
||||
binding_span: decl.map(|d| d.span),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1084,12 +1082,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
path: &ast::Path,
|
||||
parent_scope: &ParentScope<'ra>,
|
||||
invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>,
|
||||
binding: Option<NameBinding<'ra>>,
|
||||
decl: Option<Decl<'ra>>,
|
||||
) {
|
||||
if let Some((mod_def_id, node_id)) = invoc_in_mod_inert_attr
|
||||
&& let Some(binding) = binding
|
||||
&& let Some(decl) = decl
|
||||
// This is a `macro_rules` itself, not some import.
|
||||
&& let NameBindingKind::Res(res) = binding.kind
|
||||
&& let DeclKind::Def(res) = decl.kind
|
||||
&& let Res::Def(DefKind::Macro(kinds), def_id) = res
|
||||
&& kinds.contains(MacroKinds::BANG)
|
||||
// And the `macro_rules` is defined inside the attribute's module,
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
//@ known-bug: #132985
|
||||
//@ aux-build:aux132985.rs
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(min_generic_const_args)]
|
||||
#![feature(adt_const_params)]
|
||||
|
||||
extern crate aux132985;
|
||||
use aux132985::Foo;
|
||||
|
||||
fn bar<const N: Foo>() {}
|
||||
|
||||
fn baz() {
|
||||
bar::<{ Foo }>();
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
//@ known-bug: #136138
|
||||
#![feature(min_generic_const_args)]
|
||||
struct U;
|
||||
struct S<const N: U>()
|
||||
where
|
||||
S<{ U }>:;
|
||||
fn main() {}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
//@ known-bug: #139596
|
||||
|
||||
#![feature(min_generic_const_args)]
|
||||
struct Colour;
|
||||
|
||||
struct Led<const C: Colour>;
|
||||
|
||||
fn main() {
|
||||
Led::<{ Colour}>;
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
//@ known-bug: #132980
|
||||
// Originally a rustdoc test. Should be moved back there with @has checks
|
||||
// readded once fixed.
|
||||
// Previous issue (before mgca): https://github.com/rust-lang/rust/issues/105952
|
||||
#![crate_name = "foo"]
|
||||
#![feature(min_generic_const_args)]
|
||||
pub enum ParseMode {
|
||||
Raw,
|
||||
}
|
||||
pub trait Parse {
|
||||
#[type_const]
|
||||
const PARSE_MODE: ParseMode;
|
||||
}
|
||||
pub trait RenderRaw {}
|
||||
|
||||
impl<T: Parse<PARSE_MODE = { ParseMode::Raw }>> RenderRaw for T {}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
//! Regression test for <https://github.com/rust-lang/rust/issues/105952>
|
||||
|
||||
#![crate_name = "foo"]
|
||||
#![feature(min_generic_const_args, adt_const_params)]
|
||||
#![expect(incomplete_features)]
|
||||
use std::marker::ConstParamTy;
|
||||
|
||||
#[derive(PartialEq, Eq, ConstParamTy)]
|
||||
pub enum ParseMode {
|
||||
Raw,
|
||||
}
|
||||
pub trait Parse {
|
||||
#[type_const]
|
||||
const PARSE_MODE: ParseMode;
|
||||
}
|
||||
pub trait RenderRaw {}
|
||||
|
||||
//@ hasraw foo/trait.RenderRaw.html 'impl'
|
||||
//@ hasraw foo/trait.RenderRaw.html 'ParseMode::Raw'
|
||||
impl<T: Parse<PARSE_MODE = { ParseMode::Raw }>> RenderRaw for T {}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
//@ known-bug: #110395
|
||||
//@ compile-flags: -Znext-solver
|
||||
//@ check-pass
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(const_trait_impl, generic_const_exprs)]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,95 +0,0 @@
|
|||
error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed
|
||||
--> $DIR/issue-88119.rs:4:30
|
||||
|
|
||||
LL | #![feature(const_trait_impl, generic_const_exprs)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: remove one of these features
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `&T: [const] ConstName`
|
||||
--> $DIR/issue-88119.rs:18:49
|
||||
|
|
||||
LL | impl<T: ?Sized + ConstName> const ConstName for &T
|
||||
| ^^
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `&T: ConstName`
|
||||
--> $DIR/issue-88119.rs:18:49
|
||||
|
|
||||
LL | impl<T: ?Sized + ConstName> const ConstName for &T
|
||||
| ^^
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `[(); name_len::<T>()] well-formed`
|
||||
--> $DIR/issue-88119.rs:20:5
|
||||
|
|
||||
LL | [(); name_len::<T>()]:,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: required by a bound in `<&T as ConstName>`
|
||||
--> $DIR/issue-88119.rs:20:5
|
||||
|
|
||||
LL | [(); name_len::<T>()]:,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&T as ConstName>`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `[(); name_len::<T>()] well-formed`
|
||||
--> $DIR/issue-88119.rs:20:10
|
||||
|
|
||||
LL | [(); name_len::<T>()]:,
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: required by a bound in `<&T as ConstName>`
|
||||
--> $DIR/issue-88119.rs:20:5
|
||||
|
|
||||
LL | [(); name_len::<T>()]:,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&T as ConstName>`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `&mut T: [const] ConstName`
|
||||
--> $DIR/issue-88119.rs:25:49
|
||||
|
|
||||
LL | impl<T: ?Sized + ConstName> const ConstName for &mut T
|
||||
| ^^^^^^
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `&mut T: ConstName`
|
||||
--> $DIR/issue-88119.rs:25:49
|
||||
|
|
||||
LL | impl<T: ?Sized + ConstName> const ConstName for &mut T
|
||||
| ^^^^^^
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `[(); name_len::<T>()] well-formed`
|
||||
--> $DIR/issue-88119.rs:27:5
|
||||
|
|
||||
LL | [(); name_len::<T>()]:,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: required by a bound in `<&mut T as ConstName>`
|
||||
--> $DIR/issue-88119.rs:27:5
|
||||
|
|
||||
LL | [(); name_len::<T>()]:,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&mut T as ConstName>`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `[(); name_len::<T>()] well-formed`
|
||||
--> $DIR/issue-88119.rs:27:10
|
||||
|
|
||||
LL | [(); name_len::<T>()]:,
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: required by a bound in `<&mut T as ConstName>`
|
||||
--> $DIR/issue-88119.rs:27:5
|
||||
|
|
||||
LL | [(); name_len::<T>()]:,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&mut T as ConstName>`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `&&mut u8: ConstName`
|
||||
--> $DIR/issue-88119.rs:32:35
|
||||
|
|
||||
LL | pub const ICE_1: &'static [u8] = <&&mut u8 as ConstName>::NAME_BYTES;
|
||||
| ^^^^^^^^
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `&mut &u8: ConstName`
|
||||
--> $DIR/issue-88119.rs:33:35
|
||||
|
|
||||
LL | pub const ICE_2: &'static [u8] = <&mut &u8 as ConstName>::NAME_BYTES;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
||||
19
tests/ui/const-generics/mgca/const-ctor-overflow-eval.rs
Normal file
19
tests/ui/const-generics/mgca/const-ctor-overflow-eval.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#![feature(min_generic_const_args, adt_const_params)]
|
||||
#![expect(incomplete_features)]
|
||||
use std::marker::ConstParamTy;
|
||||
|
||||
#[derive(ConstParamTy, PartialEq, Eq)]
|
||||
struct U;
|
||||
|
||||
#[derive(ConstParamTy, PartialEq, Eq)]
|
||||
//~^ ERROR overflow evaluating the requirement `S<U> well-formed`
|
||||
//~| ERROR overflow evaluating the requirement `S<U> well-formed`
|
||||
|
||||
struct S<const N: U>()
|
||||
where
|
||||
S<{ U }>:;
|
||||
//~^ ERROR overflow evaluating the requirement `S<U> well-formed`
|
||||
//~| ERROR overflow evaluating the requirement `S<U> well-formed`
|
||||
//~| ERROR overflow evaluating the requirement `S<U> well-formed`
|
||||
|
||||
fn main() {}
|
||||
80
tests/ui/const-generics/mgca/const-ctor-overflow-eval.stderr
Normal file
80
tests/ui/const-generics/mgca/const-ctor-overflow-eval.stderr
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
error[E0275]: overflow evaluating the requirement `S<U> well-formed`
|
||||
--> $DIR/const-ctor-overflow-eval.rs:14:5
|
||||
|
|
||||
LL | S<{ U }>:;
|
||||
| ^^^^^^^^
|
||||
|
|
||||
note: required by a bound in `S`
|
||||
--> $DIR/const-ctor-overflow-eval.rs:14:5
|
||||
|
|
||||
LL | struct S<const N: U>()
|
||||
| - required by a bound in this struct
|
||||
LL | where
|
||||
LL | S<{ U }>:;
|
||||
| ^^^^^^^^ required by this bound in `S`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `S<U> well-formed`
|
||||
--> $DIR/const-ctor-overflow-eval.rs:14:5
|
||||
|
|
||||
LL | S<{ U }>:;
|
||||
| ^^^^^^^^
|
||||
|
|
||||
note: required by a bound in `S`
|
||||
--> $DIR/const-ctor-overflow-eval.rs:14:5
|
||||
|
|
||||
LL | struct S<const N: U>()
|
||||
| - required by a bound in this struct
|
||||
LL | where
|
||||
LL | S<{ U }>:;
|
||||
| ^^^^^^^^ required by this bound in `S`
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `S<U> well-formed`
|
||||
--> $DIR/const-ctor-overflow-eval.rs:14:5
|
||||
|
|
||||
LL | S<{ U }>:;
|
||||
| ^^^^^^^^
|
||||
|
|
||||
note: required by a bound in `S`
|
||||
--> $DIR/const-ctor-overflow-eval.rs:14:5
|
||||
|
|
||||
LL | struct S<const N: U>()
|
||||
| - required by a bound in this struct
|
||||
LL | where
|
||||
LL | S<{ U }>:;
|
||||
| ^^^^^^^^ required by this bound in `S`
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `S<U> well-formed`
|
||||
--> $DIR/const-ctor-overflow-eval.rs:8:24
|
||||
|
|
||||
LL | #[derive(ConstParamTy, PartialEq, Eq)]
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
note: required by a bound in `S`
|
||||
--> $DIR/const-ctor-overflow-eval.rs:14:5
|
||||
|
|
||||
LL | struct S<const N: U>()
|
||||
| - required by a bound in this struct
|
||||
LL | where
|
||||
LL | S<{ U }>:;
|
||||
| ^^^^^^^^ required by this bound in `S`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `S<U> well-formed`
|
||||
--> $DIR/const-ctor-overflow-eval.rs:8:35
|
||||
|
|
||||
LL | #[derive(ConstParamTy, PartialEq, Eq)]
|
||||
| ^^
|
||||
|
|
||||
note: required by a bound in `S`
|
||||
--> $DIR/const-ctor-overflow-eval.rs:14:5
|
||||
|
|
||||
LL | struct S<const N: U>()
|
||||
| - required by a bound in this struct
|
||||
LL | where
|
||||
LL | S<{ U }>:;
|
||||
| ^^^^^^^^ required by this bound in `S`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
||||
19
tests/ui/const-generics/mgca/const-ctor-with-error.rs
Normal file
19
tests/ui/const-generics/mgca/const-ctor-with-error.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// to ensure it does not ices like before
|
||||
|
||||
#![feature(min_generic_const_args, adt_const_params)]
|
||||
#![expect(incomplete_features)]
|
||||
use std::marker::ConstParamTy;
|
||||
|
||||
#[derive(ConstParamTy, PartialEq, Eq)]
|
||||
enum Option<T> {
|
||||
#[allow(dead_code)]
|
||||
Some(T),
|
||||
None,
|
||||
}
|
||||
|
||||
fn pass_enum<const P: Option<u32>>() {}
|
||||
|
||||
fn main() {
|
||||
pass_enum::<{ None }>();
|
||||
//~^ ERROR missing generics for enum `std::option::Option`
|
||||
}
|
||||
14
tests/ui/const-generics/mgca/const-ctor-with-error.stderr
Normal file
14
tests/ui/const-generics/mgca/const-ctor-with-error.stderr
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
error[E0107]: missing generics for enum `std::option::Option`
|
||||
--> $DIR/const-ctor-with-error.rs:17:19
|
||||
|
|
||||
LL | pass_enum::<{ None }>();
|
||||
| ^^^^ expected 1 generic argument
|
||||
|
|
||||
help: add missing generic argument
|
||||
|
|
||||
LL | pass_enum::<{ None<T> }>();
|
||||
| +++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0107`.
|
||||
49
tests/ui/const-generics/mgca/const-ctor.rs
Normal file
49
tests/ui/const-generics/mgca/const-ctor.rs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
//! Regression test for <https://github.com/rust-lang/rust/issues/139596>
|
||||
//! <https://github.com/rust-lang/rust/issues/136138>
|
||||
//! <https://github.com/rust-lang/rust/issues/132985>
|
||||
|
||||
//@ check-pass
|
||||
|
||||
#![feature(
|
||||
min_generic_const_args,
|
||||
adt_const_params,
|
||||
generic_const_parameter_types,
|
||||
unsized_const_params
|
||||
)]
|
||||
#![expect(incomplete_features)]
|
||||
use std::marker::{ConstParamTy, ConstParamTy_};
|
||||
#[derive(ConstParamTy, PartialEq, Eq)]
|
||||
struct Colour;
|
||||
|
||||
#[derive(ConstParamTy, PartialEq, Eq)]
|
||||
enum A {
|
||||
B,
|
||||
}
|
||||
|
||||
#[derive(ConstParamTy, PartialEq, Eq)]
|
||||
enum MyOption<T> {
|
||||
#[allow(dead_code)]
|
||||
Some(T),
|
||||
None,
|
||||
}
|
||||
|
||||
#[derive(ConstParamTy, PartialEq, Eq)]
|
||||
struct Led<const C: Colour>;
|
||||
|
||||
#[derive(Eq, PartialEq, ConstParamTy)]
|
||||
struct Foo<const N: usize>;
|
||||
|
||||
fn pass_enum<const P: MyOption<u32>>() {}
|
||||
|
||||
fn accepts_foo<const N: usize, const M: Foo<N>>() {}
|
||||
|
||||
fn accepts_bar<T: ConstParamTy_, const B: MyOption<T>>() {}
|
||||
|
||||
fn test<T: ConstParamTy_, const N: usize>() {
|
||||
accepts_foo::<N, { Foo::<N> }>();
|
||||
accepts_bar::<T, { MyOption::None::<T> }>();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
Led::<{ Colour }>;
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
error: const `impl` for trait `Debug` which is not `const`
|
||||
--> $DIR/rustc-impl-const-stability.rs:15:12
|
||||
|
|
||||
LL | impl const std::fmt::Debug for Data {
|
||||
| ^^^^^^^^^^^^^^^ this trait is not `const`
|
||||
|
|
||||
= note: marking a trait with `const` ensures all default method bodies are `const`
|
||||
= note: adding a non-const method body in the future would be a breaking change
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
35
tests/ui/macros/concat-nested-repetition.rs
Normal file
35
tests/ui/macros/concat-nested-repetition.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
//@ check-pass
|
||||
#![feature(macro_metavar_expr_concat)]
|
||||
|
||||
struct A;
|
||||
struct B;
|
||||
const AA: A = A;
|
||||
const BB: B = B;
|
||||
|
||||
macro_rules! define_ioctl_data {
|
||||
(struct $s:ident {
|
||||
$($field:ident: $ty:ident $([$opt:ident])?,)*
|
||||
}) => {
|
||||
pub struct $s {
|
||||
$($field: $ty,)*
|
||||
}
|
||||
|
||||
impl $s {
|
||||
$($(
|
||||
fn ${concat(get_, $field)}(&self) -> $ty {
|
||||
let _ = $opt;
|
||||
todo!()
|
||||
}
|
||||
)?)*
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
define_ioctl_data! {
|
||||
struct Foo {
|
||||
a: A [AA],
|
||||
b: B [BB],
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -11,7 +11,7 @@ macro_rules! InRepetition {
|
|||
) => {
|
||||
$(
|
||||
$(
|
||||
${concat(_, $arg)} //~ ERROR nested repetitions with `${concat(...)}` metavariable expressions are not yet supported
|
||||
${concat(_, $arg)} //~ ERROR macro expansion ends with an incomplete expression: expected one of `!` or `::`
|
||||
)*
|
||||
)*
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: nested repetitions with `${concat(...)}` metavariable expressions are not yet supported
|
||||
--> $DIR/in-repetition.rs:14:30
|
||||
error: macro expansion ends with an incomplete expression: expected one of `!` or `::`
|
||||
--> $DIR/in-repetition.rs:14:35
|
||||
|
|
||||
LL | ${concat(_, $arg)}
|
||||
| ^^^
|
||||
| ^ expected one of `!` or `::`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,7 @@ macro_rules! one_rep {
|
|||
macro_rules! issue_128346 {
|
||||
( $($a:ident)* ) => {
|
||||
A(
|
||||
const ${concat($a, Z)}: i32 = 3;
|
||||
//~^ ERROR invalid syntax
|
||||
const ${concat($a, Z)}: i32 = 3; //~ ERROR `${concat(...)}` variable is still repeating at this depth
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
|
@ -20,8 +19,8 @@ macro_rules! issue_128346 {
|
|||
macro_rules! issue_131393 {
|
||||
($t:ident $($en:ident)?) => {
|
||||
read::<${concat($t, $en)}>()
|
||||
//~^ ERROR invalid syntax
|
||||
//~| ERROR invalid syntax
|
||||
//~^ ERROR `${concat(...)}` variable is still repeating at this depth
|
||||
//~| ERROR `${concat(...)}` variable is still repeating at this depth
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
error: invalid syntax
|
||||
--> $DIR/concat-repetitions.rs:14:20
|
||||
error: `${concat(...)}` variable is still repeating at this depth
|
||||
--> $DIR/concat-repetitions.rs:14:29
|
||||
|
|
||||
LL | const ${concat($a, Z)}: i32 = 3;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
| ^
|
||||
|
||||
error: invalid syntax
|
||||
--> $DIR/concat-repetitions.rs:22:17
|
||||
error: `${concat(...)}` variable is still repeating at this depth
|
||||
--> $DIR/concat-repetitions.rs:21:30
|
||||
|
|
||||
LL | read::<${concat($t, $en)}>()
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
| ^^
|
||||
|
||||
error: invalid syntax
|
||||
--> $DIR/concat-repetitions.rs:22:17
|
||||
error: `${concat(...)}` variable is still repeating at this depth
|
||||
--> $DIR/concat-repetitions.rs:21:30
|
||||
|
|
||||
LL | read::<${concat($t, $en)}>()
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
| ^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
error: `[const]` can only be applied to `const` traits
|
||||
--> $DIR/const_trait_impl.rs:33:9
|
||||
|
|
||||
LL | impl<T: [const] Debug> const A for T {
|
||||
| ^^^^^^^ can't be applied to `Debug`
|
||||
|
|
||||
note: `Debug` can't be used with `[const]` because it isn't `const`
|
||||
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
|
||||
|
||||
error: `[const]` can only be applied to `const` traits
|
||||
--> $DIR/const_trait_impl.rs:39:9
|
||||
|
|
||||
LL | impl<T: [const] Debug + [const] Sup> const A for T {
|
||||
| ^^^^^^^ can't be applied to `Debug`
|
||||
|
|
||||
note: `Debug` can't be used with `[const]` because it isn't `const`
|
||||
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
|
||||
|
||||
error: `[const]` can only be applied to `const` traits
|
||||
--> $DIR/const_trait_impl.rs:45:9
|
||||
|
|
||||
LL | impl<T: [const] Debug + [const] Sub> const A for T {
|
||||
| ^^^^^^^ can't be applied to `Debug`
|
||||
|
|
||||
note: `Debug` can't be used with `[const]` because it isn't `const`
|
||||
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
|
||||
|
||||
error: `[const]` can only be applied to `const` traits
|
||||
--> $DIR/const_trait_impl.rs:39:9
|
||||
|
|
||||
LL | impl<T: [const] Debug + [const] Sup> const A for T {
|
||||
| ^^^^^^^ can't be applied to `Debug`
|
||||
|
|
||||
note: `Debug` can't be used with `[const]` because it isn't `const`
|
||||
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: `[const]` can only be applied to `const` traits
|
||||
--> $DIR/const_trait_impl.rs:33:9
|
||||
|
|
||||
LL | impl<T: [const] Debug> const A for T {
|
||||
| ^^^^^^^ can't be applied to `Debug`
|
||||
|
|
||||
note: `Debug` can't be used with `[const]` because it isn't `const`
|
||||
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: `[const]` can only be applied to `const` traits
|
||||
--> $DIR/const_trait_impl.rs:45:9
|
||||
|
|
||||
LL | impl<T: [const] Debug + [const] Sub> const A for T {
|
||||
| ^^^^^^^ can't be applied to `Debug`
|
||||
|
|
||||
note: `Debug` can't be used with `[const]` because it isn't `const`
|
||||
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
//@ known-bug: #110395
|
||||
#![feature(derive_const)]
|
||||
#![feature(const_default, derive_const)]
|
||||
|
||||
pub struct A;
|
||||
|
||||
impl std::fmt::Debug for A {
|
||||
fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
panic!()
|
||||
impl Default for A {
|
||||
fn default() -> A {
|
||||
A
|
||||
}
|
||||
}
|
||||
|
||||
#[derive_const(Debug)]
|
||||
#[derive_const(Default)]
|
||||
pub struct S(A);
|
||||
//~^ ERROR: cannot call non-const associated function
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,13 @@
|
|||
error: const `impl` for trait `Debug` which is not `const`
|
||||
--> $DIR/derive-const-non-const-type.rs:12:16
|
||||
error[E0015]: cannot call non-const associated function `<A as Default>::default` in constant functions
|
||||
--> $DIR/derive-const-non-const-type.rs:12:14
|
||||
|
|
||||
LL | #[derive_const(Debug)]
|
||||
| ^^^^^ this trait is not `const`
|
||||
|
|
||||
= note: marking a trait with `const` ensures all default method bodies are `const`
|
||||
= note: adding a non-const method body in the future would be a breaking change
|
||||
|
||||
error[E0015]: cannot call non-const method `Formatter::<'_>::debug_tuple_field1_finish` in constant functions
|
||||
--> $DIR/derive-const-non-const-type.rs:12:16
|
||||
|
|
||||
LL | #[derive_const(Debug)]
|
||||
| ^^^^^
|
||||
LL | #[derive_const(Default)]
|
||||
| ------- in this derive macro expansion
|
||||
LL | pub struct S(A);
|
||||
| ^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
//@ compile-flags: -Znext-solver
|
||||
//@ known-bug: #110395
|
||||
//@ check-pass
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(staged_api, const_trait_impl, const_default)]
|
||||
|
|
@ -12,8 +11,8 @@ pub struct Data {
|
|||
|
||||
#[stable(feature = "potato", since = "1.27.0")]
|
||||
#[rustc_const_unstable(feature = "data_foo", issue = "none")]
|
||||
impl const std::fmt::Debug for Data {
|
||||
fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
Ok(())
|
||||
impl const Default for Data {
|
||||
fn default() -> Data {
|
||||
Data { _data: 0xbeef }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
// Tests that trait bounds on specializing trait impls must be `[const]` if the
|
||||
// same bound is present on the default impl and is `[const]` there.
|
||||
//@ known-bug: #110395
|
||||
// FIXME(const_trait_impl) ^ should error
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
|
@ -23,9 +21,9 @@ where
|
|||
default fn bar() {}
|
||||
}
|
||||
|
||||
impl<T> Bar for T
|
||||
impl<T> Bar for T //~ ERROR conflicting implementations of trait `Bar`
|
||||
where
|
||||
T: Foo, //FIXME ~ ERROR missing `[const]` qualifier
|
||||
T: Foo,
|
||||
T: Specialize,
|
||||
{
|
||||
fn bar() {}
|
||||
|
|
@ -42,7 +40,7 @@ where
|
|||
default fn baz() {}
|
||||
}
|
||||
|
||||
impl<T> const Baz for T //FIXME ~ ERROR conflicting implementations of trait `Baz`
|
||||
impl<T> const Baz for T //~ ERROR conflicting implementations of trait `Baz`
|
||||
where
|
||||
T: Foo,
|
||||
T: Specialize,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0119]: conflicting implementations of trait `Bar`
|
||||
--> $DIR/const-default-bound-non-const-specialized-bound.rs:26:1
|
||||
--> $DIR/const-default-bound-non-const-specialized-bound.rs:24:1
|
||||
|
|
||||
LL | / impl<T> const Bar for T
|
||||
LL | | where
|
||||
|
|
@ -8,19 +8,19 @@ LL | | T: [const] Foo,
|
|||
...
|
||||
LL | / impl<T> Bar for T
|
||||
LL | | where
|
||||
LL | | T: Foo, //FIXME ~ ERROR missing `[const]` qualifier
|
||||
LL | | T: Foo,
|
||||
LL | | T: Specialize,
|
||||
| |__________________^ conflicting implementation
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Baz`
|
||||
--> $DIR/const-default-bound-non-const-specialized-bound.rs:45:1
|
||||
--> $DIR/const-default-bound-non-const-specialized-bound.rs:43:1
|
||||
|
|
||||
LL | / impl<T> const Baz for T
|
||||
LL | | where
|
||||
LL | | T: [const] Foo,
|
||||
| |___________________- first implementation here
|
||||
...
|
||||
LL | / impl<T> const Baz for T //FIXME ~ ERROR conflicting implementations of trait `Baz`
|
||||
LL | / impl<T> const Baz for T
|
||||
LL | | where
|
||||
LL | | T: Foo,
|
||||
LL | | T: Specialize,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
//@ known-bug: #110395
|
||||
|
||||
#![feature(const_trait_impl, min_specialization, rustc_attrs)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
//@ check-pass
|
||||
#![feature(const_trait_impl, const_default, min_specialization, rustc_attrs)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
#[rustc_specialization_trait]
|
||||
pub const unsafe trait Sup {
|
||||
|
|
@ -30,19 +28,19 @@ pub const trait A {
|
|||
fn a() -> u32;
|
||||
}
|
||||
|
||||
impl<T: [const] Debug> const A for T {
|
||||
impl<T: [const] Default> const A for T {
|
||||
default fn a() -> u32 {
|
||||
2
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: [const] Debug + [const] Sup> const A for T {
|
||||
impl<T: [const] Default + [const] Sup> const A for T {
|
||||
default fn a() -> u32 {
|
||||
3
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: [const] Debug + [const] Sub> const A for T {
|
||||
impl<T: [const] Default + [const] Sub> const A for T {
|
||||
fn a() -> u32 {
|
||||
T::foo()
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#![feature(const_trait_impl, min_specialization, rustc_attrs)]
|
||||
//@ known-bug: #110395
|
||||
#![allow(internal_features)]
|
||||
|
||||
#[rustc_specialization_trait]
|
||||
pub const trait Sup {}
|
||||
|
||||
|
|
@ -23,7 +24,7 @@ impl<T: Default + [const] Sup> const A for T {
|
|||
|
||||
const fn generic<T: Default>() {
|
||||
<T as A>::a();
|
||||
//FIXME ~^ ERROR: the trait bound `T: [const] Sup` is not satisfied
|
||||
//~^ ERROR: the trait bound `T: [const] A` is not satisfied
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0277]: the trait bound `T: [const] A` is not satisfied
|
||||
--> $DIR/specializing-constness-2.rs:25:6
|
||||
--> $DIR/specializing-constness-2.rs:26:6
|
||||
|
|
||||
LL | <T as A>::a();
|
||||
| ^
|
||||
Loading…
Add table
Add a link
Reference in a new issue