Skip to content

Commit a79f97b

Browse files
Disentangle ForwardGenericParamBan and ConstParamTy ribs
1 parent 385970f commit a79f97b

27 files changed

+188
-105
lines changed

compiler/rustc_resolve/messages.ftl

+9-3
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,13 @@ resolve_extern_crate_self_requires_renaming =
153153
`extern crate self;` requires renaming
154154
.suggestion = rename the `self` crate to be able to import it
155155
156+
resolve_forward_declared_generic_in_const_param_ty =
157+
const parameter types cannot reference parameters before they are declared
158+
.label = const parameter type cannot reference `{$param}` before it is declared
159+
156160
resolve_forward_declared_generic_param =
157-
generic parameters with a default cannot use forward declared identifiers
158-
.label = defaulted generic parameters cannot be forward declared
161+
generic parameter defaults cannot reference parameters before they are declared
162+
.label = cannot reference `{$param}` before it is declared
159163
160164
resolve_found_an_item_configured_out =
161165
found an item that was configured out
@@ -377,9 +381,11 @@ resolve_self_imports_only_allowed_within_multipart_suggestion =
377381
resolve_self_imports_only_allowed_within_suggestion =
378382
consider importing the module directly
379383
384+
resolve_self_in_const_generic_ty =
385+
cannot use `Self` in const parameter type
386+
380387
resolve_self_in_generic_param_default =
381388
generic parameters cannot use `Self` in their defaults
382-
.label = `Self` in generic parameter default
383389
384390
resolve_similarly_named_defined_here =
385391
similarly named {$candidate_descr} `{$candidate}` defined here

compiler/rustc_resolve/src/diagnostics.rs

+20-10
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ use crate::imports::{Import, ImportKind};
4242
use crate::late::{PatternSource, Rib};
4343
use crate::{
4444
AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, BindingKey, Finalize,
45-
HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module, ModuleKind,
46-
ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError,
47-
ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used, VisResolutionError,
48-
errors as errs, path_names_to_string,
45+
ForwardGenericParamBanReason, HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module,
46+
ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult,
47+
PrivacyError, ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used,
48+
VisResolutionError, errors as errs, path_names_to_string,
4949
};
5050

