summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_resolve/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /compiler/rustc_resolve/src
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_resolve/src')
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs45
-rw-r--r--compiler/rustc_resolve/src/check_unused.rs17
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs123
-rw-r--r--compiler/rustc_resolve/src/effective_visibilities.rs6
-rw-r--r--compiler/rustc_resolve/src/errors.rs88
-rw-r--r--compiler/rustc_resolve/src/ident.rs202
-rw-r--r--compiler/rustc_resolve/src/imports.rs54
-rw-r--r--compiler/rustc_resolve/src/late.rs497
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs278
-rw-r--r--compiler/rustc_resolve/src/lib.rs44
-rw-r--r--compiler/rustc_resolve/src/macros.rs39
-rw-r--r--compiler/rustc_resolve/src/rustdoc.rs1
12 files changed, 735 insertions, 659 deletions
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index ff0f1f559..727777333 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -9,10 +9,9 @@ use crate::def_collector::collect_definitions;
use crate::imports::{Import, ImportKind};
use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
use crate::Namespace::{self, MacroNS, TypeNS, ValueNS};
+use crate::{errors, BindingKey, MacroData};
use crate::{Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, ModuleOrUniformRoot};
-use crate::{
- MacroData, NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError,
-};
+use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError};
use crate::{Resolver, ResolverArenas, Segment, ToNameBinding, VisResolutionError};
use rustc_ast::visit::{self, AssocCtxt, Visitor};
@@ -70,7 +69,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
T: ToNameBinding<'a>,
{
let binding = def.to_name_binding(self.arenas);
- let key = self.new_key(ident, ns);
+ let key = self.new_disambiguated_key(ident, ns);
if let Err(old_binding) = self.try_define(parent, key, binding) {
self.report_conflict(parent, ident, ns, old_binding, &binding);
}
@@ -130,7 +129,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
expn_id,
self.def_span(def_id),
// FIXME: Account for `#[no_implicit_prelude]` attributes.
- parent.map_or(false, |module| module.no_implicit_prelude),
+ parent.is_some_and(|module| module.no_implicit_prelude),
));
}
}
@@ -197,10 +196,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
pub(crate) fn build_reduced_graph_external(&mut self, module: Module<'a>) {
- // Query `module_children` is not used because hashing spans in its result is expensive.
- let children =
- Vec::from_iter(self.cstore().module_children_untracked(module.def_id(), self.tcx.sess));
- for child in children {
+ for child in self.tcx.module_children(module.def_id()) {
let parent_scope = ParentScope::module(module, self);
BuildReducedGraphVisitor { r: self, parent_scope }
.build_reduced_graph_for_external_crate_res(child);
@@ -380,7 +376,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
ImportKind::Single { target, type_ns_only, .. } => {
self.r.per_ns(|this, ns| {
if !type_ns_only || ns == TypeNS {
- let key = this.new_key(target, ns);
+ let key = BindingKey::new(target, ns);
let mut resolution = this.resolution(current_module, key).borrow_mut();
resolution.add_single_import(import);
}
@@ -526,11 +522,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
ident.name = crate_name;
}
- self.r
- .tcx
- .sess
- .struct_span_err(item.span, "`$crate` may not be imported")
- .emit();
+ self.r.tcx.sess.emit_err(errors::CrateImported { span: item.span });
}
}
@@ -881,6 +873,11 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
let msg = "macro-expanded `extern crate` items cannot \
shadow names passed with `--extern`";
self.r.tcx.sess.span_err(item.span, msg);
+ // `return` is intended to discard this binding because it's an
+ // unregistered ambiguity error which would result in a panic
+ // caused by inconsistency `path_res`
+ // more details: https://github.com/rust-lang/rust/pull/111761
+ return;
}
}
let entry = self.r.extern_prelude.entry(ident.normalize_to_macros_2_0()).or_insert(
@@ -929,9 +926,15 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
}
/// Builds the reduced graph for a single item in an external crate.
- fn build_reduced_graph_for_external_crate_res(&mut self, child: ModChild) {
+ fn build_reduced_graph_for_external_crate_res(&mut self, child: &ModChild) {
let parent = self.parent_scope.module;
- let ModChild { ident, res, vis, span, .. } = child;
+ let ModChild { ident, res, vis, ref reexport_chain } = *child;
+ let span = self.r.def_span(
+ reexport_chain
+ .first()
+ .and_then(|reexport| reexport.id())
+ .unwrap_or_else(|| res.def_id()),
+ );
let res = res.expect_non_local();
let expansion = self.parent_scope.expansion;
// Record primary definitions.
@@ -1001,7 +1004,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
let msg = format!("`{}` is already in scope", name);
let note =
"macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)";
- self.r.tcx.sess.struct_span_err(span, &msg).note(note).emit();
+ self.r.tcx.sess.struct_span_err(span, msg).note(note).emit();
}
}
@@ -1025,11 +1028,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
self.r
.tcx
.sess
- .struct_span_err(
- attr.span,
- "`#[macro_use]` is not supported on `extern crate self`",
- )
- .emit();
+ .emit_err(errors::MacroUseExternCrateSelf { span: attr.span });
}
}
let ill_formed = |span| {
diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs
index ae3fd0ede..dc35c8b17 100644
--- a/compiler/rustc_resolve/src/check_unused.rs
+++ b/compiler/rustc_resolve/src/check_unused.rs
@@ -117,16 +117,11 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
match item.kind {
ast::UseTreeKind::Simple(Some(ident)) => {
if ident.name == kw::Underscore
- && !self
- .r
- .import_res_map
- .get(&id)
- .map(|per_ns| {
- per_ns.iter().filter_map(|res| res.as_ref()).any(|res| {
- matches!(res, Res::Def(DefKind::Trait | DefKind::TraitAlias, _))
- })
+ && !self.r.import_res_map.get(&id).is_some_and(|per_ns| {
+ per_ns.iter().filter_map(|res| res.as_ref()).any(|res| {
+ matches!(res, Res::Def(DefKind::Trait | DefKind::TraitAlias, _))
})
- .unwrap_or(false)
+ })
{
self.unused_import(self.base_id).add(id);
}
@@ -418,7 +413,7 @@ impl Resolver<'_, '_> {
UNUSED_IMPORTS,
unused.use_tree_id,
ms,
- &msg,
+ msg,
BuiltinLintDiagnostics::UnusedImports(fix_msg.into(), fixes, test_module_span),
);
}
@@ -469,7 +464,7 @@ impl Resolver<'_, '_> {
.r
.extern_prelude
.get(&extern_crate.ident)
- .map_or(false, |entry| !entry.introduced_by_item)
+ .is_some_and(|entry| !entry.introduced_by_item)
{
continue;
}
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 0c9d30608..8c6ac822a 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -28,10 +28,10 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{BytePos, Span, SyntaxContext};
use thin_vec::ThinVec;
-use crate::errors as errs;
use crate::imports::{Import, ImportKind};
use crate::late::{PatternSource, Rib};
use crate::path_names_to_string;
+use crate::{errors as errs, BindingKey};
use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, Finalize};
use crate::{HasGenericParams, MacroRulesScope, Module, ModuleKind, ModuleOrUniformRoot};
use crate::{LexicalScopeBinding, NameBinding, NameBindingKind, PrivacyError, VisResolutionError};
@@ -238,7 +238,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
},
};
- err.note(&format!(
+ err.note(format!(
"`{}` must be defined only once in the {} namespace of this {}",
name,
ns.descr(),
@@ -663,15 +663,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
Ident::with_dummy_span(name),
Namespace::ValueNS,
&parent_scope,
- &|res: Res| match res {
- Res::Def(
- DefKind::Ctor(CtorOf::Variant, CtorKind::Const)
- | DefKind::Ctor(CtorOf::Struct, CtorKind::Const)
- | DefKind::Const
- | DefKind::AssocConst,
- _,
- ) => true,
- _ => false,
+ &|res: Res| {
+ matches!(
+ res,
+ Res::Def(
+ DefKind::Ctor(CtorOf::Variant, CtorKind::Const)
+ | DefKind::Ctor(CtorOf::Struct, CtorKind::Const)
+ | DefKind::Const
+ | DefKind::AssocConst,
+ _,
+ )
+ )
},
);
@@ -681,7 +683,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
making the path in the pattern qualified: `path::to::ModOrType::{}`",
name,
);
- err.span_help(span, &help_msg);
+ err.span_help(span, help_msg);
}
show_candidates(
self.tcx,
@@ -781,10 +783,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if let Some((suggestions, msg, applicability)) = suggestion {
if suggestions.is_empty() {
- err.help(&msg);
+ err.help(msg);
return err;
}
- err.multipart_suggestion(&msg, suggestions, applicability);
+ err.multipart_suggestion(msg, suggestions, applicability);
}
err
@@ -862,18 +864,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ResolutionError::ForwardDeclaredGenericParam => {
self.tcx.sess.create_err(errs::ForwardDeclaredGenericParam { span })
}
- ResolutionError::ParamInTyOfConstParam(name) => {
- self.tcx.sess.create_err(errs::ParamInTyOfConstParam { span, name })
- }
- ResolutionError::ParamInNonTrivialAnonConst { name, is_type } => {
+ ResolutionError::ParamInTyOfConstParam { name, param_kind: is_type } => self
+ .tcx
+ .sess
+ .create_err(errs::ParamInTyOfConstParam { span, name, param_kind: is_type }),
+ ResolutionError::ParamInNonTrivialAnonConst { name, param_kind: is_type } => {
self.tcx.sess.create_err(errs::ParamInNonTrivialAnonConst {
span,
name,
- sub_is_type: if is_type {
- errs::ParamInNonTrivialAnonConstIsType::AType
- } else {
- errs::ParamInNonTrivialAnonConstIsType::NotAType { name }
- },
+ param_kind: is_type,
help: self
.tcx
.sess
@@ -881,6 +880,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
.then_some(errs::ParamInNonTrivialAnonConstHelp),
})
}
+ ResolutionError::ParamInEnumDiscriminant { name, param_kind: is_type } => self
+ .tcx
+ .sess
+ .create_err(errs::ParamInEnumDiscriminant { span, name, param_kind: is_type }),
ResolutionError::SelfInGenericParamDefault => {
self.tcx.sess.create_err(errs::SelfInGenericParamDefault { span })
}
@@ -928,7 +931,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
} => {
let mut err = self.tcx.sess.struct_span_err_with_code(
span,
- &format!(
+ format!(
"item `{}` is an associated {}, which doesn't match its trait `{}`",
name, kind, trait_path,
),
@@ -945,6 +948,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ResolutionError::InvalidAsmSym => {
self.tcx.sess.create_err(errs::InvalidAsmSym { span })
}
+ ResolutionError::LowercaseSelf => {
+ self.tcx.sess.create_err(errs::LowercaseSelf { span })
+ }
}
}
@@ -1357,7 +1363,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) {
let msg = format!("unsafe traits like `{}` should be implemented explicitly", ident);
- err.span_note(ident.span, &msg);
+ err.span_note(ident.span, msg);
return;
}
if self.macro_names.contains(&ident.normalize_to_macros_2_0()) {
@@ -1417,7 +1423,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if !import.span.is_dummy() {
err.span_note(
import.span,
- &format!("`{}` is imported here, but it is {}", ident, desc),
+ format!("`{}` is imported here, but it is {}", ident, desc),
);
// Silence the 'unused import' warning we might get,
// since this diagnostic already covers that import.
@@ -1425,7 +1431,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
return;
}
}
- err.note(&format!("`{}` is in scope, but it is {}", ident, desc));
+ err.note(format!("`{}` is in scope, but it is {}", ident, desc));
return;
}
}
@@ -1472,7 +1478,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
err.span_label(
self.tcx.sess.source_map().guess_head_span(def_span),
- &format!(
+ format!(
"{}{} `{}` defined here",
prefix,
suggestion.res.descr(),
@@ -1490,7 +1496,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
format!("maybe you meant this {}", suggestion.res.descr())
}
};
- err.span_suggestion(span, &msg, suggestion.candidate, Applicability::MaybeIncorrect);
+ err.span_suggestion(span, msg, suggestion.candidate, Applicability::MaybeIncorrect);
true
}
@@ -1532,7 +1538,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let mut err = struct_span_err!(self.tcx.sess, ident.span, E0659, "`{ident}` is ambiguous");
err.span_label(ident.span, "ambiguous name");
- err.note(&format!("ambiguous because of {}", kind.descr()));
+ err.note(format!("ambiguous because of {}", kind.descr()));
let mut could_refer_to = |b: &NameBinding<'_>, misc: AmbiguityErrorMisc, also: &str| {
let what = self.binding_description(b, ident, misc == AmbiguityErrorMisc::FromPrelude);
@@ -1560,10 +1566,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
AmbiguityErrorMisc::FromPrelude | AmbiguityErrorMisc::None => {}
}
- err.span_note(b.span, &note_msg);
+ err.span_note(b.span, note_msg);
for (i, help_msg) in help_msgs.iter().enumerate() {
let or = if i == 0 { "" } else { "or " };
- err.help(&format!("{}{}", or, help_msg));
+ err.help(format!("{}{}", or, help_msg));
}
};
@@ -1606,7 +1612,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let descr = get_descr(binding);
let mut err =
struct_span_err!(self.tcx.sess, ident.span, E0603, "{} `{}` is private", descr, ident);
- err.span_label(ident.span, &format!("private {}", descr));
+ err.span_label(ident.span, format!("private {}", descr));
let mut non_exhaustive = None;
// If an ADT is foreign and marked as `non_exhaustive`, then that's
@@ -1621,7 +1627,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
err.span_label(span, "a constructor is private if any of the fields is private");
if let Res::Def(_, d) = res && let Some(fields) = self.field_visibility_spans.get(&d) {
err.multipart_suggestion_verbose(
- &format!(
+ format!(
"consider making the field{} publicly accessible",
pluralize!(fields.len())
),
@@ -1674,7 +1680,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
format!("cannot be constructed because it is `#[non_exhaustive]`"),
);
}
- err.span_note(note_span, &msg);
+ err.span_note(note_span, msg);
}
err.emit();
@@ -1826,8 +1832,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
(msg, None)
} else if ident.name == kw::SelfUpper {
- ("`Self` is only available in impls, traits, and type definitions".to_string(), None)
- } else if ident.name.as_str().chars().next().map_or(false, |c| c.is_ascii_uppercase()) {
+ // As mentioned above, `opt_ns` being `None` indicates a module path in import.
+ // We can use this to improve a confusing error for, e.g. `use Self::Variant` in an
+ // impl
+ if opt_ns.is_none() {
+ ("`Self` cannot be used in imports".to_string(), None)
+ } else {
+ (
+ "`Self` is only available in impls, traits, and type definitions".to_string(),
+ None,
+ )
+ }
+ } else if ident.name.as_str().chars().next().is_some_and(|c| c.is_ascii_uppercase()) {
// Check whether the name refers to an item in the value namespace.
let binding = if let Some(ribs) = ribs {
self.resolve_ident_in_lexical_scope(
@@ -1867,15 +1883,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
Some(LexicalScopeBinding::Item(name_binding)) => Some(name_binding.span),
_ => None,
};
- let suggestion = if let Some(span) = match_span {
- Some((
+ let suggestion = match_span.map(|span| {
+ (
vec![(span, String::from(""))],
format!("`{}` is defined here, but is not a type", ident),
Applicability::MaybeIncorrect,
- ))
- } else {
- None
- };
+ )
+ });
(format!("use of undeclared type `{}`", ident), suggestion)
} else {
@@ -2077,7 +2091,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
let resolutions = self.resolutions(crate_module).borrow();
- let resolution = resolutions.get(&self.new_key(ident, MacroNS))?;
+ let binding_key = BindingKey::new(ident, MacroNS);
+ let resolution = resolutions.get(&binding_key)?;
let binding = resolution.borrow().binding()?;
if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() {
let module_name = crate_module.kind.name().unwrap();
@@ -2150,7 +2165,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let is_definitely_crate = import
.module_path
.first()
- .map_or(false, |f| f.ident.name != kw::SelfLower && f.ident.name != kw::Super);
+ .is_some_and(|f| f.ident.name != kw::SelfLower && f.ident.name != kw::Super);
// Add the import to the start, with a `{` if required.
let start_point = source_map.start_point(after_crate_name);
@@ -2444,7 +2459,7 @@ fn show_candidates(
};
for note in accessible_path_strings.iter().flat_map(|cand| cand.3.as_ref()) {
- err.note(note);
+ err.note(note.clone());
}
if let Some(span) = use_placement_span {
@@ -2452,7 +2467,7 @@ fn show_candidates(
DiagnosticMode::Pattern => {
err.span_suggestions(
span,
- &msg,
+ msg,
accessible_path_strings.into_iter().map(|a| a.0),
Applicability::MaybeIncorrect,
);
@@ -2471,7 +2486,7 @@ fn show_candidates(
err.span_suggestions_with_style(
span,
- &msg,
+ msg,
accessible_path_strings.into_iter().map(|a| a.0),
Applicability::MaybeIncorrect,
SuggestionStyle::ShowAlways,
@@ -2481,7 +2496,7 @@ fn show_candidates(
if sp.can_be_used_for_suggestions() {
err.span_suggestion_verbose(
sp,
- &format!("if you import `{}`, refer to it directly", last.ident),
+ format!("if you import `{}`, refer to it directly", last.ident),
"",
Applicability::Unspecified,
);
@@ -2495,7 +2510,7 @@ fn show_candidates(
msg.push_str(&candidate.0);
}
- err.help(&msg);
+ err.help(msg);
}
} else if !matches!(mode, DiagnosticMode::Import) {
assert!(!inaccessible_path_strings.is_empty());
@@ -2520,9 +2535,9 @@ fn show_candidates(
let span = tcx.sess.source_map().guess_head_span(span);
let mut multi_span = MultiSpan::from_span(span);
multi_span.push_span_label(span, "not accessible");
- err.span_note(multi_span, &msg);
+ err.span_note(multi_span, msg);
} else {
- err.note(&msg);
+ err.note(msg);
}
if let Some(note) = (*note).as_deref() {
err.note(note);
@@ -2566,10 +2581,10 @@ fn show_candidates(
}
for note in inaccessible_path_strings.iter().flat_map(|cand| cand.3.as_ref()) {
- err.note(note);
+ err.note(note.clone());
}
- err.span_note(multi_span, &msg);
+ err.span_note(multi_span, msg);
}
}
}
diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs
index bed579f6b..7393bdb38 100644
--- a/compiler/rustc_resolve/src/effective_visibilities.rs
+++ b/compiler/rustc_resolve/src/effective_visibilities.rs
@@ -175,7 +175,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
/// to not update anything and we can skip it.
///
/// We are checking this condition only if the correct value of private visibility is
- /// cheaply available, otherwise it does't make sense performance-wise.
+ /// cheaply available, otherwise it doesn't make sense performance-wise.
///
/// `None` is returned if the update can be skipped,
/// and cheap private visibility is returned otherwise.
@@ -199,7 +199,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
let tcx = self.r.tcx;
self.changed |= self.import_effective_visibilities.update(
binding,
- nominal_vis,
+ Some(nominal_vis),
|| cheap_private_vis.unwrap_or_else(|| self.r.private_vis_import(binding)),
inherited_eff_vis,
parent_id.level(),
@@ -213,7 +213,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
let tcx = self.r.tcx;
self.changed |= self.def_effective_visibilities.update(
def_id,
- nominal_vis,
+ Some(nominal_vis),
|| cheap_private_vis.unwrap_or_else(|| self.r.private_vis_def(def_id)),
inherited_eff_vis,
parent_id.level(),
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index afa796cb6..2ab55f126 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -22,7 +22,7 @@ pub(crate) struct UnderscoreLifetimeNameCannotBeUsedHere(#[primary_span] pub(cra
#[derive(Diagnostic)]
#[diag(resolve_crate_may_not_be_imported)]
-pub(crate) struct CrateMayNotBeImprted(#[primary_span] pub(crate) Span);
+pub(crate) struct CrateMayNotBeImported(#[primary_span] pub(crate) Span);
#[derive(Diagnostic)]
#[diag(resolve_crate_root_imports_must_be_named_explicitly)]
@@ -326,6 +326,18 @@ pub(crate) struct ParamInTyOfConstParam {
#[label]
pub(crate) span: Span,
pub(crate) name: Symbol,
+ #[subdiagnostic]
+ pub(crate) param_kind: Option<ParamKindInTyOfConstParam>,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum ParamKindInTyOfConstParam {
+ #[note(resolve_type_param_in_ty_of_const_param)]
+ Type,
+ #[note(resolve_const_param_in_ty_of_const_param)]
+ Const,
+ #[note(resolve_lifetime_param_in_ty_of_const_param)]
+ Lifetime,
}
#[derive(Diagnostic)]
@@ -344,7 +356,7 @@ pub(crate) struct ParamInNonTrivialAnonConst {
pub(crate) span: Span,
pub(crate) name: Symbol,
#[subdiagnostic]
- pub(crate) sub_is_type: ParamInNonTrivialAnonConstIsType,
+ pub(crate) param_kind: ParamKindInNonTrivialAnonConst,
#[subdiagnostic]
pub(crate) help: Option<ParamInNonTrivialAnonConstHelp>,
}
@@ -354,11 +366,13 @@ pub(crate) struct ParamInNonTrivialAnonConst {
pub(crate) struct ParamInNonTrivialAnonConstHelp;
#[derive(Subdiagnostic)]
-pub(crate) enum ParamInNonTrivialAnonConstIsType {
- #[note(resolve_param_in_non_trivial_anon_const_sub_type)]
- AType,
- #[help(resolve_param_in_non_trivial_anon_const_sub_non_type)]
- NotAType { name: Symbol },
+pub(crate) enum ParamKindInNonTrivialAnonConst {
+ #[note(resolve_type_param_in_non_trivial_anon_const)]
+ Type,
+ #[help(resolve_const_param_in_non_trivial_anon_const)]
+ Const { name: Symbol },
+ #[note(resolve_lifetime_param_in_non_trivial_anon_const)]
+ Lifetime,
}
#[derive(Diagnostic)]
@@ -429,6 +443,14 @@ pub(crate) struct InvalidAsmSym {
}
#[derive(Diagnostic)]
+#[diag(resolve_lowercase_self)]
+pub(crate) struct LowercaseSelf {
+ #[primary_span]
+ #[suggestion(code = "Self", applicability = "maybe-incorrect", style = "short")]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
#[diag(resolve_trait_impl_duplicate, code = "E0201")]
pub(crate) struct TraitImplDuplicate {
#[primary_span]
@@ -508,3 +530,55 @@ pub(crate) struct RemoveSurroundingDerive {
pub(crate) struct AddAsNonDerive<'a> {
pub(crate) macro_path: &'a str,
}
+
+#[derive(Diagnostic)]
+#[diag(resolve_proc_macro_same_crate)]
+pub(crate) struct ProcMacroSameCrate {
+ #[primary_span]
+ pub(crate) span: Span,
+ #[help]
+ pub(crate) is_test: bool,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_imported_crate)]
+pub(crate) struct CrateImported {
+ #[primary_span]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_macro_use_extern_crate_self)]
+pub(crate) struct MacroUseExternCrateSelf {
+ #[primary_span]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_accessible_unsure)]
+#[note]
+pub(crate) struct CfgAccessibleUnsure {
+ #[primary_span]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_param_in_enum_discriminant)]
+pub(crate) struct ParamInEnumDiscriminant {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ pub(crate) name: Symbol,
+ #[subdiagnostic]
+ pub(crate) param_kind: ParamKindInEnumDiscriminant,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum ParamKindInEnumDiscriminant {
+ #[note(resolve_type_param_in_enum_discriminant)]
+ Type,
+ #[note(resolve_const_param_in_enum_discriminant)]
+ Const,
+ #[note(resolve_lifetime_param_in_enum_discriminant)]
+ Lifetime,
+}
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 5a56d7b99..945c7ce3a 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -13,10 +13,12 @@ use rustc_span::{Span, DUMMY_SP};
use std::ptr;
+use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
use crate::late::{
- ConstantHasGenerics, ConstantItemKind, HasGenericParams, PathSource, Rib, RibKind,
+ ConstantHasGenerics, HasGenericParams, NoConstantGenericsReason, PathSource, Rib, RibKind,
};
use crate::macros::{sub_namespace_match, MacroRulesScope};
+use crate::BindingKey;
use crate::{errors, AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize};
use crate::{Import, ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot};
use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError, Res};
@@ -24,7 +26,6 @@ use crate::{ResolutionError, Resolver, Scope, ScopeSet, Segment, ToNameBinding,
use Determinacy::*;
use Namespace::*;
-use RibKind::*;
type Visibility = ty::Visibility<LocalDefId>;
@@ -324,8 +325,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
module = match ribs[i].kind {
- ModuleRibKind(module) => module,
- MacroDefinition(def) if def == self.macro_def(ident.span.ctxt()) => {
+ RibKind::Module(module) => module,
+ RibKind::MacroDefinition(def) if def == self.macro_def(ident.span.ctxt()) => {
// If an invocation of this macro created `ident`, give up on `ident`
// and switch to `ident`'s source from the macro definition.
ident.span.remove_mark();
@@ -527,7 +528,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
lint_id,
orig_ident.span,
- &format!(
+ format!(
"cannot find {} `{}` in this scope",
ns.descr(),
ident
@@ -865,7 +866,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
};
- let key = self.new_key(ident, ns);
+ let key = BindingKey::new(ident, ns);
let resolution =
self.resolution(module, key).try_borrow_mut().map_err(|_| (Determined, Weak::No))?; // This happens when there is a cycle of imports.
@@ -1084,7 +1085,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let ribs = &all_ribs[rib_index + 1..];
// An invalid forward use of a generic parameter from a previous default.
- if let ForwardGenericParamBanRibKind = all_ribs[rib_index].kind {
+ if let RibKind::ForwardGenericParamBan = all_ribs[rib_index].kind {
if let Some(span) = finalize {
let res_error = if rib_ident.name == kw::SelfUpper {
ResolutionError::SelfInGenericParamDefault
@@ -1104,14 +1105,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
for rib in ribs {
match rib.kind {
- NormalRibKind
- | ClosureOrAsyncRibKind
- | ModuleRibKind(..)
- | MacroDefinition(..)
- | ForwardGenericParamBanRibKind => {
+ RibKind::Normal
+ | RibKind::ClosureOrAsync
+ | RibKind::Module(..)
+ | RibKind::MacroDefinition(..)
+ | RibKind::ForwardGenericParamBan => {
// Nothing to do. Continue.
}
- ItemRibKind(_) | AssocItemRibKind => {
+ RibKind::Item(_) | RibKind::AssocItem => {
// This was an attempt to access an upvar inside a
// named function item. This is not allowed, so we
// report an error.
@@ -1123,42 +1124,45 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
res_err = Some((span, CannotCaptureDynamicEnvironmentInFnItem));
}
}
- ConstantItemRibKind(_, item) => {
+ RibKind::ConstantItem(_, item) => {
// Still doesn't deal with upvars
if let Some(span) = finalize {
- let (span, resolution_error) =
- if let Some((ident, constant_item_kind)) = item {
- let kind_str = match constant_item_kind {
- ConstantItemKind::Const => "const",
- ConstantItemKind::Static => "static",
- };
- (
- span,
- AttemptToUseNonConstantValueInConstant(
- ident, "let", kind_str,
- ),
- )
- } else {
- (
- rib_ident.span,
- AttemptToUseNonConstantValueInConstant(
- original_rib_ident_def,
- "const",
- "let",
- ),
- )
- };
+ let (span, resolution_error) = match item {
+ None if rib_ident.as_str() == "self" => (span, LowercaseSelf),
+ None => (
+ rib_ident.span,
+ AttemptToUseNonConstantValueInConstant(
+ original_rib_ident_def,
+ "const",
+ "let",
+ ),
+ ),
+ Some((ident, kind)) => (
+ span,
+ AttemptToUseNonConstantValueInConstant(
+ ident,
+ "let",
+ kind.as_str(),
+ ),
+ ),
+ };
self.report_error(span, resolution_error);
}
return Res::Err;
}
- ConstParamTyRibKind => {
+ RibKind::ConstParamTy => {
if let Some(span) = finalize {
- self.report_error(span, ParamInTyOfConstParam(rib_ident.name));
+ self.report_error(
+ span,
+ ParamInTyOfConstParam {
+ name: rib_ident.name,
+ param_kind: None,
+ },
+ );
}
return Res::Err;
}
- InlineAsmSymRibKind => {
+ RibKind::InlineAsmSym => {
if let Some(span) = finalize {
self.report_error(span, InvalidAsmSym);
}
@@ -1174,23 +1178,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
for rib in ribs {
let has_generic_params: HasGenericParams = match rib.kind {
- NormalRibKind
- | ClosureOrAsyncRibKind
- | ModuleRibKind(..)
- | MacroDefinition(..)
- | InlineAsmSymRibKind
- | AssocItemRibKind
- | ForwardGenericParamBanRibKind => {
+ RibKind::Normal
+ | RibKind::ClosureOrAsync
+ | RibKind::Module(..)
+ | RibKind::MacroDefinition(..)
+ | RibKind::InlineAsmSym
+ | RibKind::AssocItem
+ | RibKind::ForwardGenericParamBan => {
// Nothing to do. Continue.
continue;
}
- ConstantItemRibKind(trivial, _) => {
- let features = self.tcx.sess.features_untracked();
- // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
- if !(trivial == ConstantHasGenerics::Yes
- || features.generic_const_exprs)
- {
+ RibKind::ConstantItem(trivial, _) => {
+ if let ConstantHasGenerics::No(cause) = trivial {
// HACK(min_const_generics): If we encounter `Self` in an anonymous
// constant we can't easily tell if it's generic at this stage, so
// we instead remember this and then enforce the self type to be
@@ -1208,13 +1208,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
} else {
if let Some(span) = finalize {
- self.report_error(
- span,
- ResolutionError::ParamInNonTrivialAnonConst {
- name: rib_ident.name,
- is_type: true,
- },
- );
+ let error = match cause {
+ NoConstantGenericsReason::IsEnumDiscriminant => {
+ ResolutionError::ParamInEnumDiscriminant {
+ name: rib_ident.name,
+ param_kind: ParamKindInEnumDiscriminant::Type,
+ }
+ }
+ NoConstantGenericsReason::NonTrivialConstArg => {
+ ResolutionError::ParamInNonTrivialAnonConst {
+ name: rib_ident.name,
+ param_kind:
+ ParamKindInNonTrivialAnonConst::Type,
+ }
+ }
+ };
+ self.report_error(span, error);
self.tcx.sess.delay_span_bug(span, CG_BUG_STR);
}
@@ -1226,12 +1235,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
// This was an attempt to use a type parameter outside its scope.
- ItemRibKind(has_generic_params) => has_generic_params,
- ConstParamTyRibKind => {
+ RibKind::Item(has_generic_params) => has_generic_params,
+ RibKind::ConstParamTy => {
if let Some(span) = finalize {
self.report_error(
span,
- ResolutionError::ParamInTyOfConstParam(rib_ident.name),
+ ResolutionError::ParamInTyOfConstParam {
+ name: rib_ident.name,
+ param_kind: Some(errors::ParamKindInTyOfConstParam::Type),
+ },
);
}
return Res::Err;
@@ -1253,29 +1265,34 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
Res::Def(DefKind::ConstParam, _) => {
for rib in ribs {
let has_generic_params = match rib.kind {
- NormalRibKind
- | ClosureOrAsyncRibKind
- | ModuleRibKind(..)
- | MacroDefinition(..)
- | InlineAsmSymRibKind
- | AssocItemRibKind
- | ForwardGenericParamBanRibKind => continue,
-
- ConstantItemRibKind(trivial, _) => {
- let features = self.tcx.sess.features_untracked();
- // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
- if !(trivial == ConstantHasGenerics::Yes
- || features.generic_const_exprs)
- {
+ RibKind::Normal
+ | RibKind::ClosureOrAsync
+ | RibKind::Module(..)
+ | RibKind::MacroDefinition(..)
+ | RibKind::InlineAsmSym
+ | RibKind::AssocItem
+ | RibKind::ForwardGenericParamBan => continue,
+
+ RibKind::ConstantItem(trivial, _) => {
+ if let ConstantHasGenerics::No(cause) = trivial {
if let Some(span) = finalize {
- self.report_error(
- span,
- ResolutionError::ParamInNonTrivialAnonConst {
- name: rib_ident.name,
- is_type: false,
- },
- );
- self.tcx.sess.delay_span_bug(span, CG_BUG_STR);
+ let error = match cause {
+ NoConstantGenericsReason::IsEnumDiscriminant => {
+ ResolutionError::ParamInEnumDiscriminant {
+ name: rib_ident.name,
+ param_kind: ParamKindInEnumDiscriminant::Const,
+ }
+ }
+ NoConstantGenericsReason::NonTrivialConstArg => {
+ ResolutionError::ParamInNonTrivialAnonConst {
+ name: rib_ident.name,
+ param_kind: ParamKindInNonTrivialAnonConst::Const {
+ name: rib_ident.name,
+ },
+ }
+ }
+ };
+ self.report_error(span, error);
}
return Res::Err;
@@ -1284,12 +1301,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
continue;
}
- ItemRibKind(has_generic_params) => has_generic_params,
- ConstParamTyRibKind => {
+ RibKind::Item(has_generic_params) => has_generic_params,
+ RibKind::ConstParamTy => {
if let Some(span) = finalize {
self.report_error(
span,
- ResolutionError::ParamInTyOfConstParam(rib_ident.name),
+ ResolutionError::ParamInTyOfConstParam {
+ name: rib_ident.name,
+ param_kind: Some(errors::ParamKindInTyOfConstParam::Const),
+ },
);
}
return Res::Err;
@@ -1345,7 +1365,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ribs: Option<&PerNS<Vec<Rib<'a>>>>,
ignore_binding: Option<&'a NameBinding<'a>>,
) -> PathResult<'a> {
- debug!("resolve_path(path={:?}, opt_ns={:?}, finalize={:?})", path, opt_ns, finalize);
+ debug!(
+ "resolve_path(path={:?}, opt_ns={:?}, finalize={:?}) path_len: {}",
+ path,
+ opt_ns,
+ finalize,
+ path.len()
+ );
let mut module = None;
let mut allow_super = true;
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 3c22d51c3..7c4c05d4b 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -405,17 +405,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
t
}
- // Define a dummy resolution containing a `Res::Err` as a placeholder for a failed resolution,
- // also mark such failed imports as used to avoid duplicate diagnostics.
- fn import_dummy_binding(&mut self, import: &'a Import<'a>) {
+ // 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: &'a Import<'a>, is_indeterminate: bool) {
if let ImportKind::Single { target, ref target_bindings, .. } = import.kind {
- if target_bindings.iter().any(|binding| binding.get().is_some()) {
+ if !(is_indeterminate || target_bindings.iter().all(|binding| binding.get().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);
self.per_ns(|this, ns| {
- let key = this.new_key(target, ns);
+ let key = BindingKey::new(target, ns);
let _ = this.try_define(import.parent_scope.module, key, dummy_binding);
});
self.record_use(target, dummy_binding, false);
@@ -474,7 +475,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// If this import is unresolved then create a dummy import
// resolution for it so that later resolve stages won't complain.
- self.import_dummy_binding(import);
+ self.import_dummy_binding(import, is_indeterminate);
if let Some(err) = unresolved_import_error {
if let ImportKind::Single { source, ref source_bindings, .. } = import.kind {
@@ -578,7 +579,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let mut diag = struct_span_err!(self.tcx.sess, span, E0432, "{}", &msg);
if let Some((_, UnresolvedImportError { note: Some(note), .. })) = errors.iter().last() {
- diag.note(note);
+ diag.note(note.clone());
}
for (import, err) in errors.into_iter().take(MAX_LABEL_COUNT) {
@@ -588,10 +589,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if let Some((suggestions, msg, applicability)) = err.suggestion {
if suggestions.is_empty() {
- diag.help(&msg);
+ diag.help(msg);
continue;
}
- diag.multipart_suggestion(&msg, suggestions, applicability);
+ diag.multipart_suggestion(msg, suggestions, applicability);
}
if let Some(candidates) = &err.candidates {
@@ -712,7 +713,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
.span_label(import.span, "cannot be imported directly")
.emit();
}
- let key = this.new_key(target, ns);
+ let key = BindingKey::new(target, ns);
this.update_resolution(parent, key, |_, resolution| {
resolution.single_imports.remove(&Interned::new_unchecked(import));
});
@@ -1063,7 +1064,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
PUB_USE_OF_PRIVATE_EXTERN_CRATE,
import_id,
import.span,
- &msg,
+ msg,
);
} else {
let error_msg = if crate_private_reexport {
@@ -1084,7 +1085,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
struct_span_err!(self.tcx.sess, import.span, E0365, "{}", error_msg)
.span_label(import.span, label_msg)
- .note(&format!("consider declaring type or module `{}` with `pub`", ident))
+ .note(format!("consider declaring type or module `{}` with `pub`", ident))
.emit();
} else {
let mut err =
@@ -1102,7 +1103,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
_ => {
err.span_note(
import.span,
- &format!(
+ format!(
"consider marking `{ident}` as `pub` in the imported module"
),
);
@@ -1200,7 +1201,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
UNUSED_IMPORTS,
id,
import.span,
- &format!("the item `{}` is imported redundantly", ident),
+ format!("the item `{}` is imported redundantly", ident),
BuiltinLintDiagnostics::RedundantImport(redundant_spans, ident),
);
}
@@ -1261,14 +1262,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
*module.globs.borrow_mut() = Vec::new();
if let Some(def_id) = module.opt_def_id() {
- let mut non_reexports = Vec::new();
- let mut reexports = Vec::new();
+ let mut children = Vec::new();
module.for_each_child(self, |this, ident, _, binding| {
let res = binding.res().expect_non_local();
- if !binding.is_import() {
- non_reexports.push(res.def_id().expect_local());
- } else if res != def::Res::Err && !binding.is_ambiguity() {
+ if res != def::Res::Err && !binding.is_ambiguity() {
let mut reexport_chain = SmallVec::new();
let mut next_binding = binding;
while let NameBindingKind::Import { binding, import, .. } = next_binding.kind {
@@ -1276,23 +1274,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
next_binding = binding;
}
- reexports.push(ModChild {
- ident,
- res,
- vis: binding.vis,
- span: binding.span,
- reexport_chain,
- });
+ children.push(ModChild { ident, res, vis: binding.vis, reexport_chain });
}
});
- // Should be fine because this code is only called for local modules.
- let def_id = def_id.expect_local();
- if !non_reexports.is_empty() {
- self.module_children_non_reexports.insert(def_id, non_reexports);
- }
- if !reexports.is_empty() {
- self.module_children_reexports.insert(def_id, reexports);
+ if !children.is_empty() {
+ // Should be fine because this code is only called for local modules.
+ self.module_children.insert(def_id.expect_local(), children);
}
}
}
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 90a2fa89c..e06119076 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -6,8 +6,7 @@
//! If you wonder why there's no `early.rs`, that's because it's split into three files -
//! `build_reduced_graph.rs`, `macros.rs` and `imports.rs`.
-use RibKind::*;
-
+use crate::BindingKey;
use crate::{path_names_to_string, rustdoc, BindingError, Finalize, LexicalScopeBinding};
use crate::{Module, ModuleOrUniformRoot, NameBinding, ParentScope, PathResult};
use crate::{ResolutionError, Resolver, Segment, UseError};
@@ -18,7 +17,7 @@ use rustc_ast::*;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_errors::{Applicability, DiagnosticArgValue, DiagnosticId, IntoDiagnosticArg};
use rustc_hir::def::Namespace::{self, *};
-use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, PartialRes, PerNS};
+use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::{BindingAnnotation, PrimTy, TraitCandidate};
use rustc_middle::middle::resolve_bound_vars::Set1;
@@ -68,6 +67,15 @@ enum IsRepeatExpr {
Yes,
}
+/// Describes whether an `AnonConst` is a type level const arg or
+/// some other form of anon const (i.e. inline consts or enum discriminants)
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+enum AnonConstKind {
+ EnumDiscriminant,
+ InlineConst,
+ ConstArg(IsRepeatExpr),
+}
+
impl PatternSource {
fn descr(self) -> &'static str {
match self {
@@ -107,7 +115,7 @@ pub(crate) enum HasGenericParams {
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub(crate) enum ConstantHasGenerics {
Yes,
- No,
+ No(NoConstantGenericsReason),
}
impl ConstantHasGenerics {
@@ -116,12 +124,42 @@ impl ConstantHasGenerics {
}
}
+/// Reason for why an anon const is not allowed to reference generic parameters
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub(crate) enum NoConstantGenericsReason {
+ /// Const arguments are only allowed to use generic parameters when:
+ /// - `feature(generic_const_exprs)` is enabled
+ /// or
+ /// - the const argument is a sole const generic paramater, i.e. `foo::<{ N }>()`
+ ///
+ /// If neither of the above are true then this is used as the cause.
+ NonTrivialConstArg,
+ /// Enum discriminants are not allowed to reference generic parameters ever, this
+ /// is used when an anon const is in the following position:
+ ///
+ /// ```rust,compile_fail
+ /// enum Foo<const N: isize> {
+ /// Variant = { N }, // this anon const is not allowed to use generics
+ /// }
+ /// ```
+ IsEnumDiscriminant,
+}
+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub(crate) enum ConstantItemKind {
Const,
Static,
}
+impl ConstantItemKind {
+ pub(crate) fn as_str(&self) -> &'static str {
+ match self {
+ Self::Const => "const",
+ Self::Static => "static",
+ }
+ }
+}
+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum RecordPartialRes {
Yes,
@@ -133,28 +171,28 @@ enum RecordPartialRes {
#[derive(Copy, Clone, Debug)]
pub(crate) enum RibKind<'a> {
/// No restriction needs to be applied.
- NormalRibKind,
+ Normal,
/// We passed through an impl or trait and are now in one of its
/// methods or associated types. Allow references to ty params that impl or trait
/// binds. Disallow any other upvars (including other ty params that are
/// upvars).
- AssocItemRibKind,
+ AssocItem,
/// We passed through a closure. Disallow labels.
- ClosureOrAsyncRibKind,
+ ClosureOrAsync,
/// We passed through an item scope. Disallow upvars.
- ItemRibKind(HasGenericParams),
+ Item(HasGenericParams),
/// We're in a constant item. Can't refer to dynamic stuff.
///
/// The item may reference generic parameters in trivial constant expressions.
/// All other constants aren't allowed to use generic params at all.
- ConstantItemRibKind(ConstantHasGenerics, Option<(Ident, ConstantItemKind)>),
+ ConstantItem(ConstantHasGenerics, Option<(Ident, ConstantItemKind)>),
/// We passed through a module.
- ModuleRibKind(Module<'a>),
+ Module(Module<'a>),
/// We passed through a `macro_rules!` statement
MacroDefinition(DefId),
@@ -162,15 +200,15 @@ pub(crate) enum RibKind<'a> {
/// All bindings in this rib are generic parameters that can't be used
/// from the default of a generic parameter because they're not declared
/// before said generic parameter. Also see the `visit_generics` override.
- ForwardGenericParamBanRibKind,
+ ForwardGenericParamBan,
/// We are inside of the type of a const parameter. Can't refer to any
/// parameters.
- ConstParamTyRibKind,
+ ConstParamTy,
/// We are inside a `sym` inline assembly operand. Can only refer to
/// globals.
- InlineAsmSymRibKind,
+ InlineAsmSym,
}
impl RibKind<'_> {
@@ -178,30 +216,30 @@ impl RibKind<'_> {
/// variables.
pub(crate) fn contains_params(&self) -> bool {
match self {
- NormalRibKind
- | ClosureOrAsyncRibKind
- | ConstantItemRibKind(..)
- | ModuleRibKind(_)
- | MacroDefinition(_)
- | ConstParamTyRibKind
- | InlineAsmSymRibKind => false,
- AssocItemRibKind | ItemRibKind(_) | ForwardGenericParamBanRibKind => true,
+ RibKind::Normal
+ | RibKind::ClosureOrAsync
+ | RibKind::ConstantItem(..)
+ | RibKind::Module(_)
+ | RibKind::MacroDefinition(_)
+ | RibKind::ConstParamTy
+ | RibKind::InlineAsmSym => false,
+ RibKind::AssocItem | RibKind::Item(_) | RibKind::ForwardGenericParamBan => true,
}
}
/// This rib forbids referring to labels defined in upwards ribs.
fn is_label_barrier(self) -> bool {
match self {
- NormalRibKind | MacroDefinition(..) => false,
-
- AssocItemRibKind
- | ClosureOrAsyncRibKind
- | ItemRibKind(..)
- | ConstantItemRibKind(..)
- | ModuleRibKind(..)
- | ForwardGenericParamBanRibKind
- | ConstParamTyRibKind
- | InlineAsmSymRibKind => true,
+ RibKind::Normal | RibKind::MacroDefinition(..) => false,
+
+ RibKind::AssocItem
+ | RibKind::ClosureOrAsync
+ | RibKind::Item(..)
+ | RibKind::ConstantItem(..)
+ | RibKind::Module(..)
+ | RibKind::ForwardGenericParamBan
+ | RibKind::ConstParamTy
+ | RibKind::InlineAsmSym => true,
}
}
}
@@ -275,15 +313,18 @@ enum LifetimeRibKind {
/// Signal we cannot find which should be the anonymous lifetime.
ElisionFailure,
- /// FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const
- /// generics. We are disallowing this until we can decide on how we want to handle non-'static
- /// lifetimes in const generics. See issue #74052 for discussion.
- ConstGeneric,
+ /// This rib forbids usage of generic parameters inside of const parameter types.
+ ///
+ /// While this is desirable to support eventually, it is difficult to do and so is
+ /// currently forbidden. See rust-lang/project-const-generics#28 for more info.
+ ConstParamTy,
- /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
- /// This function will emit an error if `generic_const_exprs` is not enabled, the body
- /// identified by `body_id` is an anonymous constant and `lifetime_ref` is non-static.
- AnonConst,
+ /// Usage of generic parameters is forbidden in various positions for anon consts:
+ /// - const arguments when `generic_const_exprs` is not enabled
+ /// - enum discriminant values
+ ///
+ /// This rib emits an error when a lifetime would resolve to a lifetime parameter.
+ ConcreteAnonConst(NoConstantGenericsReason),
/// This rib acts as a barrier to forbid reference to lifetimes of a parent item.
Item,
@@ -548,9 +589,6 @@ struct DiagnosticMetadata<'ast> {
/// they are used (in a `break` or `continue` statement)
unused_labels: FxHashMap<NodeId, Span>,
- /// Only used for better errors on `fn(): fn()`.
- current_type_ascription: Vec<Span>,
-
/// Only used for better errors on `let x = { foo: bar };`.
/// In the case of a parse error with `let x = { foo: bar, };`, this isn't needed, it's only
/// needed for cases where this parses as a correct type ascription.
@@ -653,13 +691,8 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
self.resolve_block(block);
self.parent_scope.macro_rules = old_macro_rules;
}
- fn visit_anon_const(&mut self, constant: &'ast AnonConst) {
- // We deal with repeat expressions explicitly in `resolve_expr`.
- self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| {
- this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
- this.resolve_anon_const(constant, IsRepeatExpr::No);
- })
- })
+ fn visit_anon_const(&mut self, _constant: &'ast AnonConst) {
+ bug!("encountered anon const without a manual call to `resolve_anon_const`");
}
fn visit_expr(&mut self, expr: &'ast Expr) {
self.resolve_expr(expr, None);
@@ -681,7 +714,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
fn visit_ty(&mut self, ty: &'ast Ty) {
let prev = self.diagnostic_metadata.current_trait_object;
let prev_ty = self.diagnostic_metadata.current_type_path;
- match ty.kind {
+ match &ty.kind {
TyKind::Ref(None, _) => {
// Elided lifetime in reference: we resolve as if there was some lifetime `'_` with
// NodeId `ty.id`.
@@ -690,7 +723,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
self.resolve_elided_lifetime(ty.id, span);
visit::walk_ty(self, ty);
}
- TyKind::Path(ref qself, ref path) => {
+ TyKind::Path(qself, path) => {
self.diagnostic_metadata.current_type_path = Some(ty);
self.smart_resolve_path(ty.id, &qself, path, PathSource::Type);
@@ -705,7 +738,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
let span = ty.span.shrink_to_lo().to(path.span.shrink_to_lo());
self.with_generic_param_rib(
&[],
- NormalRibKind,
+ RibKind::Normal,
LifetimeRibKind::Generics {
binder: ty.id,
kind: LifetimeBinderKind::PolyTrait,
@@ -735,15 +768,15 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
visit::walk_ty(self, ty);
self.lifetime_elision_candidates = candidates;
}
- TyKind::TraitObject(ref bounds, ..) => {
+ TyKind::TraitObject(bounds, ..) => {
self.diagnostic_metadata.current_trait_object = Some(&bounds[..]);
visit::walk_ty(self, ty)
}
- TyKind::BareFn(ref bare_fn) => {
+ TyKind::BareFn(bare_fn) => {
let span = ty.span.shrink_to_lo().to(bare_fn.decl_span.shrink_to_lo());
self.with_generic_param_rib(
&bare_fn.generic_params,
- NormalRibKind,
+ RibKind::Normal,
LifetimeRibKind::Generics {
binder: ty.id,
kind: LifetimeBinderKind::BareFnType,
@@ -774,6 +807,13 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
},
)
}
+ TyKind::Array(element_ty, length) => {
+ self.visit_ty(element_ty);
+ self.resolve_anon_const(length, AnonConstKind::ConstArg(IsRepeatExpr::No));
+ }
+ TyKind::Typeof(ct) => {
+ self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::No))
+ }
_ => visit::walk_ty(self, ty),
}
self.diagnostic_metadata.current_trait_object = prev;
@@ -783,7 +823,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
let span = tref.span.shrink_to_lo().to(tref.trait_ref.path.span.shrink_to_lo());
self.with_generic_param_rib(
&tref.bound_generic_params,
- NormalRibKind,
+ RibKind::Normal,
LifetimeRibKind::Generics {
binder: tref.trait_ref.ref_id,
kind: LifetimeBinderKind::PolyTrait,
@@ -807,7 +847,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
ForeignItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
self.with_generic_param_rib(
&generics.params,
- ItemRibKind(HasGenericParams::Yes(generics.span)),
+ RibKind::Item(HasGenericParams::Yes(generics.span)),
LifetimeRibKind::Generics {
binder: foreign_item.id,
kind: LifetimeBinderKind::Item,
@@ -819,7 +859,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
ForeignItemKind::Fn(box Fn { ref generics, .. }) => {
self.with_generic_param_rib(
&generics.params,
- ItemRibKind(HasGenericParams::Yes(generics.span)),
+ RibKind::Item(HasGenericParams::Yes(generics.span)),
LifetimeRibKind::Generics {
binder: foreign_item.id,
kind: LifetimeBinderKind::Function,
@@ -859,13 +899,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
sig.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),
&sig.decl.output,
);
-
- this.record_lifetime_params_for_async(
- fn_id,
- sig.header.asyncness.opt_return_id(),
- );
},
);
+ self.record_lifetime_params_for_async(fn_id, sig.header.asyncness.opt_return_id());
return;
}
FnKind::Fn(..) => {
@@ -877,9 +913,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
debug!("(resolving function) entering function");
// Create a value rib for the function.
- self.with_rib(ValueNS, ClosureOrAsyncRibKind, |this| {
+ self.with_rib(ValueNS, RibKind::ClosureOrAsync, |this| {
// Create a label rib for the function.
- this.with_label_rib(ClosureOrAsyncRibKind, |this| {
+ this.with_label_rib(RibKind::ClosureOrAsync, |this| {
match fn_kind {
FnKind::Fn(_, _, sig, _, generics, body) => {
this.visit_generics(generics);
@@ -1003,36 +1039,25 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
// namespace first, and if that fails we try again in the value namespace. If
// resolution in the value namespace succeeds, we have an generic const argument on
// our hands.
- if let TyKind::Path(ref qself, ref path) = ty.kind {
+ if let TyKind::Path(None, ref path) = ty.kind {
// We cannot disambiguate multi-segment paths right now as that requires type
// checking.
- if path.segments.len() == 1 && path.segments[0].args.is_none() {
+ if path.is_potential_trivial_const_arg() {
let mut check_ns = |ns| {
self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns)
.is_some()
};
if !check_ns(TypeNS) && check_ns(ValueNS) {
- // This must be equivalent to `visit_anon_const`, but we cannot call it
- // directly due to visitor lifetimes so we have to copy-paste some code.
- //
- // Note that we might not be inside of an repeat expression here,
- // but considering that `IsRepeatExpr` is only relevant for
- // non-trivial constants this is doesn't matter.
- self.with_constant_rib(
- IsRepeatExpr::No,
- ConstantHasGenerics::Yes,
- None,
+ self.resolve_anon_const_manual(
+ true,
+ AnonConstKind::ConstArg(IsRepeatExpr::No),
|this| {
this.smart_resolve_path(
ty.id,
- qself,
+ &None,
path,
PathSource::Expr(None),
);
-
- if let Some(ref qself) = *qself {
- this.visit_ty(&qself.ty);
- }
this.visit_path(path, ty.id);
},
);
@@ -1046,7 +1071,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
self.visit_ty(ty);
}
GenericArg::Lifetime(lt) => self.visit_lifetime(lt, visit::LifetimeCtxt::GenericArg),
- GenericArg::Const(ct) => self.visit_anon_const(ct),
+ GenericArg::Const(ct) => {
+ self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::No))
+ }
}
self.diagnostic_metadata.currently_processing_generics = prev;
}
@@ -1062,7 +1089,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
match constraint.kind {
AssocConstraintKind::Equality { ref term } => match term {
Term::Ty(ty) => self.visit_ty(ty),
- Term::Const(c) => self.visit_anon_const(c),
+ Term::Const(c) => {
+ self.resolve_anon_const(c, AnonConstKind::ConstArg(IsRepeatExpr::No))
+ }
},
AssocConstraintKind::Bound { ref bounds } => {
walk_list!(self, visit_param_bound, bounds, BoundKind::Bound);
@@ -1079,7 +1108,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
for rib in self.lifetime_ribs.iter().rev() {
match rib.kind {
// We are inside a `PolyTraitRef`. The lifetimes are
- // to be intoduced in that (maybe implicit) `for<>` binder.
+ // to be introduced in that (maybe implicit) `for<>` binder.
LifetimeRibKind::Generics {
binder,
kind: LifetimeBinderKind::PolyTrait,
@@ -1111,8 +1140,8 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
| LifetimeRibKind::AnonymousReportError
| LifetimeRibKind::Elided(_)
| LifetimeRibKind::ElisionFailure
- | LifetimeRibKind::AnonConst
- | LifetimeRibKind::ConstGeneric => {}
+ | LifetimeRibKind::ConcreteAnonConst(_)
+ | LifetimeRibKind::ConstParamTy => {}
}
}
}
@@ -1136,7 +1165,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
let span = predicate_span.shrink_to_lo().to(bounded_ty.span.shrink_to_lo());
this.with_generic_param_rib(
&bound_generic_params,
- NormalRibKind,
+ RibKind::Normal,
LifetimeRibKind::Generics {
binder: bounded_ty.id,
kind: LifetimeBinderKind::WhereBound,
@@ -1173,7 +1202,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
InlineAsmOperand::Const { anon_const, .. } => {
// Although this is `DefKind::AnonConst`, it is allowed to reference outer
// generic parameters like an inline const.
- self.resolve_inline_const(anon_const);
+ self.resolve_anon_const(anon_const, AnonConstKind::InlineConst);
}
InlineAsmOperand::Sym { sym } => self.visit_inline_asm_sym(sym),
}
@@ -1182,9 +1211,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) {
// This is similar to the code for AnonConst.
- self.with_rib(ValueNS, InlineAsmSymRibKind, |this| {
- this.with_rib(TypeNS, InlineAsmSymRibKind, |this| {
- this.with_label_rib(InlineAsmSymRibKind, |this| {
+ self.with_rib(ValueNS, RibKind::InlineAsmSym, |this| {
+ this.with_rib(TypeNS, RibKind::InlineAsmSym, |this| {
+ this.with_label_rib(RibKind::InlineAsmSym, |this| {
this.smart_resolve_path(sym.id, &sym.qself, &sym.path, PathSource::Expr(None));
visit::walk_inline_asm_sym(this, sym);
});
@@ -1197,6 +1226,10 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
visit::walk_variant(self, v)
}
+ fn visit_variant_discr(&mut self, discr: &'ast AnonConst) {
+ self.resolve_anon_const(discr, AnonConstKind::EnumDiscriminant);
+ }
+
fn visit_field_def(&mut self, f: &'ast FieldDef) {
self.resolve_doc_links(&f.attrs, MaybeExported::Ok(f.id));
visit::walk_field_def(self, f)
@@ -1209,7 +1242,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// although it may be useful to track other components as well for diagnostics.
let graph_root = resolver.graph_root;
let parent_scope = ParentScope::module(graph_root, resolver);
- let start_rib_kind = ModuleRibKind(graph_root);
+ let start_rib_kind = RibKind::Module(graph_root);
LateResolutionVisitor {
r: resolver,
parent_scope,
@@ -1313,8 +1346,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
if let Some(module) = self.r.get_module(self.r.local_def_id(id).to_def_id()) {
// Move down in the graph.
let orig_module = replace(&mut self.parent_scope.module, module);
- self.with_rib(ValueNS, ModuleRibKind(module), |this| {
- this.with_rib(TypeNS, ModuleRibKind(module), |this| {
+ self.with_rib(ValueNS, RibKind::Module(module), |this| {
+ this.with_rib(TypeNS, RibKind::Module(module), |this| {
let ret = f(this);
this.parent_scope.module = orig_module;
ret
@@ -1331,8 +1364,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// provide previous type parameters as they're built. We
// put all the parameters on the ban list and then remove
// them one by one as they are processed and become available.
- let mut forward_ty_ban_rib = Rib::new(ForwardGenericParamBanRibKind);
- let mut forward_const_ban_rib = Rib::new(ForwardGenericParamBanRibKind);
+ let mut forward_ty_ban_rib = Rib::new(RibKind::ForwardGenericParamBan);
+ let mut forward_const_ban_rib = Rib::new(RibKind::ForwardGenericParamBan);
for param in params.iter() {
match param.kind {
GenericParamKind::Type { .. } => {
@@ -1393,9 +1426,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// Const parameters can't have param bounds.
assert!(param.bounds.is_empty());
- this.ribs[TypeNS].push(Rib::new(ConstParamTyRibKind));
- this.ribs[ValueNS].push(Rib::new(ConstParamTyRibKind));
- this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| {
+ this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy));
+ this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy));
+ this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| {
this.visit_ty(ty)
});
this.ribs[TypeNS].pop().unwrap();
@@ -1404,9 +1437,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
if let Some(ref expr) = default {
this.ribs[TypeNS].push(forward_ty_ban_rib);
this.ribs[ValueNS].push(forward_const_ban_rib);
- this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| {
- this.resolve_anon_const(expr, IsRepeatExpr::No)
- });
+ this.resolve_anon_const(
+ expr,
+ AnonConstKind::ConstArg(IsRepeatExpr::No),
+ );
forward_const_ban_rib = this.ribs[ValueNS].pop().unwrap();
forward_ty_ban_rib = this.ribs[TypeNS].pop().unwrap();
}
@@ -1458,7 +1492,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
if let Some(&(_, res)) = rib.bindings.get(&normalized_ident) {
self.record_lifetime_res(lifetime.id, res, LifetimeElisionCandidate::Named);
- if let LifetimeRes::Param { param, .. } = res {
+ if let LifetimeRes::Param { param, binder } = res {
match self.lifetime_uses.entry(param) {
Entry::Vacant(v) => {
debug!("First use of {:?} at {:?}", res, ident.span);
@@ -1472,10 +1506,16 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
LifetimeRibKind::Item
| LifetimeRibKind::AnonymousReportError
| LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many),
- // An anonymous lifetime is legal here, go ahead.
- LifetimeRibKind::AnonymousCreateParameter { .. } => {
- Some(LifetimeUseSet::One { use_span: ident.span, use_ctxt })
- }
+ // An anonymous lifetime is legal here, and bound to the right
+ // place, go ahead.
+ LifetimeRibKind::AnonymousCreateParameter {
+ binder: anon_binder,
+ ..
+ } => Some(if binder == anon_binder {
+ LifetimeUseSet::One { use_span: ident.span, use_ctxt }
+ } else {
+ LifetimeUseSet::Many
+ }),
// Only report if eliding the lifetime would have the same
// semantics.
LifetimeRibKind::Elided(r) => Some(if res == r {
@@ -1484,8 +1524,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
LifetimeUseSet::Many
}),
LifetimeRibKind::Generics { .. }
- | LifetimeRibKind::ConstGeneric => None,
- LifetimeRibKind::AnonConst => {
+ | LifetimeRibKind::ConstParamTy => None,
+ LifetimeRibKind::ConcreteAnonConst(_) => {
span_bug!(ident.span, "unexpected rib kind: {:?}", rib.kind)
}
})
@@ -1504,8 +1544,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
match rib.kind {
LifetimeRibKind::Item => break,
- LifetimeRibKind::ConstGeneric => {
- self.emit_non_static_lt_in_const_generic_error(lifetime);
+ LifetimeRibKind::ConstParamTy => {
+ self.emit_non_static_lt_in_const_param_ty_error(lifetime);
self.record_lifetime_res(
lifetime.id,
LifetimeRes::Error,
@@ -1513,8 +1553,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
);
return;
}
- LifetimeRibKind::AnonConst => {
- self.maybe_emit_forbidden_non_static_lifetime_error(lifetime);
+ LifetimeRibKind::ConcreteAnonConst(cause) => {
+ self.emit_forbidden_non_static_lifetime_error(cause, lifetime);
self.record_lifetime_res(
lifetime.id,
LifetimeRes::Error,
@@ -1613,9 +1653,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
return;
}
LifetimeRibKind::Item => break,
- LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstGeneric => {}
- LifetimeRibKind::AnonConst => {
- // There is always an `Elided(LifetimeRes::Static)` inside an `AnonConst`.
+ LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstParamTy => {}
+ LifetimeRibKind::ConcreteAnonConst(_) => {
+ // There is always an `Elided(LifetimeRes::Infer)` inside an `AnonConst`.
span_bug!(lifetime.ident.span, "unexpected rib kind: {:?}", rib.kind)
}
}
@@ -1835,9 +1875,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
self.report_missing_lifetime_specifiers(vec![missing_lifetime], None);
break;
}
- LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstGeneric => {}
- LifetimeRibKind::AnonConst => {
- // There is always an `Elided(LifetimeRes::Static)` inside an `AnonConst`.
+ LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstParamTy => {}
+ LifetimeRibKind::ConcreteAnonConst(_) => {
+ // There is always an `Elided(LifetimeRes::Infer)` inside an `AnonConst`.
span_bug!(elided_lifetime_span, "unexpected rib kind: {:?}", rib.kind)
}
}
@@ -2079,6 +2119,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
}
visit::walk_ty(self, ty)
}
+
+ // A type may have an expression as a const generic argument.
+ // We do not want to recurse into those.
+ fn visit_expr(&mut self, _: &'a Expr) {}
}
let impl_self = self
@@ -2116,7 +2160,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
for i in (0..self.label_ribs.len()).rev() {
let rib = &self.label_ribs[i];
- if let MacroDefinition(def) = rib.kind {
+ if let RibKind::MacroDefinition(def) = rib.kind {
// If an invocation of this macro created `ident`, give up on `ident`
// and switch to `ident`'s source from the macro definition.
if def == self.r.macro_def(label.span.ctxt()) {
@@ -2164,7 +2208,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
self.with_current_self_item(item, |this| {
this.with_generic_param_rib(
&generics.params,
- ItemRibKind(HasGenericParams::Yes(generics.span)),
+ RibKind::Item(HasGenericParams::Yes(generics.span)),
LifetimeRibKind::Generics {
binder: item.id,
kind: LifetimeBinderKind::Item,
@@ -2205,7 +2249,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
this.r
.tcx
.sess
- .span_err(ident.span, &format!("imports cannot refer to {}", what));
+ .span_err(ident.span, format!("imports cannot refer to {}", what));
}
};
@@ -2245,7 +2289,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
ItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
self.with_generic_param_rib(
&generics.params,
- ItemRibKind(HasGenericParams::Yes(generics.span)),
+ RibKind::Item(HasGenericParams::Yes(generics.span)),
LifetimeRibKind::Generics {
binder: item.id,
kind: LifetimeBinderKind::Item,
@@ -2258,7 +2302,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
ItemKind::Fn(box Fn { ref generics, .. }) => {
self.with_generic_param_rib(
&generics.params,
- ItemRibKind(HasGenericParams::Yes(generics.span)),
+ RibKind::Item(HasGenericParams::Yes(generics.span)),
LifetimeRibKind::Generics {
binder: item.id,
kind: LifetimeBinderKind::Function,
@@ -2297,7 +2341,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// Create a new rib for the trait-wide type parameters.
self.with_generic_param_rib(
&generics.params,
- ItemRibKind(HasGenericParams::Yes(generics.span)),
+ RibKind::Item(HasGenericParams::Yes(generics.span)),
LifetimeRibKind::Generics {
binder: item.id,
kind: LifetimeBinderKind::Item,
@@ -2318,7 +2362,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// Create a new rib for the trait-wide type parameters.
self.with_generic_param_rib(
&generics.params,
- ItemRibKind(HasGenericParams::Yes(generics.span)),
+ RibKind::Item(HasGenericParams::Yes(generics.span)),
LifetimeRibKind::Generics {
binder: item.id,
kind: LifetimeBinderKind::Item,
@@ -2421,11 +2465,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
let mut seen_lifetimes = FxHashSet::default();
// We also can't shadow bindings from the parent item
- if let AssocItemRibKind = kind {
+ if let RibKind::AssocItem = kind {
let mut add_bindings_for_ns = |ns| {
let parent_rib = self.ribs[ns]
.iter()
- .rfind(|r| matches!(r.kind, ItemRibKind(_)))
+ .rfind(|r| matches!(r.kind, RibKind::Item(_)))
.expect("associated item outside of an item");
seen_bindings.extend(parent_rib.bindings.keys().map(|ident| (*ident, ident.span)));
};
@@ -2514,8 +2558,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
};
let res = match kind {
- ItemRibKind(..) | AssocItemRibKind => Res::Def(def_kind, def_id.to_def_id()),
- NormalRibKind => {
+ RibKind::Item(..) | RibKind::AssocItem => Res::Def(def_kind, def_id.to_def_id()),
+ RibKind::Normal => {
if self.r.tcx.sess.features_untracked().non_lifetime_binders {
Res::Def(def_kind, def_id.to_def_id())
} else {
@@ -2561,11 +2605,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
}
fn with_static_rib(&mut self, f: impl FnOnce(&mut Self)) {
- let kind = ItemRibKind(HasGenericParams::No);
+ let kind = RibKind::Item(HasGenericParams::No);
self.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f))
}
- // HACK(min_const_generics,const_evaluatable_unchecked): We
+ // HACK(min_const_generics, generic_const_exprs): We
// want to keep allowing `[0; std::mem::size_of::<*mut T>()]`
// with a future compat lint for now. We do this by adding an
// additional special case for repeat expressions.
@@ -2581,18 +2625,26 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
item: Option<(Ident, ConstantItemKind)>,
f: impl FnOnce(&mut Self),
) {
- self.with_rib(ValueNS, ConstantItemRibKind(may_use_generics, item), |this| {
- this.with_rib(
- TypeNS,
- ConstantItemRibKind(
- may_use_generics.force_yes_if(is_repeat == IsRepeatExpr::Yes),
- item,
- ),
- |this| {
- this.with_label_rib(ConstantItemRibKind(may_use_generics, item), f);
- },
- )
- });
+ let f = |this: &mut Self| {
+ this.with_rib(ValueNS, RibKind::ConstantItem(may_use_generics, item), |this| {
+ this.with_rib(
+ TypeNS,
+ RibKind::ConstantItem(
+ may_use_generics.force_yes_if(is_repeat == IsRepeatExpr::Yes),
+ item,
+ ),
+ |this| {
+ this.with_label_rib(RibKind::ConstantItem(may_use_generics, item), f);
+ },
+ )
+ })
+ };
+
+ if let ConstantHasGenerics::No(cause) = may_use_generics {
+ self.with_lifetime_rib(LifetimeRibKind::ConcreteAnonConst(cause), f)
+ } else {
+ f(self)
+ }
}
fn with_current_self_type<T>(&mut self, self_type: &Ty, f: impl FnOnce(&mut Self) -> T) -> T {
@@ -2621,7 +2673,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|this: &mut Self, generics: &Generics, kind, item: &'ast AssocItem| {
this.with_generic_param_rib(
&generics.params,
- AssocItemRibKind,
+ RibKind::AssocItem,
LifetimeRibKind::Generics { binder: item.id, span: generics.span, kind },
|this| visit::walk_assoc_item(this, item, AssocCtxt::Trait),
);
@@ -2702,7 +2754,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
}
fn with_self_rib_ns(&mut self, ns: Namespace, self_res: Res, f: impl FnOnce(&mut Self)) {
- let mut self_type_rib = Rib::new(NormalRibKind);
+ let mut self_type_rib = Rib::new(RibKind::Normal);
// Plain insert (no renaming, since types are not currently hygienic)
self_type_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), self_res);
@@ -2728,7 +2780,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// If applicable, create a rib for the type parameters.
self.with_generic_param_rib(
&generics.params,
- ItemRibKind(HasGenericParams::Yes(generics.span)),
+ RibKind::Item(HasGenericParams::Yes(generics.span)),
LifetimeRibKind::Generics {
span: generics.span,
binder: item_id,
@@ -2842,7 +2894,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// We also need a new scope for the impl item type parameters.
self.with_generic_param_rib(
&generics.params,
- AssocItemRibKind,
+ RibKind::AssocItem,
LifetimeRibKind::Generics {
binder: item.id,
span: generics.span,
@@ -2870,7 +2922,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// We also need a new scope for the impl item type parameters.
self.with_generic_param_rib(
&generics.params,
- AssocItemRibKind,
+ RibKind::AssocItem,
LifetimeRibKind::Generics {
binder: item.id,
span: generics.span,
@@ -2916,7 +2968,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// If there is a TraitRef in scope for an impl, then the method must be in the trait.
let Some((module, _)) = &self.current_trait_ref else { return; };
ident.span.normalize_to_macros_2_0_and_adjust(module.expansion);
- let key = self.r.new_key(ident, ns);
+ let key = BindingKey::new(ident, ns);
let mut binding = self.r.resolution(module, key).try_borrow().ok().and_then(|r| r.binding);
debug!(?binding);
if binding.is_none() {
@@ -2927,7 +2979,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
TypeNS => ValueNS,
_ => ns,
};
- let key = self.r.new_key(ident, ns);
+ let key = BindingKey::new(ident, ns);
binding = self.r.resolution(module, key).try_borrow().ok().and_then(|r| r.binding);
debug!(?binding);
}
@@ -3142,7 +3194,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
}
fn resolve_arm(&mut self, arm: &'ast Arm) {
- self.with_rib(ValueNS, NormalRibKind, |this| {
+ self.with_rib(ValueNS, RibKind::Normal, |this| {
this.resolve_pattern_top(&arm.pat, PatternSource::Match);
walk_list!(this, visit_expr, &arm.guard);
this.visit_expr(&arm.body);
@@ -3492,10 +3544,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
//
// Similar thing, for types, happens in `report_errors` above.
let report_errors_for_call = |this: &mut Self, parent_err: Spanned<ResolutionError<'a>>| {
- if !source.is_call() {
- return Some(parent_err);
- }
-
// Before we start looking for candidates, we have to get our hands
// on the type user is trying to perform invocation on; basically:
// we're transforming `HashMap::new` into just `HashMap`.
@@ -3803,7 +3851,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// use std::u8; // bring module u8 in scope
// fn f() -> u8 { // OK, resolves to primitive u8, not to std::u8
// u8::max_value() // OK, resolves to associated function <u8>::max_value,
- // // not to non-existent std::u8::max_value
+ // // not to nonexistent std::u8::max_value
// }
//
// Such behavior is required for backward compatibility.
@@ -3864,7 +3912,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
diagnostics::signal_label_shadowing(self.r.tcx.sess, orig_span, label.ident)
}
- self.with_label_rib(NormalRibKind, |this| {
+ self.with_label_rib(RibKind::Normal, |this| {
let ident = label.ident.normalize_to_macro_rules();
this.label_ribs.last_mut().unwrap().bindings.insert(ident, id);
f(this);
@@ -3887,11 +3935,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
let mut num_macro_definition_ribs = 0;
if let Some(anonymous_module) = anonymous_module {
debug!("(resolving block) found anonymous module, moving down");
- self.ribs[ValueNS].push(Rib::new(ModuleRibKind(anonymous_module)));
- self.ribs[TypeNS].push(Rib::new(ModuleRibKind(anonymous_module)));
+ self.ribs[ValueNS].push(Rib::new(RibKind::Module(anonymous_module)));
+ self.ribs[TypeNS].push(Rib::new(RibKind::Module(anonymous_module)));
self.parent_scope.module = anonymous_module;
} else {
- self.ribs[ValueNS].push(Rib::new(NormalRibKind));
+ self.ribs[ValueNS].push(Rib::new(RibKind::Normal));
}
let prev = self.diagnostic_metadata.current_block_could_be_bare_struct_literal.take();
@@ -3908,8 +3956,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
&& let ItemKind::MacroDef(..) = item.kind {
num_macro_definition_ribs += 1;
let res = self.r.local_def_id(item.id).to_def_id();
- self.ribs[ValueNS].push(Rib::new(MacroDefinition(res)));
- self.label_ribs.push(Rib::new(MacroDefinition(res)));
+ self.ribs[ValueNS].push(Rib::new(RibKind::MacroDefinition(res)));
+ self.label_ribs.push(Rib::new(RibKind::MacroDefinition(res)));
}
self.visit_stmt(stmt);
@@ -3929,24 +3977,54 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
debug!("(resolving block) leaving block");
}
- fn resolve_anon_const(&mut self, constant: &'ast AnonConst, is_repeat: IsRepeatExpr) {
- debug!("resolve_anon_const {:?} is_repeat: {:?}", constant, is_repeat);
- self.with_constant_rib(
- is_repeat,
- if constant.value.is_potential_trivial_const_param() {
- ConstantHasGenerics::Yes
- } else {
- ConstantHasGenerics::No
- },
- None,
- |this| visit::walk_anon_const(this, constant),
+ fn resolve_anon_const(&mut self, constant: &'ast AnonConst, anon_const_kind: AnonConstKind) {
+ debug!(
+ "resolve_anon_const(constant: {:?}, anon_const_kind: {:?})",
+ constant, anon_const_kind
);
+
+ self.resolve_anon_const_manual(
+ constant.value.is_potential_trivial_const_arg(),
+ anon_const_kind,
+ |this| this.resolve_expr(&constant.value, None),
+ )
}
- fn resolve_inline_const(&mut self, constant: &'ast AnonConst) {
- debug!("resolve_anon_const {constant:?}");
- self.with_constant_rib(IsRepeatExpr::No, ConstantHasGenerics::Yes, None, |this| {
- visit::walk_anon_const(this, constant)
+ /// There are a few places that we need to resolve an anon const but we did not parse an
+ /// anon const so cannot provide an `&'ast AnonConst`. Right now this is just unbraced
+ /// const arguments that were parsed as type arguments, and `legact_const_generics` which
+ /// parse as normal function argument expressions. To avoid duplicating the code for resolving
+ /// an anon const we have this function which lets the caller manually call `resolve_expr` or
+ /// `smart_resolve_path`.
+ fn resolve_anon_const_manual(
+ &mut self,
+ is_trivial_const_arg: bool,
+ anon_const_kind: AnonConstKind,
+ resolve_expr: impl FnOnce(&mut Self),
+ ) {
+ let is_repeat_expr = match anon_const_kind {
+ AnonConstKind::ConstArg(is_repeat_expr) => is_repeat_expr,
+ _ => IsRepeatExpr::No,
+ };
+
+ let may_use_generics = match anon_const_kind {
+ AnonConstKind::EnumDiscriminant => {
+ ConstantHasGenerics::No(NoConstantGenericsReason::IsEnumDiscriminant)
+ }
+ AnonConstKind::InlineConst => ConstantHasGenerics::Yes,
+ AnonConstKind::ConstArg(_) => {
+ if self.r.tcx.features().generic_const_exprs || is_trivial_const_arg {
+ ConstantHasGenerics::Yes
+ } else {
+ ConstantHasGenerics::No(NoConstantGenericsReason::NonTrivialConstArg)
+ }
+ }
+ };
+
+ self.with_constant_rib(is_repeat_expr, may_use_generics, None, |this| {
+ this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
+ resolve_expr(this);
+ });
});
}
@@ -3996,7 +4074,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
}
ExprKind::If(ref cond, ref then, ref opt_else) => {
- self.with_rib(ValueNS, NormalRibKind, |this| {
+ self.with_rib(ValueNS, RibKind::Normal, |this| {
let old = this.diagnostic_metadata.in_if_condition.replace(cond);
this.visit_expr(cond);
this.diagnostic_metadata.in_if_condition = old;
@@ -4013,7 +4091,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
ExprKind::While(ref cond, ref block, label) => {
self.with_resolved_label(label, expr.id, |this| {
- this.with_rib(ValueNS, NormalRibKind, |this| {
+ this.with_rib(ValueNS, RibKind::Normal, |this| {
let old = this.diagnostic_metadata.in_if_condition.replace(cond);
this.visit_expr(cond);
this.diagnostic_metadata.in_if_condition = old;
@@ -4024,7 +4102,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
ExprKind::ForLoop(ref pat, ref iter_expr, ref block, label) => {
self.visit_expr(iter_expr);
- self.with_rib(ValueNS, NormalRibKind, |this| {
+ self.with_rib(ValueNS, RibKind::Normal, |this| {
this.resolve_pattern_top(pat, PatternSource::For);
this.resolve_labeled_block(label, expr.id, block);
});
@@ -4051,34 +4129,18 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// Constant arguments need to be treated as AnonConst since
// that is how they will be later lowered to HIR.
if const_args.contains(&idx) {
- self.with_constant_rib(
- IsRepeatExpr::No,
- if argument.is_potential_trivial_const_param() {
- ConstantHasGenerics::Yes
- } else {
- ConstantHasGenerics::No
- },
- None,
- |this| {
- this.resolve_expr(argument, None);
- },
+ self.resolve_anon_const_manual(
+ argument.is_potential_trivial_const_arg(),
+ AnonConstKind::ConstArg(IsRepeatExpr::No),
+ |this| this.resolve_expr(argument, None),
);
} else {
self.resolve_expr(argument, None);
}
}
}
- ExprKind::Type(ref type_expr, ref ty) => {
- // `ParseSess::type_ascription_path_suggestions` keeps spans of colon tokens in
- // type ascription. Here we are trying to retrieve the span of the colon token as
- // well, but only if it's written without spaces `expr:Ty` and therefore confusable
- // with `expr::Ty`, only in this case it will match the span from
- // `type_ascription_path_suggestions`.
- self.diagnostic_metadata
- .current_type_ascription
- .push(type_expr.span.between(ty.span));
+ ExprKind::Type(ref _type_expr, ref _ty) => {
visit::walk_expr(self, expr);
- self.diagnostic_metadata.current_type_ascription.pop();
}
// `async |x| ...` gets desugared to `|x| async {...}`, so we need to
// resolve the arguments within the proper scopes so that usages of them inside the
@@ -4089,8 +4151,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
ref body,
..
}) => {
- self.with_rib(ValueNS, NormalRibKind, |this| {
- this.with_label_rib(ClosureOrAsyncRibKind, |this| {
+ self.with_rib(ValueNS, RibKind::Normal, |this| {
+ this.with_label_rib(RibKind::ClosureOrAsync, |this| {
// Resolve arguments:
this.resolve_params(&fn_decl.inputs);
// No need to resolve return type --
@@ -4114,7 +4176,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
}) => {
self.with_generic_param_rib(
&generic_params,
- NormalRibKind,
+ RibKind::Normal,
LifetimeRibKind::Generics {
binder: expr.id,
kind: LifetimeBinderKind::Closure,
@@ -4125,18 +4187,14 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
}
ExprKind::Closure(..) => visit::walk_expr(self, expr),
ExprKind::Async(..) => {
- self.with_label_rib(ClosureOrAsyncRibKind, |this| visit::walk_expr(this, expr));
+ self.with_label_rib(RibKind::ClosureOrAsync, |this| visit::walk_expr(this, expr));
}
ExprKind::Repeat(ref elem, ref ct) => {
self.visit_expr(elem);
- self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| {
- this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
- this.resolve_anon_const(ct, IsRepeatExpr::Yes)
- })
- });
+ self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::Yes));
}
ExprKind::ConstBlock(ref ct) => {
- self.resolve_inline_const(ct);
+ self.resolve_anon_const(ct, AnonConstKind::InlineConst);
}
ExprKind::Index(ref elem, ref idx) => {
self.resolve_expr(elem, Some(expr));
@@ -4229,12 +4287,12 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
}
}
- fn resolve_and_cache_rustdoc_path(&mut self, path_str: &str, ns: Namespace) -> bool {
+ fn resolve_and_cache_rustdoc_path(&mut self, path_str: &str, ns: Namespace) -> Option<Res> {
// FIXME: This caching may be incorrect in case of multiple `macro_rules`
// items with the same name in the same module.
// Also hygiene is not considered.
let mut doc_link_resolutions = std::mem::take(&mut self.r.doc_link_resolutions);
- let res = doc_link_resolutions
+ let res = *doc_link_resolutions
.entry(self.parent_scope.module.nearest_parent_mod().expect_local())
.or_default()
.entry((Symbol::intern(path_str), ns))
@@ -4249,8 +4307,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
return None;
}
res
- })
- .is_some();
+ });
self.r.doc_link_resolutions = doc_link_resolutions;
res
}
@@ -4285,8 +4342,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
let mut any_resolved = false;
let mut need_assoc = false;
for ns in [TypeNS, ValueNS, MacroNS] {
- if self.resolve_and_cache_rustdoc_path(&path_str, ns) {
- any_resolved = true;
+ if let Some(res) = self.resolve_and_cache_rustdoc_path(&path_str, ns) {
+ // Rustdoc ignores tool attribute resolutions and attempts
+ // to resolve their prefixes for diagnostics.
+ any_resolved = !matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Tool));
} else if ns != MacroNS {
need_assoc = true;
}
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 37fbfad2d..df6582580 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1,7 +1,7 @@
use crate::diagnostics::{ImportSuggestion, LabelSuggestion, TypoSuggestion};
use crate::late::{AliasPossibility, LateResolutionVisitor, RibKind};
use crate::late::{LifetimeBinderKind, LifetimeRes, LifetimeRibKind, LifetimeUseSet};
-use crate::path_names_to_string;
+use crate::{errors, path_names_to_string};
use crate::{Module, ModuleKind, ModuleOrUniformRoot};
use crate::{PathResult, PathSource, Segment};
@@ -22,19 +22,20 @@ use rustc_hir::def::{self, CtorKind, CtorOf, DefKind};
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
use rustc_hir::PrimTy;
use rustc_session::lint;
-use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::edition::Edition;
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{BytePos, Span};
+use rustc_span::Span;
use std::iter;
use std::ops::Deref;
use thin_vec::ThinVec;
+use super::NoConstantGenericsReason;
+
type Res = def::Res<ast::NodeId>;
/// A field or associated item from self type suggested in case of resolution failure.
@@ -91,7 +92,7 @@ fn import_candidate_to_enum_paths(suggestion: &ImportSuggestion) -> (String, Str
/// Description of an elided lifetime.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub(super) struct MissingLifetime {
- /// Used to overwrite the resolution with the suggestion, to avoid cascasing errors.
+ /// Used to overwrite the resolution with the suggestion, to avoid cascading errors.
pub id: NodeId,
/// Where to suggest adding the lifetime.
pub span: Span,
@@ -196,8 +197,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
.sess
.source_map()
.span_to_snippet(span)
- .map(|snippet| snippet.ends_with(')'))
- .unwrap_or(false)
+ .is_ok_and(|snippet| snippet.ends_with(')'))
}
Res::Def(
DefKind::Ctor(..) | DefKind::AssocFn | DefKind::Const | DefKind::AssocConst,
@@ -315,8 +315,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
debug!(?res, ?source);
let base_error = self.make_base_error(path, span, source, res);
let code = source.error_code(res.is_some());
- let mut err =
- self.r.tcx.sess.struct_span_err_with_code(base_error.span, &base_error.msg, code);
+ let mut err = self.r.tcx.sess.struct_span_err_with_code(
+ base_error.span,
+ base_error.msg.clone(),
+ code,
+ );
self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span);
@@ -332,7 +335,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
if self.suggest_pattern_match_with_let(&mut err, source, span) {
// Fallback label.
- err.span_label(base_error.span, &base_error.fallback_label);
+ err.span_label(base_error.span, base_error.fallback_label);
return (err, Vec::new());
}
@@ -350,18 +353,15 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
return (err, candidates);
}
- if !self.type_ascription_suggestion(&mut err, base_error.span) {
- let mut fallback =
- self.suggest_trait_and_bounds(&mut err, source, res, span, &base_error);
+ let mut fallback = self.suggest_trait_and_bounds(&mut err, source, res, span, &base_error);
- // if we have suggested using pattern matching, then don't add needless suggestions
- // for typos.
- fallback |= self.suggest_typo(&mut err, source, path, span, &base_error);
+ // if we have suggested using pattern matching, then don't add needless suggestions
+ // for typos.
+ fallback |= self.suggest_typo(&mut err, source, path, span, &base_error);
- if fallback {
- // Fallback label.
- err.span_label(base_error.span, &base_error.fallback_label);
- }
+ if fallback {
+ // Fallback label.
+ err.span_label(base_error.span, base_error.fallback_label);
}
self.err_code_special_cases(&mut err, source, path, span);
@@ -408,7 +408,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
let Some(path_last_segment) = path.last() else { return };
let item_str = path_last_segment.ident;
- // Emit help message for fake-self from other languages (e.g., `this` in Javascript).
+ // Emit help message for fake-self from other languages (e.g., `this` in JavaScript).
if ["this", "my"].contains(&item_str.as_str()) {
err.span_suggestion_short(
span,
@@ -494,24 +494,6 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
.filter(|(_, enum_ty_path)| !enum_ty_path.starts_with("std::prelude::"))
.collect();
if !enum_candidates.is_empty() {
- if let (PathSource::Type, Some(span)) =
- (source, self.diagnostic_metadata.current_type_ascription.last())
- {
- if self
- .r
- .tcx
- .sess
- .parse_sess
- .type_ascription_path_suggestions
- .borrow()
- .contains(span)
- {
- // Already reported this issue on the lhs of the type ascription.
- err.downgrade_to_delayed_bug();
- return (true, candidates);
- }
- }
-
enum_candidates.sort();
// Contextualize for E0412 "cannot find type", but don't belabor the point
@@ -530,7 +512,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
err.span_suggestions(
span,
- &msg,
+ msg,
enum_candidates.into_iter().map(|(_variant_path, enum_ty_path)| enum_ty_path),
Applicability::MachineApplicable,
);
@@ -577,7 +559,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
| AssocSuggestion::AssocType => {
err.span_suggestion(
span,
- &format!("you might have meant to {}", candidate.action()),
+ format!("you might have meant to {}", candidate.action()),
format!("Self::{path_str}"),
Applicability::MachineApplicable,
);
@@ -598,7 +580,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
err.span_suggestion(
call_span,
- &format!("try calling `{ident}` as a method"),
+ format!("try calling `{ident}` as a method"),
format!("self.{path_str}({args_snippet})"),
Applicability::MachineApplicable,
);
@@ -623,14 +605,14 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
// Try to find in last block rib
- if let Some(rib) = &self.last_block_rib && let RibKind::NormalRibKind = rib.kind {
+ if let Some(rib) = &self.last_block_rib && let RibKind::Normal = rib.kind {
for (ident, &res) in &rib.bindings {
if let Res::Local(_) = res && path.len() == 1 &&
ident.span.eq_ctxt(path[0].ident.span) &&
ident.name == path[0].ident.name {
err.span_help(
ident.span,
- &format!("the binding `{}` is available in a different scope in the same function", path_str),
+ format!("the binding `{}` is available in a different scope in the same function", path_str),
);
return (true, candidates);
}
@@ -739,7 +721,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
if let TypoCandidate::Shadowed(res, Some(sugg_span)) = typo_sugg
&& res
.opt_def_id()
- .map_or(false, |id| id.is_local() || is_in_same_file(span, sugg_span))
+ .is_some_and(|id| id.is_local() || is_in_same_file(span, sugg_span))
{
err.span_label(
sugg_span,
@@ -873,7 +855,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
// The current function has a `self` parameter, but we were unable to resolve
// a reference to `self`. This can only happen if the `self` identifier we
// are resolving came from a different hygiene context.
- if fn_kind.decl().inputs.get(0).map_or(false, |p| p.is_self()) {
+ if fn_kind.decl().inputs.get(0).is_some_and(|p| p.is_self()) {
err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters");
} else {
let doesnt = if is_assoc_fn {
@@ -911,7 +893,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
if let Some(ident) = fn_kind.ident() {
err.span_label(
ident.span,
- &format!("this function {} have a `self` parameter", doesnt),
+ format!("this function {} have a `self` parameter", doesnt),
);
}
}
@@ -1087,7 +1069,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
if ident.span == span {
err.span_suggestion_verbose(
*where_span,
- &format!("constrain the associated type to `{}`", ident),
+ format!("constrain the associated type to `{}`", ident),
format!(
"{}: {}<{} = {}>",
self.r
@@ -1288,7 +1270,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
PathSource::Expr(_) | PathSource::TupleStruct(..) | PathSource::Pat => {
let span = find_span(&source, err);
- err.span_label(self.r.def_span(def_id), &format!("`{path_str}` defined here"));
+ err.span_label(self.r.def_span(def_id), format!("`{path_str}` defined here"));
let (tail, descr, applicability, old_fields) = match source {
PathSource::Pat => ("", "pattern", Applicability::MachineApplicable, None),
@@ -1332,7 +1314,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
};
err.span_suggestion(
span,
- &format!("use struct {} syntax instead", descr),
+ format!("use struct {} syntax instead", descr),
format!("{path_str} {{{pad}{fields}{pad}}}"),
applicability,
);
@@ -1393,26 +1375,6 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
Res::Def(DefKind::Enum, def_id),
PathSource::TupleStruct(..) | PathSource::Expr(..),
) => {
- if self
- .diagnostic_metadata
- .current_type_ascription
- .last()
- .map(|sp| {
- self.r
- .tcx
- .sess
- .parse_sess
- .type_ascription_path_suggestions
- .borrow()
- .contains(&sp)
- })
- .unwrap_or(false)
- {
- err.downgrade_to_delayed_bug();
- // We already suggested changing `:` into `::` during parsing.
- return false;
- }
-
self.suggest_using_enum_variant(err, source, def_id, span);
}
(Res::Def(DefKind::Struct, def_id), source) if ns == ValueNS => {
@@ -1494,7 +1456,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
if non_visible_spans.len() > 0 {
if let Some(fields) = self.r.field_visibility_spans.get(&def_id) {
err.multipart_suggestion_verbose(
- &format!(
+ format!(
"consider making the field{} publicly accessible",
pluralize!(fields.len())
),
@@ -1524,7 +1486,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
let span = find_span(&source, err);
err.span_label(
self.r.def_span(def_id),
- &format!("`{path_str}` defined here"),
+ format!("`{path_str}` defined here"),
);
err.span_suggestion(
span,
@@ -1538,7 +1500,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
(Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_def_id), _) if ns == ValueNS => {
let def_id = self.r.tcx.parent(ctor_def_id);
- err.span_label(self.r.def_span(def_id), &format!("`{path_str}` defined here"));
+ err.span_label(self.r.def_span(def_id), format!("`{path_str}` defined here"));
let fields = self.r.field_def_ids(def_id).map_or_else(
|| "/* fields */".to_string(),
|field_ids| vec!["_"; field_ids.len()].join(", "),
@@ -1669,7 +1631,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
.tcx
.fn_arg_names(def_id)
.first()
- .map_or(false, |ident| ident.name == kw::SelfLower),
+ .is_some_and(|ident| ident.name == kw::SelfLower),
};
if has_self {
return Some(AssocSuggestion::MethodWithSelf { called });
@@ -1728,7 +1690,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
// Items in scope
- if let RibKind::ModuleRibKind(module) = rib.kind {
+ if let RibKind::Module(module) = rib.kind {
// Items from this module
self.r.add_module_candidates(module, &mut names, &filter_fn, Some(ctxt));
@@ -1817,80 +1779,6 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
})
}
- /// Only used in a specific case of type ascription suggestions
- fn get_colon_suggestion_span(&self, start: Span) -> Span {
- let sm = self.r.tcx.sess.source_map();
- start.to(sm.next_point(start))
- }
-
- fn type_ascription_suggestion(&self, err: &mut Diagnostic, base_span: Span) -> bool {
- let sm = self.r.tcx.sess.source_map();
- let base_snippet = sm.span_to_snippet(base_span);
- if let Some(&sp) = self.diagnostic_metadata.current_type_ascription.last() {
- if let Ok(snippet) = sm.span_to_snippet(sp) {
- let len = snippet.trim_end().len() as u32;
- if snippet.trim() == ":" {
- let colon_sp =
- sp.with_lo(sp.lo() + BytePos(len - 1)).with_hi(sp.lo() + BytePos(len));
- let mut show_label = true;
- if sm.is_multiline(sp) {
- err.span_suggestion_short(
- colon_sp,
- "maybe you meant to write `;` here",
- ";",
- Applicability::MaybeIncorrect,
- );
- } else {
- let after_colon_sp =
- self.get_colon_suggestion_span(colon_sp.shrink_to_hi());
- if snippet.len() == 1 {
- // `foo:bar`
- err.span_suggestion(
- colon_sp,
- "maybe you meant to write a path separator here",
- "::",
- Applicability::MaybeIncorrect,
- );
- show_label = false;
- if !self
- .r
- .tcx
- .sess
- .parse_sess
- .type_ascription_path_suggestions
- .borrow_mut()
- .insert(colon_sp)
- {
- err.downgrade_to_delayed_bug();
- }
- }
- if let Ok(base_snippet) = base_snippet {
- // Try to find an assignment
- let eq_span = sm.span_look_ahead(after_colon_sp, Some("="), Some(50));
- if let Ok(ref snippet) = sm.span_to_snippet(eq_span) && snippet == "=" {
- err.span_suggestion(
- base_span,
- "maybe you meant to write an assignment here",
- format!("let {}", base_snippet),
- Applicability::MaybeIncorrect,
- );
- show_label = false;
- }
- }
- }
- if show_label {
- err.span_label(
- base_span,
- "expecting a type here because of type ascription",
- );
- }
- return show_label;
- }
- }
- }
- false
- }
-
// try to give a suggestion for this pattern: `name = blah`, which is common in other languages
// suggest `let name = blah` to introduce a new binding
fn let_binding_suggestion(&mut self, err: &mut Diagnostic, ident_span: Span) -> bool {
@@ -2014,7 +1902,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
err.span_suggestions(
span,
- &msg,
+ msg,
suggestable_variants,
Applicability::MaybeIncorrect,
);
@@ -2022,17 +1910,17 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
// If the enum has no tuple variants..
if non_suggestable_variant_count == variants.len() {
- err.help(&format!("the enum has no tuple variants {}", source_msg));
+ err.help(format!("the enum has no tuple variants {}", source_msg));
}
// If there are also non-tuple variants..
if non_suggestable_variant_count == 1 {
- err.help(&format!(
+ err.help(format!(
"you might have meant {} the enum's non-tuple variant",
source_msg
));
} else if non_suggestable_variant_count >= 1 {
- err.help(&format!(
+ err.help(format!(
"you might have meant {} one of the enum's non-tuple variants",
source_msg
));
@@ -2042,10 +1930,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
let def_id = self.r.tcx.parent(ctor_def_id);
match kind {
CtorKind::Const => false,
- CtorKind::Fn => !self
- .r
- .field_def_ids(def_id)
- .map_or(false, |field_ids| field_ids.is_empty()),
+ CtorKind::Fn => {
+ !self.r.field_def_ids(def_id).is_some_and(|field_ids| field_ids.is_empty())
+ }
}
};
@@ -2282,7 +2169,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
lint::builtin::SINGLE_USE_LIFETIMES,
param.id,
param.ident.span,
- &format!("lifetime parameter `{}` only used once", param.ident),
+ format!("lifetime parameter `{}` only used once", param.ident),
lint::BuiltinLintDiagnostics::SingleUseLifetime {
param_span: param.ident.span,
use_span: Some((use_span, elidable)),
@@ -2301,7 +2188,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
lint::builtin::UNUSED_LIFETIMES,
param.id,
param.ident.span,
- &format!("lifetime parameter `{}` never used", param.ident),
+ format!("lifetime parameter `{}` never used", param.ident),
lint::BuiltinLintDiagnostics::SingleUseLifetime {
param_span: param.ident.span,
use_span: None,
@@ -2367,7 +2254,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
suggest_note = false; // Avoid displaying the same help multiple times.
err.span_label(
span,
- &format!(
+ format!(
"lifetime `{}` is missing in item created through this procedural macro",
name,
),
@@ -2428,37 +2315,56 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
}
- pub(crate) fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &ast::Lifetime) {
- struct_span_err!(
- self.r.tcx.sess,
- lifetime_ref.ident.span,
- E0771,
- "use of non-static lifetime `{}` in const generic",
- lifetime_ref.ident
- )
- .note(
- "for more information, see issue #74052 \
- <https://github.com/rust-lang/rust/issues/74052>",
- )
- .emit();
+ pub(crate) fn emit_non_static_lt_in_const_param_ty_error(&self, lifetime_ref: &ast::Lifetime) {
+ self.r
+ .tcx
+ .sess
+ .create_err(errors::ParamInTyOfConstParam {
+ span: lifetime_ref.ident.span,
+ name: lifetime_ref.ident.name,
+ param_kind: Some(errors::ParamKindInTyOfConstParam::Lifetime),
+ })
+ .emit();
}
/// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
/// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by
/// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
- pub(crate) fn maybe_emit_forbidden_non_static_lifetime_error(
+ pub(crate) fn emit_forbidden_non_static_lifetime_error(
&self,
+ cause: NoConstantGenericsReason,
lifetime_ref: &ast::Lifetime,
) {
- let feature_active = self.r.tcx.sess.features_untracked().generic_const_exprs;
- if !feature_active {
- feature_err(
- &self.r.tcx.sess.parse_sess,
- sym::generic_const_exprs,
- lifetime_ref.ident.span,
- "a non-static lifetime is not allowed in a `const`",
- )
- .emit();
+ match cause {
+ NoConstantGenericsReason::IsEnumDiscriminant => {
+ self.r
+ .tcx
+ .sess
+ .create_err(errors::ParamInEnumDiscriminant {
+ span: lifetime_ref.ident.span,
+ name: lifetime_ref.ident.name,
+ param_kind: errors::ParamKindInEnumDiscriminant::Lifetime,
+ })
+ .emit();
+ }
+ NoConstantGenericsReason::NonTrivialConstArg => {
+ assert!(!self.r.tcx.features().generic_const_exprs);
+ self.r
+ .tcx
+ .sess
+ .create_err(errors::ParamInNonTrivialAnonConst {
+ span: lifetime_ref.ident.span,
+ name: lifetime_ref.ident.name,
+ param_kind: errors::ParamKindInNonTrivialAnonConst::Lifetime,
+ help: self
+ .r
+ .tcx
+ .sess
+ .is_nightly_build()
+ .then_some(errors::ParamInNonTrivialAnonConstHelp),
+ })
+ .emit();
+ }
}
}
@@ -2573,13 +2479,13 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
)];
}
} else if num_params == 1 {
- err.help(&format!(
+ err.help(format!(
"this function's return type contains a borrowed value, \
but the signature does not say which {} it is borrowed from",
m
));
} else {
- err.help(&format!(
+ err.help(format!(
"this function's return type contains a borrowed value, \
but the signature does not say whether it is borrowed from {}",
m
@@ -2648,7 +2554,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
1 => {
err.multipart_suggestion_verbose(
- &format!("consider using the `{}` lifetime", existing_name),
+ format!("consider using the `{}` lifetime", existing_name),
spans_suggs,
Applicability::MaybeIncorrect,
);
@@ -2699,7 +2605,7 @@ pub(super) fn signal_label_shadowing(sess: &Session, orig: Span, shadower: Ident
let shadower = shadower.span;
let mut err = sess.struct_span_warn(
shadower,
- &format!("label name `{}` shadows a label name that is already in scope", name),
+ format!("label name `{}` shadows a label name that is already in scope", name),
);
err.span_label(orig, "first declared here");
err.span_label(shadower, format!("label `{}` already in scope", name));
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index b820d56b8..3d2bd8429 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -21,6 +21,9 @@
#[macro_use]
extern crate tracing;
+use errors::{
+ ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst, ParamKindInTyOfConstParam,
+};
use rustc_arena::{DroplessArena, TypedArena};
use rustc_ast::node_id::NodeMap;
use rustc_ast::{self as ast, attr, NodeId, CRATE_NODE_ID};
@@ -33,17 +36,18 @@ use rustc_errors::{
Applicability, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, SubdiagnosticMessage,
};
use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind};
+use rustc_fluent_macro::fluent_messages;
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, PartialRes, PerNS};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, LocalDefIdSet};
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::definitions::DefPathData;
use rustc_hir::TraitCandidate;
-use rustc_index::vec::IndexVec;
-use rustc_macros::fluent_messages;
+use rustc_index::IndexVec;
use rustc_metadata::creader::{CStore, CrateLoader};
use rustc_middle::metadata::ModChild;
use rustc_middle::middle::privacy::EffectiveVisibilities;
+use rustc_middle::query::Providers;
use rustc_middle::span_bug;
use rustc_middle::ty::{self, MainDefinition, RegisteredTools, TyCtxt};
use rustc_middle::ty::{ResolverGlobalCtxt, ResolverOutputs};
@@ -81,6 +85,7 @@ pub mod rustdoc;
fluent_messages! { "../messages.ftl" }
+#[derive(Debug)]
enum Weak {
Yes,
No,
@@ -101,7 +106,7 @@ impl Determinacy {
/// A specific scope in which a name can be looked up.
/// This enum is currently used only for early resolution (imports and macros),
/// but not for late resolution yet.
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
enum Scope<'a> {
DeriveHelpers(LocalExpnId),
DeriveHelpersCompat,
@@ -223,11 +228,15 @@ enum ResolutionError<'a> {
/// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
ForwardDeclaredGenericParam,
/// ERROR E0770: the type of const parameters must not depend on other generic parameters.
- ParamInTyOfConstParam(Symbol),
+ ParamInTyOfConstParam { name: Symbol, param_kind: Option<ParamKindInTyOfConstParam> },
/// generic parameters must not be used inside const evaluations.
///
/// This error is only emitted when using `min_const_generics`.
- ParamInNonTrivialAnonConst { name: Symbol, is_type: bool },
+ ParamInNonTrivialAnonConst { name: Symbol, param_kind: ParamKindInNonTrivialAnonConst },
+ /// generic parameters must not be used inside enum discriminants.
+ ///
+ /// This error is emitted even with `generic_const_exprs`.
+ ParamInEnumDiscriminant { name: Symbol, param_kind: ParamKindInEnumDiscriminant },
/// Error E0735: generic parameters with a default cannot use `Self`
SelfInGenericParamDefault,
/// Error E0767: use of unreachable label
@@ -244,6 +253,8 @@ enum ResolutionError<'a> {
TraitImplDuplicate { name: Symbol, trait_item_span: Span, old_span: Span },
/// Inline asm `sym` operand must refer to a `fn` or `static`.
InvalidAsmSym,
+ /// `self` used instead of `Self` in a generic parameter
+ LowercaseSelf,
}
enum VisResolutionError<'a> {
@@ -459,6 +470,13 @@ struct BindingKey {
disambiguator: u32,
}
+impl BindingKey {
+ fn new(ident: Ident, ns: Namespace) -> Self {
+ let ident = ident.normalize_to_macros_2_0();
+ BindingKey { ident, ns, disambiguator: 0 }
+ }
+}
+
type Resolutions<'a> = RefCell<FxIndexMap<BindingKey, &'a RefCell<NameResolution<'a>>>>;
/// One node in the tree of modules.
@@ -909,8 +927,7 @@ pub struct Resolver<'a, 'tcx> {
/// `CrateNum` resolutions of `extern crate` items.
extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
- module_children_non_reexports: LocalDefIdMap<Vec<LocalDefId>>,
- module_children_reexports: LocalDefIdMap<Vec<ModChild>>,
+ module_children: LocalDefIdMap<Vec<ModChild>>,
trait_map: NodeMap<Vec<TraitCandidate>>,
/// A map from nodes to anonymous modules.
@@ -934,6 +951,7 @@ pub struct Resolver<'a, 'tcx> {
empty_module: Module<'a>,
module_map: FxHashMap<DefId, Module<'a>>,
binding_parent_modules: FxHashMap<Interned<'a, NameBinding<'a>>, Module<'a>>,
+
underscore_disambiguator: u32,
/// Maps glob imports to the names of items actually imported.
@@ -1260,8 +1278,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
lifetimes_res_map: Default::default(),
extra_lifetime_params_map: Default::default(),
extern_crate_map: Default::default(),
- module_children_non_reexports: Default::default(),
- module_children_reexports: Default::default(),
+ module_children: Default::default(),
trait_map: NodeMap::default(),
underscore_disambiguator: 0,
empty_module,
@@ -1399,8 +1416,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
has_pub_restricted,
effective_visibilities,
extern_crate_map,
- module_children_non_reexports: self.module_children_non_reexports,
- module_children_reexports: self.module_children_reexports,
+ module_children: self.module_children,
glob_map,
maybe_unused_trait_imports,
main_def,
@@ -1461,7 +1477,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
fn is_builtin_macro(&mut self, res: Res) -> bool {
- self.get_macro(res).map_or(false, |macro_data| macro_data.ext.builtin_name.is_some())
+ self.get_macro(res).is_some_and(|macro_data| macro_data.ext.builtin_name.is_some())
}
fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
@@ -1588,7 +1604,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
import_ids
}
- fn new_key(&mut self, ident: Ident, ns: Namespace) -> BindingKey {
+ fn new_disambiguated_key(&mut self, ident: Ident, ns: Namespace) -> BindingKey {
let ident = ident.normalize_to_macros_2_0();
let disambiguator = if ident.name == kw::Underscore {
self.underscore_disambiguator += 1;
@@ -2020,6 +2036,6 @@ impl Finalize {
}
}
-pub fn provide(providers: &mut ty::query::Providers) {
+pub fn provide(providers: &mut Providers) {
providers.registered_tools = macros::registered_tools;
}
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 22b014c06..df5c16a93 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -1,7 +1,7 @@
//! A bunch of methods and structures more or less related to resolving macros and
//! interface provided by `Resolver` to macro expander.
-use crate::errors::{AddAsNonDerive, MacroExpectedFound, RemoveSurroundingDerive};
+use crate::errors::{self, AddAsNonDerive, MacroExpectedFound, RemoveSurroundingDerive};
use crate::Namespace::*;
use crate::{BuiltinMacroState, Determinacy};
use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet};
@@ -121,7 +121,7 @@ pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools {
if let Some(old_ident) = registered_tools.replace(ident) {
let msg = format!("{} `{}` was already registered", "tool", ident);
tcx.sess
- .struct_span_err(ident.span, &msg)
+ .struct_span_err(ident.span, msg)
.span_label(old_ident.span, "already registered here")
.emit();
}
@@ -130,7 +130,7 @@ pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools {
let msg = format!("`{}` only accepts identifiers", sym::register_tool);
let span = nested_meta.span();
tcx.sess
- .struct_span_err(span, &msg)
+ .struct_span_err(span, msg)
.span_label(span, "not an identifier")
.emit();
}
@@ -202,7 +202,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
self.tcx
.sess
.diagnostic()
- .bug(&format!("built-in macro `{}` was already registered", name));
+ .bug(format!("built-in macro `{}` was already registered", name));
}
}
@@ -315,7 +315,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
UNUSED_MACROS,
node_id,
ident.span,
- &format!("unused macro definition: `{}`", ident.name),
+ format!("unused macro definition: `{}`", ident.name),
);
}
for (&(def_id, arm_i), &(ident, rule_span)) in self.unused_macro_rules.iter() {
@@ -328,7 +328,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
UNUSED_MACRO_RULES,
node_id,
rule_span,
- &format!(
+ format!(
"{} rule of macro `{}` is never used",
crate::diagnostics::ordinalize(arm_i + 1),
ident.name
@@ -436,9 +436,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
// HACK(Urgau): This shouldn't be necessary
PathResult::Failed { is_error_from_last_segment: false, .. } => {
self.tcx.sess
- .struct_span_err(span, "not sure whether the path is accessible or not")
- .note("the type may have associated items, but we are currently not checking them")
- .emit();
+ .emit_err(errors::CfgAccessibleUnsure { span });
// If we get a partially resolved NonModule in one namespace, we should get the
// same result in any other namespaces, so we can return early.
@@ -513,10 +511,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if let Some(def_id) = def_id.as_local() {
self.unused_macros.remove(&def_id);
if self.proc_macro_stubs.contains(&def_id) {
- self.tcx.sess.span_err(
- path.span,
- "can't use a procedural macro from the same crate that defines it",
- );
+ self.tcx.sess.emit_err(errors::ProcMacroSameCrate {
+ span: path.span,
+ is_test: self.tcx.sess.is_test_crate(),
+ });
}
}
}
@@ -700,7 +698,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
Segment::names_to_string(path)
);
let msg_note = "import resolution is stuck, try simplifying macro imports";
- this.tcx.sess.struct_span_err(span, &msg).note(msg_note).emit();
+ this.tcx.sess.struct_span_err(span, msg).note(msg_note).emit();
}
}
};
@@ -790,7 +788,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
Err(..) => {
let expected = kind.descr_expected();
let msg = format!("cannot find {} `{}` in this scope", expected, ident);
- let mut err = self.tcx.sess.struct_span_err(ident.span, &msg);
+ let mut err = self.tcx.sess.struct_span_err(ident.span, msg);
self.unresolved_macro_suggestions(&mut err, kind, &parent_scope, ident);
err.emit();
}
@@ -825,8 +823,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let is_allowed = |feature| {
self.active_features.contains(&feature) || span.allows_unstable(feature)
};
- let allowed_by_implication =
- implied_by.map(|feature| is_allowed(feature)).unwrap_or(false);
+ let allowed_by_implication = implied_by.is_some_and(|feature| is_allowed(feature));
if !is_allowed(feature) && !allowed_by_implication {
let lint_buffer = &mut self.lint_buffer;
let soft_handler =
@@ -868,9 +865,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if kind != NonMacroAttrKind::Tool && binding.map_or(true, |b| b.is_import()) {
let msg =
format!("cannot use {} {} through an import", kind.article(), kind.descr());
- let mut err = self.tcx.sess.struct_span_err(span, &msg);
+ let mut err = self.tcx.sess.struct_span_err(span, msg);
if let Some(binding) = binding {
- err.span_note(binding.span, &format!("the {} imported here", kind.descr()));
+ err.span_note(binding.span, format!("the {} imported here", kind.descr()));
}
err.emit();
}
@@ -885,7 +882,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if macro_kind.is_some() && sub_namespace_match(macro_kind, Some(MacroKind::Attr)) {
self.tcx.sess.span_err(
ident.span,
- &format!("name `{}` is reserved in attribute namespace", ident),
+ format!("name `{}` is reserved in attribute namespace", ident),
);
}
}
@@ -929,7 +926,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
} else {
let msg = format!("cannot find a built-in macro with name `{}`", item.ident);
- self.tcx.sess.span_err(item.span, &msg);
+ self.tcx.sess.span_err(item.span, msg);
}
}
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs
index 9eae99be2..d433391f2 100644
--- a/compiler/rustc_resolve/src/rustdoc.rs
+++ b/compiler/rustc_resolve/src/rustdoc.rs
@@ -367,6 +367,7 @@ fn preprocess_link(link: &str) -> Box<str> {
let link = link.strip_suffix("{}").unwrap_or(link);
let link = link.strip_suffix("[]").unwrap_or(link);
let link = if link != "!" { link.strip_suffix('!').unwrap_or(link) } else { link };
+ let link = link.trim();
strip_generics_from_path(link).unwrap_or_else(|_| link.into())
}