Prevent const parameters having type parameters as types
This commit is contained in:
parent
bd31c392f2
commit
976b3d1d9e
@ -1642,6 +1642,16 @@ fn main() {
|
||||
```
|
||||
"##,
|
||||
|
||||
E0671: r##"
|
||||
Const parameters cannot depend on type parameters.
|
||||
The following is therefore invalid:
|
||||
```
|
||||
fn const_id<T, const N: T>() -> T {
|
||||
N
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
}
|
||||
|
||||
register_diagnostics! {
|
||||
|
@ -185,6 +185,8 @@ enum ResolutionError<'a> {
|
||||
BindingShadowsSomethingUnacceptable(&'a str, Name, &'a NameBinding<'a>),
|
||||
/// Error E0128: type parameters with a default cannot use forward-declared identifiers.
|
||||
ForwardDeclaredTyParam, // FIXME(const_generics:defaults)
|
||||
/// Error E0671: const parameter cannot depend on type parameter.
|
||||
ConstParamDependentOnTypeParam,
|
||||
}
|
||||
|
||||
/// Combines an error with provided span and emits it.
|
||||
@ -440,6 +442,16 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
|
||||
span, "defaulted type parameters cannot be forward declared".to_string());
|
||||
err
|
||||
}
|
||||
ResolutionError::ConstParamDependentOnTypeParam => {
|
||||
let mut err = struct_span_err!(
|
||||
resolver.session,
|
||||
span,
|
||||
E0671,
|
||||
"const parameters cannot depend on type parameters"
|
||||
);
|
||||
err.span_label(span, format!("const parameter depends on type parameter"));
|
||||
err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -915,6 +927,18 @@ fn visit_generics(&mut self, generics: &'tcx Generics) {
|
||||
}
|
||||
}));
|
||||
|
||||
// We also ban access to type parameters for use as the types of const parameters.
|
||||
let mut const_ty_param_ban_rib = Rib::new(TyParamAsConstParamTy);
|
||||
const_ty_param_ban_rib.bindings.extend(generics.params.iter()
|
||||
.filter(|param| {
|
||||
if let GenericParamKind::Type { .. } = param.kind {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.map(|param| (Ident::with_empty_ctxt(param.ident.name), Def::Err)));
|
||||
|
||||
for param in &generics.params {
|
||||
match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => self.visit_generic_param(param),
|
||||
@ -933,11 +957,15 @@ fn visit_generics(&mut self, generics: &'tcx Generics) {
|
||||
default_ban_rib.bindings.remove(&Ident::with_empty_ctxt(param.ident.name));
|
||||
}
|
||||
GenericParamKind::Const { ref ty } => {
|
||||
self.ribs[TypeNS].push(const_ty_param_ban_rib);
|
||||
|
||||
for bound in ¶m.bounds {
|
||||
self.visit_param_bound(bound);
|
||||
}
|
||||
|
||||
self.visit_ty(ty);
|
||||
|
||||
const_ty_param_ban_rib = self.ribs[TypeNS].pop().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -994,6 +1022,9 @@ enum RibKind<'a> {
|
||||
/// from the default of a type parameter because they're not declared
|
||||
/// before said type parameter. Also see the `visit_generics` override.
|
||||
ForwardTyParamBanRibKind,
|
||||
|
||||
/// We forbid the use of type parameters as the types of const parameters.
|
||||
TyParamAsConstParamTy,
|
||||
}
|
||||
|
||||
/// A single local scope.
|
||||
@ -3944,6 +3975,15 @@ fn adjust_local_def(&mut self,
|
||||
return Def::Err;
|
||||
}
|
||||
|
||||
// An invalid use of a type parameter as the type of a const parameter.
|
||||
if let TyParamAsConstParamTy = self.ribs[ns][rib_index].kind {
|
||||
if record_used {
|
||||
resolve_error(self, span, ResolutionError::ConstParamDependentOnTypeParam);
|
||||
}
|
||||
assert_eq!(def, Def::Err);
|
||||
return Def::Err;
|
||||
}
|
||||
|
||||
match def {
|
||||
Def::Upvar(..) => {
|
||||
span_bug!(span, "unexpected {:?} in bindings", def)
|
||||
@ -3955,7 +3995,7 @@ fn adjust_local_def(&mut self,
|
||||
for rib in ribs {
|
||||
match rib.kind {
|
||||
NormalRibKind | ModuleRibKind(..) | MacroDefinition(..) |
|
||||
ForwardTyParamBanRibKind => {
|
||||
ForwardTyParamBanRibKind | TyParamAsConstParamTy => {
|
||||
// Nothing to do. Continue.
|
||||
}
|
||||
ClosureRibKind(function_id) => {
|
||||
@ -4013,7 +4053,7 @@ fn adjust_local_def(&mut self,
|
||||
match rib.kind {
|
||||
NormalRibKind | TraitOrImplItemRibKind | ClosureRibKind(..) |
|
||||
ModuleRibKind(..) | MacroDefinition(..) | ForwardTyParamBanRibKind |
|
||||
ConstantItemRibKind => {
|
||||
ConstantItemRibKind | TyParamAsConstParamTy => {
|
||||
// Nothing to do. Continue.
|
||||
}
|
||||
ItemRibKind | FnItemRibKind => {
|
||||
|
Loading…
Reference in New Issue
Block a user