5151
type Res = def::Res<ast::NodeId>;
@@ -887,9 +887,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
887887
participle,
888888
name,
889889
}),
890-
ResolutionError::ForwardDeclaredGenericParam => {
891-
self.dcx().create_err(errs::ForwardDeclaredGenericParam { span })
892-
}
890+
ResolutionError::ForwardDeclaredGenericParam(param, reason) => match reason {
891+
ForwardGenericParamBanReason::Default => {
892+
self.dcx().create_err(errs::ForwardDeclaredGenericParam { param, span })
893+
}
894+
ForwardGenericParamBanReason::ConstParamTy => self
895+
.dcx()
896+
.create_err(errs::ForwardDeclaredGenericInConstParamTy { param, span }),
897+
},
893898
ResolutionError::ParamInTyOfConstParam { name } => {
894899
self.dcx().create_err(errs::ParamInTyOfConstParam { span, name })
895900
}
@@ -908,9 +913,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
908913
ResolutionError::ParamInEnumDiscriminant { name, param_kind: is_type } => self
909914
.dcx()
910915
.create_err(errs::ParamInEnumDiscriminant { span, name, param_kind: is_type }),
911-
ResolutionError::SelfInGenericParamDefault => {
912-
self.dcx().create_err(errs::SelfInGenericParamDefault { span })
913-
}
916+
ResolutionError::ForwardDeclaredSelf(reason) => match reason {
917+
ForwardGenericParamBanReason::Default => {
918+
self.dcx().create_err(errs::SelfInGenericParamDefault { span })
919+
}
920+
ForwardGenericParamBanReason::ConstParamTy => {
921+
self.dcx().create_err(errs::SelfInConstGenericTy { span })
922+
}
923+
},
914924
ResolutionError::UnreachableLabel { name, definition_span, suggestion } => {
915925
let ((sub_suggestion_label, sub_suggestion), sub_unreachable_label) =
916926
match suggestion {

compiler/rustc_resolve/src/errors.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,16 @@ pub(crate) struct ForwardDeclaredGenericParam {
338338
#[primary_span]
339339
#[label]
340340
pub(crate) span: Span,
341+
pub(crate) param: Symbol,
342+
}
343+
344+
#[derive(Diagnostic)]
345+
#[diag(resolve_forward_declared_generic_in_const_param_ty)]
346+
pub(crate) struct ForwardDeclaredGenericInConstParamTy {
347+
#[primary_span]
348+
#[label]
349+
pub(crate) span: Span,
350+
pub(crate) param: Symbol,
341351
}
342352

343353
#[derive(Diagnostic)]
@@ -353,7 +363,13 @@ pub(crate) struct ParamInTyOfConstParam {
353363
#[diag(resolve_self_in_generic_param_default, code = E0735)]
354364
pub(crate) struct SelfInGenericParamDefault {
355365
#[primary_span]
356-
#[label]
366+
pub(crate) span: Span,
367+
}
368+
369+
#[derive(Diagnostic)]
370+
#[diag(resolve_self_in_const_generic_ty)]
371+
pub(crate) struct SelfInConstGenericTy {
372+
#[primary_span]
357373
pub(crate) span: Span,
358374
}
359375

compiler/rustc_resolve/src/ident.rs

+41-20
Original file line numberDiff line numberDiff line change
@@ -1117,31 +1117,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11171117
debug!("validate_res_from_ribs({:?})", res);
11181118
let ribs = &all_ribs[rib_index + 1..];
11191119

1120-
// An invalid forward use of a generic parameter from a previous default.
1121-
if let RibKind::ForwardGenericParamBan = all_ribs[rib_index].kind {
1120+
// An invalid forward use of a generic parameter from a previous default
1121+
// or in a const param ty.
1122+
if let RibKind::ForwardGenericParamBan(reason) = all_ribs[rib_index].kind {
11221123
if let Some(span) = finalize {
11231124
let res_error = if rib_ident.name == kw::SelfUpper {
1124-
ResolutionError::SelfInGenericParamDefault
1125+
ResolutionError::ForwardDeclaredSelf(reason)
11251126
} else {
1126-
ResolutionError::ForwardDeclaredGenericParam
1127+
ResolutionError::ForwardDeclaredGenericParam(rib_ident.name, reason)
11271128
};
11281129
self.report_error(span, res_error);
11291130
}
11301131
assert_eq!(res, Res::Err);
11311132
return Res::Err;
11321133
}
11331134

1134-
if let RibKind::ConstParamTy = all_ribs[rib_index].kind {
1135-
if let Some(span) = finalize {
1136-
self.report_error(
1137-
span,
1138-
ResolutionError::ParamInTyOfConstParam { name: rib_ident.name },
1139-
);
1140-
}
1141-
assert_eq!(res, Res::Err);
1142-
return Res::Err;
1143-
}
1144-
11451135
match res {
11461136
Res::Local(_) => {
11471137
use ResolutionError::*;
@@ -1153,7 +1143,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11531143
| RibKind::FnOrCoroutine
11541144
| RibKind::Module(..)
11551145
| RibKind::MacroDefinition(..)
1156-
| RibKind::ForwardGenericParamBan => {
1146+
| RibKind::ForwardGenericParamBan(_) => {
11571147
// Nothing to do. Continue.
11581148
}
11591149
RibKind::Item(..) | RibKind::AssocItem => {
@@ -1247,12 +1237,27 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
12471237
| RibKind::MacroDefinition(..)
12481238
| RibKind::InlineAsmSym
12491239
| RibKind::AssocItem
1250-
| RibKind::ConstParamTy
1251-
| RibKind::ForwardGenericParamBan => {
1240+
| RibKind::ForwardGenericParamBan(_) => {
12521241
// Nothing to do. Continue.
12531242
continue;
12541243
}
12551244

1245+
RibKind::ConstParamTy => {
1246+
if !self.tcx.features().generic_const_parameter_types() {
1247+
if let Some(span) = finalize {
1248+
self.report_error(
1249+
span,
1250+
ResolutionError::ParamInTyOfConstParam {
1251+
name: rib_ident.name,
1252+
},
1253+
);
1254+
}
1255+
return Res::Err;
1256+
} else {
1257+
continue;
1258+
}
1259+
}
1260+
12561261
RibKind::ConstantItem(trivial, _) => {
12571262
if let ConstantHasGenerics::No(cause) = trivial {
12581263
// HACK(min_const_generics): If we encounter `Self` in an anonymous
@@ -1325,8 +1330,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
13251330
| RibKind::MacroDefinition(..)
13261331
| RibKind::InlineAsmSym
13271332
| RibKind::AssocItem
1328-
| RibKind::ConstParamTy
1329-
| RibKind::ForwardGenericParamBan => continue,
1333+
| RibKind::ForwardGenericParamBan(_) => continue,
1334+
1335+
RibKind::ConstParamTy => {
1336+
if !self.tcx.features().generic_const_parameter_types() {
1337+
if let Some(span) = finalize {
1338+
self.report_error(
1339+
span,
1340+
ResolutionError::ParamInTyOfConstParam {
1341+
name: rib_ident.name,
1342+
},
1343+
);
1344+
}
1345+
return Res::Err;
1346+
} else {
1347+
continue;
1348+
}
1349+
}
13301350

13311351
RibKind::ConstantItem(trivial, _) => {
13321352
if let ConstantHasGenerics::No(cause) = trivial {
@@ -1377,6 +1397,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
13771397
}
13781398
_ => {}
13791399
}
1400+
13801401
res
13811402
}
13821403

compiler/rustc_resolve/src/late.rs

+29-13
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ pub(crate) enum RibKind<'ra> {
207207
/// All bindings in this rib are generic parameters that can't be used
208208
/// from the default of a generic parameter because they're not declared
209209
/// before said generic parameter. Also see the `visit_generics` override.
210-
ForwardGenericParamBan,
210+
ForwardGenericParamBan(ForwardGenericParamBanReason),
211211

212212
/// We are inside of the type of a const parameter. Can't refer to any
213213
/// parameters.
@@ -218,6 +218,12 @@ pub(crate) enum RibKind<'ra> {
218218
InlineAsmSym,
219219
}
220220

221+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
222+
pub(crate) enum ForwardGenericParamBanReason {
223+
Default,
224+
ConstParamTy,
225+
}
226+
221227
impl RibKind<'_> {
222228
/// Whether this rib kind contains generic parameters, as opposed to local
223229
/// variables.
@@ -232,7 +238,7 @@ impl RibKind<'_> {
232238
RibKind::ConstParamTy
233239
| RibKind::AssocItem
234240
| RibKind::Item(..)
235-
| RibKind::ForwardGenericParamBan => true,
241+
| RibKind::ForwardGenericParamBan(_) => true,
236242
}
237243
}
238244

@@ -246,7 +252,7 @@ impl RibKind<'_> {
246252
| RibKind::Item(..)
247253
| RibKind::ConstantItem(..)
248254
| RibKind::Module(..)
249-
| RibKind::ForwardGenericParamBan
255+
| RibKind::ForwardGenericParamBan(_)
250256
| RibKind::ConstParamTy
251257
| RibKind::InlineAsmSym => true,
252258
}
@@ -1541,8 +1547,10 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
15411547
// provide previous type parameters as they're built. We
15421548
// put all the parameters on the ban list and then remove
15431549
// them one by one as they are processed and become available.
1544-
let mut forward_ty_ban_rib = Rib::new(RibKind::ForwardGenericParamBan);
1545-
let mut forward_const_ban_rib = Rib::new(RibKind::ForwardGenericParamBan);
1550+
let mut forward_ty_ban_rib =
1551+
Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default));
1552+
let mut forward_const_ban_rib =
1553+
Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default));
15461554
for param in params.iter() {
15471555
match param.kind {
15481556
GenericParamKind::Type { .. } => {
@@ -1573,16 +1581,24 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
15731581
forward_ty_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err);
15741582
}
15751583

1584+
// NOTE: We use different ribs here not for a technical reason, but just
1585+
// for better diagnostics.
15761586
let mut forward_ty_ban_rib_const_param_ty = Rib {
15771587
bindings: forward_ty_ban_rib.bindings.clone(),
15781588
patterns_with_skipped_bindings: FxHashMap::default(),
1579-
kind: RibKind::ConstParamTy,
1589+
kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy),
15801590
};
15811591
let mut forward_const_ban_rib_const_param_ty = Rib {
15821592
bindings: forward_const_ban_rib.bindings.clone(),
15831593
patterns_with_skipped_bindings: FxHashMap::default(),
1584-
kind: RibKind::ConstParamTy,
1594+
kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy),
15851595
};
1596+
// We'll ban these with a `ConstParamTy` rib, so just clear these ribs for better
1597+
// diagnostics, so we don't mention anything about const param tys having generics at all.
1598+
if !self.r.tcx.features().generic_const_parameter_types() {
1599+
forward_ty_ban_rib_const_param_ty.bindings.clear();
1600+
forward_const_ban_rib_const_param_ty.bindings.clear();
1601+
}
15861602

15871603
self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
15881604
for param in params {
@@ -1608,9 +1624,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
16081624
// Allow all following defaults to refer to this type parameter.
16091625
let i = &Ident::with_dummy_span(param.ident.name);
16101626
forward_ty_ban_rib.bindings.remove(i);
1611-
if this.r.tcx.features().generic_const_parameter_types() {
1612-
forward_ty_ban_rib_const_param_ty.bindings.remove(i);
1613-
}
1627+
forward_ty_ban_rib_const_param_ty.bindings.remove(i);
16141628
}
16151629
GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
16161630
// Const parameters can't have param bounds.
@@ -1621,9 +1635,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
16211635
if this.r.tcx.features().generic_const_parameter_types() {
16221636
this.visit_ty(ty)
16231637
} else {
1638+
this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy));
1639+
this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy));
16241640
this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| {
16251641
this.visit_ty(ty)
16261642
});
1643+
this.ribs[TypeNS].pop().unwrap();
1644+
this.ribs[ValueNS].pop().unwrap();
16271645
}
16281646
forward_const_ban_rib_const_param_ty = this.ribs[ValueNS].pop().unwrap();
16291647
forward_ty_ban_rib_const_param_ty = this.ribs[TypeNS].pop().unwrap();
@@ -1642,9 +1660,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
16421660
// Allow all following defaults to refer to this const parameter.
16431661
let i = &Ident::with_dummy_span(param.ident.name);
16441662
forward_const_ban_rib.bindings.remove(i);
1645-
if this.r.tcx.features().generic_const_parameter_types() {
1646-
forward_const_ban_rib_const_param_ty.bindings.remove(i);
1647-
}
1663+
forward_const_ban_rib_const_param_ty.bindings.remove(i);
16481664
}
16491665
}
16501666
}

