Disallow shadowing const parameters

This commit is contained in:
Fabian Wolff 2021-05-19 18:51:42 +02:00
parent 3e827cc21e
commit f749d88ae7
7 changed files with 124 additions and 15 deletions

View file

@ -425,24 +425,29 @@ impl<'a> Resolver<'a> {
}
err
}
ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => {
let res = binding.res();
let shadows_what = res.descr();
ResolutionError::BindingShadowsSomethingUnacceptable {
shadowing_binding_descr,
name,
participle,
article,
shadowed_binding_descr,
shadowed_binding_span,
} => {
let mut err = struct_span_err!(
self.session,
span,
E0530,
"{}s cannot shadow {}s",
what_binding,
shadows_what
shadowing_binding_descr,
shadowed_binding_descr,
);
err.span_label(
span,
format!("cannot be named the same as {} {}", res.article(), shadows_what),
format!("cannot be named the same as {} {}", article, shadowed_binding_descr),
);
let participle = if binding.is_import() { "imported" } else { "defined" };
let msg = format!("the {} `{}` is {} here", shadows_what, name, participle);
err.span_label(binding.span, msg);
let msg =
format!("the {} `{}` is {} here", shadowed_binding_descr, name, participle);
err.span_label(shadowed_binding_span, msg);
err
}
ResolutionError::ForwardDeclaredTyParam => {

View file

@ -1763,13 +1763,33 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
// to something unusable as a pattern (e.g., constructor function),
// but we still conservatively report an error, see
// issues/33118#issuecomment-233962221 for one reason why.
let binding = binding.expect("no binding for a ctor or static");
self.report_error(
ident.span,
ResolutionError::BindingShadowsSomethingUnacceptable(
pat_src.descr(),
ident.name,
binding.expect("no binding for a ctor or static"),
),
ResolutionError::BindingShadowsSomethingUnacceptable {
shadowing_binding_descr: pat_src.descr(),
name: ident.name,
participle: if binding.is_import() { "imported" } else { "defined" },
article: binding.res().article(),
shadowed_binding_descr: binding.res().descr(),
shadowed_binding_span: binding.span,
},
);
None
}
Res::Def(DefKind::ConstParam, def_id) => {
// Same as for DefKind::Const above, but here, `binding` is `None`, so we
// have to construct the error differently
self.report_error(
ident.span,
ResolutionError::BindingShadowsSomethingUnacceptable {
shadowing_binding_descr: pat_src.descr(),
name: ident.name,
participle: "defined",
article: res.article(),
shadowed_binding_descr: res.descr(),
shadowed_binding_span: self.r.opt_span(def_id).expect("const parameter defined outside of local crate"),
}
);
None
}

View file

@ -234,7 +234,14 @@ enum ResolutionError<'a> {
/* current */ &'static str,
),
/// Error E0530: `X` bindings cannot shadow `Y`s.
BindingShadowsSomethingUnacceptable(&'static str, Symbol, &'a NameBinding<'a>),
BindingShadowsSomethingUnacceptable {
shadowing_binding_descr: &'static str,
name: Symbol,
participle: &'static str,
article: &'static str,
shadowed_binding_descr: &'static str,
shadowed_binding_span: Span,
},
/// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
ForwardDeclaredTyParam, // FIXME(const_generics_defaults)
/// ERROR E0770: the type of const parameters must not depend on other generic parameters.