Add pointing const identifier when emitting E0435
This commit is contained in:
parent
68ec332611
commit
f03907b33f
@ -398,13 +398,19 @@ impl<'a> Resolver<'a> {
|
||||
err.help("use the `|| { ... }` closure form instead");
|
||||
err
|
||||
}
|
||||
ResolutionError::AttemptToUseNonConstantValueInConstant => {
|
||||
ResolutionError::AttemptToUseNonConstantValueInConstant(ident, sugg) => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0435,
|
||||
"attempt to use a non-constant value in a constant"
|
||||
);
|
||||
err.span_suggestion(
|
||||
ident.span,
|
||||
&sugg,
|
||||
"".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.span_label(span, "non-constant value");
|
||||
err
|
||||
}
|
||||
|
@ -92,6 +92,12 @@ enum PatBoundCtx {
|
||||
No,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
crate enum ConstantItemKind {
|
||||
Const,
|
||||
Static,
|
||||
}
|
||||
|
||||
/// The rib kind restricts certain accesses,
|
||||
/// e.g. to a `Res::Local` of an outer item.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@ -119,7 +125,7 @@ enum PatBoundCtx {
|
||||
///
|
||||
/// The `bool` indicates if this constant may reference generic parameters
|
||||
/// and is used to only allow generic parameters to be used in trivial constant expressions.
|
||||
ConstantItemRibKind(bool),
|
||||
ConstantItemRibKind(bool, Option<(Ident, ConstantItemKind)>),
|
||||
|
||||
/// We passed through a module.
|
||||
ModuleRibKind(Module<'a>),
|
||||
@ -145,7 +151,7 @@ impl RibKind<'_> {
|
||||
NormalRibKind
|
||||
| ClosureOrAsyncRibKind
|
||||
| FnItemRibKind
|
||||
| ConstantItemRibKind(_)
|
||||
| ConstantItemRibKind(..)
|
||||
| ModuleRibKind(_)
|
||||
| MacroDefinition(_)
|
||||
| ConstParamTyRibKind => false,
|
||||
@ -634,7 +640,7 @@ fn visit_generic_arg(&mut self, arg: &'ast GenericArg) {
|
||||
// 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, true, |this| {
|
||||
self.with_constant_rib(IsRepeatExpr::No, true, None, |this| {
|
||||
this.smart_resolve_path(
|
||||
ty.id,
|
||||
qself.as_ref(),
|
||||
@ -843,7 +849,7 @@ fn is_label_valid_from_rib(&self, rib_index: usize) -> bool {
|
||||
| ClosureOrAsyncRibKind
|
||||
| FnItemRibKind
|
||||
| ItemRibKind(..)
|
||||
| ConstantItemRibKind(_)
|
||||
| ConstantItemRibKind(..)
|
||||
| ModuleRibKind(..)
|
||||
| ForwardTyParamBanRibKind
|
||||
| ConstParamTyRibKind => {
|
||||
@ -970,6 +976,7 @@ fn resolve_item(&mut self, item: &'ast Item) {
|
||||
this.with_constant_rib(
|
||||
IsRepeatExpr::No,
|
||||
true,
|
||||
None,
|
||||
|this| this.visit_expr(expr),
|
||||
);
|
||||
}
|
||||
@ -1012,11 +1019,19 @@ fn resolve_item(&mut self, item: &'ast Item) {
|
||||
self.with_item_rib(HasGenericParams::No, |this| {
|
||||
this.visit_ty(ty);
|
||||
if let Some(expr) = expr {
|
||||
let constant_item_kind = match item.kind {
|
||||
ItemKind::Const(..) => ConstantItemKind::Const,
|
||||
ItemKind::Static(..) => ConstantItemKind::Static,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
// We already forbid generic params because of the above item rib,
|
||||
// so it doesn't matter whether this is a trivial constant.
|
||||
this.with_constant_rib(IsRepeatExpr::No, true, |this| {
|
||||
this.visit_expr(expr)
|
||||
});
|
||||
this.with_constant_rib(
|
||||
IsRepeatExpr::No,
|
||||
true,
|
||||
Some((item.ident, constant_item_kind)),
|
||||
|this| this.visit_expr(expr),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1118,15 +1133,16 @@ fn with_constant_rib(
|
||||
&mut self,
|
||||
is_repeat: IsRepeatExpr,
|
||||
is_trivial: bool,
|
||||
item: Option<(Ident, ConstantItemKind)>,
|
||||
f: impl FnOnce(&mut Self),
|
||||
) {
|
||||
debug!("with_constant_rib: is_repeat={:?} is_trivial={}", is_repeat, is_trivial);
|
||||
self.with_rib(ValueNS, ConstantItemRibKind(is_trivial), |this| {
|
||||
self.with_rib(ValueNS, ConstantItemRibKind(is_trivial, item), |this| {
|
||||
this.with_rib(
|
||||
TypeNS,
|
||||
ConstantItemRibKind(is_repeat == IsRepeatExpr::Yes || is_trivial),
|
||||
ConstantItemRibKind(is_repeat == IsRepeatExpr::Yes || is_trivial, item),
|
||||
|this| {
|
||||
this.with_label_rib(ConstantItemRibKind(is_trivial), f);
|
||||
this.with_label_rib(ConstantItemRibKind(is_trivial, item), f);
|
||||
},
|
||||
)
|
||||
});
|
||||
@ -1266,6 +1282,7 @@ fn resolve_implementation(
|
||||
this.with_constant_rib(
|
||||
IsRepeatExpr::No,
|
||||
true,
|
||||
None,
|
||||
|this| {
|
||||
visit::walk_assoc_item(
|
||||
this,
|
||||
@ -2200,6 +2217,7 @@ fn resolve_anon_const(&mut self, constant: &'ast AnonConst, is_repeat: IsRepeatE
|
||||
self.with_constant_rib(
|
||||
is_repeat,
|
||||
constant.value.is_potential_trivial_const_param(),
|
||||
None,
|
||||
|this| {
|
||||
visit::walk_anon_const(this, constant);
|
||||
},
|
||||
|
@ -64,7 +64,7 @@
|
||||
use diagnostics::{extend_span_to_previous_binding, find_span_of_binding_until_next_binding};
|
||||
use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
|
||||
use imports::{Import, ImportKind, ImportResolver, NameResolution};
|
||||
use late::{HasGenericParams, PathSource, Rib, RibKind::*};
|
||||
use late::{ConstantItemKind, HasGenericParams, PathSource, Rib, RibKind::*};
|
||||
use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
|
||||
|
||||
type Res = def::Res<NodeId>;
|
||||
@ -210,7 +210,7 @@ enum ResolutionError<'a> {
|
||||
/// Error E0434: can't capture dynamic environment in a fn item.
|
||||
CannotCaptureDynamicEnvironmentInFnItem,
|
||||
/// Error E0435: attempt to use a non-constant value in a constant.
|
||||
AttemptToUseNonConstantValueInConstant,
|
||||
AttemptToUseNonConstantValueInConstant(Ident, String),
|
||||
/// Error E0530: `X` bindings cannot shadow `Y`s.
|
||||
BindingShadowsSomethingUnacceptable(&'static str, Symbol, &'a NameBinding<'a>),
|
||||
/// Error E0128: type parameters with a default cannot use forward-declared identifiers.
|
||||
@ -1821,14 +1821,16 @@ fn resolve_ident_in_lexical_scope(
|
||||
// Use the rib kind to determine whether we are resolving parameters
|
||||
// (macro 2.0 hygiene) or local variables (`macro_rules` hygiene).
|
||||
let rib_ident = if ribs[i].kind.contains_params() { normalized_ident } else { ident };
|
||||
if let Some(res) = ribs[i].bindings.get(&rib_ident).cloned() {
|
||||
if let Some((original_rib_ident_def, res)) = ribs[i].bindings.get_key_value(&rib_ident)
|
||||
{
|
||||
// The ident resolves to a type parameter or local variable.
|
||||
return Some(LexicalScopeBinding::Res(self.validate_res_from_ribs(
|
||||
i,
|
||||
rib_ident,
|
||||
res,
|
||||
*res,
|
||||
record_used,
|
||||
path_span,
|
||||
*original_rib_ident_def,
|
||||
ribs,
|
||||
)));
|
||||
}
|
||||
@ -2540,6 +2542,7 @@ fn validate_res_from_ribs(
|
||||
mut res: Res,
|
||||
record_used: bool,
|
||||
span: Span,
|
||||
original_rib_ident_def: Ident,
|
||||
all_ribs: &[Rib<'a>],
|
||||
) -> Res {
|
||||
const CG_BUG_STR: &str = "min_const_generics resolve check didn't stop compilation";
|
||||
@ -2586,10 +2589,31 @@ fn validate_res_from_ribs(
|
||||
res_err = Some(CannotCaptureDynamicEnvironmentInFnItem);
|
||||
}
|
||||
}
|
||||
ConstantItemRibKind(_) => {
|
||||
ConstantItemRibKind(_, item) => {
|
||||
// Still doesn't deal with upvars
|
||||
if record_used {
|
||||
self.report_error(span, AttemptToUseNonConstantValueInConstant);
|
||||
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",
|
||||
};
|
||||
let sugg = format!(
|
||||
"consider using `let` instead of `{}`",
|
||||
kind_str
|
||||
);
|
||||
(span, AttemptToUseNonConstantValueInConstant(ident, sugg))
|
||||
} else {
|
||||
let sugg = "consider using `const` instead of `let`";
|
||||
(
|
||||
rib_ident.span,
|
||||
AttemptToUseNonConstantValueInConstant(
|
||||
original_rib_ident_def,
|
||||
sugg.to_string(),
|
||||
),
|
||||
)
|
||||
};
|
||||
self.report_error(span, resolution_error);
|
||||
}
|
||||
return Res::Err;
|
||||
}
|
||||
@ -2625,7 +2649,7 @@ fn validate_res_from_ribs(
|
||||
in_ty_param_default = true;
|
||||
continue;
|
||||
}
|
||||
ConstantItemRibKind(trivial) => {
|
||||
ConstantItemRibKind(trivial, _) => {
|
||||
let features = self.session.features_untracked();
|
||||
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
|
||||
if !(trivial
|
||||
@ -2718,7 +2742,7 @@ fn validate_res_from_ribs(
|
||||
in_ty_param_default = true;
|
||||
continue;
|
||||
}
|
||||
ConstantItemRibKind(trivial) => {
|
||||
ConstantItemRibKind(trivial, _) => {
|
||||
let features = self.session.features_untracked();
|
||||
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
|
||||
if !(trivial
|
||||
|
Loading…
Reference in New Issue
Block a user