compiler/rustc_resolve/src/lib.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
3131
use effective_visibilities::EffectiveVisibilitiesVisitor;
3232
use errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
3333
use imports::{Import, ImportData, ImportKind, NameResolution};
34-
use late::{HasGenericParams, PathSource, PatternSource, UnnecessaryQualification};
34+
use late::{
35+
ForwardGenericParamBanReason, HasGenericParams, PathSource, PatternSource,
36+
UnnecessaryQualification,
37+
};
3538
use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
3639
use rustc_arena::{DroplessArena, TypedArena};
3740
use rustc_ast::expand::StrippedCfgItem;
@@ -272,7 +275,7 @@ enum ResolutionError<'ra> {
272275
shadowed_binding_span: Span,
273276
},
274277
/// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
275-
ForwardDeclaredGenericParam,
278+
ForwardDeclaredGenericParam(Symbol, ForwardGenericParamBanReason),
276279
// FIXME(generic_const_parameter_types): This should give custom output specifying it's only
277280
// problematic to use *forward declared* parameters when the feature is enabled.
278281
/// ERROR E0770: the type of const parameters must not depend on other generic parameters.
@@ -286,7 +289,7 @@ enum ResolutionError<'ra> {
286289
/// This error is emitted even with `generic_const_exprs`.
287290
ParamInEnumDiscriminant { name: Symbol, param_kind: ParamKindInEnumDiscriminant },
288291
/// Error E0735: generic parameters with a default cannot use `Self`
289-
SelfInGenericParamDefault,
292+
ForwardDeclaredSelf(ForwardGenericParamBanReason),
290293
/// Error E0767: use of unreachable label
291294
UnreachableLabel { name: Symbol, definition_span: Span, suggestion: Option<LabelSuggestion> },
292295
/// Error E0323, E0324, E0325: mismatch between trait item and impl item.

tests/crashes/137865.rs

-5
This file was deleted.

tests/ui/const-generics/const-param-type-depends-on-const-param.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
// We may want to lift this restriction in the future.
1010

1111
pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
12-
//~^ ERROR: the type of const parameters must not depend on other generic parameters
13-
//[min]~^^ ERROR `[u8; N]` is forbidden
12+
//~^ ERROR the type of const parameters must not depend on other generic parameters
13+
//[min]~^^ ERROR `[u8; N]` is forbidden as the type of a const generic parameter
1414

1515
pub struct SelfDependent<const N: [u8; N]>;
16-
//~^ ERROR: the type of const parameters must not depend on other generic parameters
17-
//[min]~^^ ERROR `[u8; N]` is forbidden
16+
//~^ ERROR the type of const parameters must not depend on other generic parameters
17+
//[min]~^^ ERROR `[u8; N]` is forbidden as the type of a const generic parameter
1818

1919
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#![feature(adt_const_params)]
2+
3+
trait Trait<const N: usize> {
4+
fn foo<const M: [u8; N]>() {}
5+
//~^ ERROR the type of const parameters must not depend on other generic parameters
6+
}
7+
8+
fn main() {}

0 commit comments

Comments
 (0)