Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disentangle ForwardGenericParamBan and ConstParamTy ribs #138259

Merged
merged 1 commit into from
Mar 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions compiler/rustc_resolve/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,13 @@ resolve_extern_crate_self_requires_renaming =
`extern crate self;` requires renaming
.suggestion = rename the `self` crate to be able to import it

resolve_forward_declared_generic_in_const_param_ty =
const parameter types cannot reference parameters before they are declared
.label = const parameter type cannot reference `{$param}` before it is declared

resolve_forward_declared_generic_param =
generic parameters with a default cannot use forward declared identifiers
.label = defaulted generic parameters cannot be forward declared
generic parameter defaults cannot reference parameters before they are declared
.label = cannot reference `{$param}` before it is declared

resolve_found_an_item_configured_out =
found an item that was configured out
Expand Down Expand Up @@ -377,9 +381,11 @@ resolve_self_imports_only_allowed_within_multipart_suggestion =
resolve_self_imports_only_allowed_within_suggestion =
consider importing the module directly

resolve_self_in_const_generic_ty =
cannot use `Self` in const parameter type

resolve_self_in_generic_param_default =
generic parameters cannot use `Self` in their defaults
.label = `Self` in generic parameter default

resolve_similarly_named_defined_here =
similarly named {$candidate_descr} `{$candidate}` defined here
Expand Down
30 changes: 20 additions & 10 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ use crate::imports::{Import, ImportKind};
use crate::late::{PatternSource, Rib};
use crate::{
AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, BindingKey, Finalize,
HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module, ModuleKind,
ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError,
ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used, VisResolutionError,
errors as errs, path_names_to_string,
ForwardGenericParamBanReason, HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module,
ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult,
PrivacyError, ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used,
VisResolutionError, errors as errs, path_names_to_string,
};

type Res = def::Res<ast::NodeId>;
Expand Down Expand Up @@ -887,9 +887,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
participle,
name,
}),
ResolutionError::ForwardDeclaredGenericParam => {
self.dcx().create_err(errs::ForwardDeclaredGenericParam { span })
}
ResolutionError::ForwardDeclaredGenericParam(param, reason) => match reason {
ForwardGenericParamBanReason::Default => {
self.dcx().create_err(errs::ForwardDeclaredGenericParam { param, span })
}
ForwardGenericParamBanReason::ConstParamTy => self
.dcx()
.create_err(errs::ForwardDeclaredGenericInConstParamTy { param, span }),
},
ResolutionError::ParamInTyOfConstParam { name } => {
self.dcx().create_err(errs::ParamInTyOfConstParam { span, name })
}
Expand All @@ -908,9 +913,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ResolutionError::ParamInEnumDiscriminant { name, param_kind: is_type } => self
.dcx()
.create_err(errs::ParamInEnumDiscriminant { span, name, param_kind: is_type }),
ResolutionError::SelfInGenericParamDefault => {
self.dcx().create_err(errs::SelfInGenericParamDefault { span })
}
ResolutionError::ForwardDeclaredSelf(reason) => match reason {
ForwardGenericParamBanReason::Default => {
self.dcx().create_err(errs::SelfInGenericParamDefault { span })
}
ForwardGenericParamBanReason::ConstParamTy => {
self.dcx().create_err(errs::SelfInConstGenericTy { span })
}
},
ResolutionError::UnreachableLabel { name, definition_span, suggestion } => {
let ((sub_suggestion_label, sub_suggestion), sub_unreachable_label) =
match suggestion {
Expand Down
18 changes: 17 additions & 1 deletion compiler/rustc_resolve/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,16 @@ pub(crate) struct ForwardDeclaredGenericParam {
#[primary_span]
#[label]
pub(crate) span: Span,
pub(crate) param: Symbol,
}

#[derive(Diagnostic)]
#[diag(resolve_forward_declared_generic_in_const_param_ty)]
pub(crate) struct ForwardDeclaredGenericInConstParamTy {
#[primary_span]
#[label]
pub(crate) span: Span,
pub(crate) param: Symbol,
}

#[derive(Diagnostic)]
Expand All @@ -353,7 +363,13 @@ pub(crate) struct ParamInTyOfConstParam {
#[diag(resolve_self_in_generic_param_default, code = E0735)]
pub(crate) struct SelfInGenericParamDefault {
#[primary_span]
#[label]
pub(crate) span: Span,
}

#[derive(Diagnostic)]
#[diag(resolve_self_in_const_generic_ty)]
pub(crate) struct SelfInConstGenericTy {
#[primary_span]
pub(crate) span: Span,
}

Expand Down
61 changes: 41 additions & 20 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1117,31 +1117,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
debug!("validate_res_from_ribs({:?})", res);
let ribs = &all_ribs[rib_index + 1..];

// An invalid forward use of a generic parameter from a previous default.
if let RibKind::ForwardGenericParamBan = all_ribs[rib_index].kind {
// An invalid forward use of a generic parameter from a previous default
// or in a const param ty.
if let RibKind::ForwardGenericParamBan(reason) = all_ribs[rib_index].kind {
if let Some(span) = finalize {
let res_error = if rib_ident.name == kw::SelfUpper {
ResolutionError::SelfInGenericParamDefault
ResolutionError::ForwardDeclaredSelf(reason)
} else {
ResolutionError::ForwardDeclaredGenericParam
ResolutionError::ForwardDeclaredGenericParam(rib_ident.name, reason)
};
self.report_error(span, res_error);
}
assert_eq!(res, Res::Err);
return Res::Err;
}

if let RibKind::ConstParamTy = all_ribs[rib_index].kind {
if let Some(span) = finalize {
self.report_error(
span,
ResolutionError::ParamInTyOfConstParam { name: rib_ident.name },
);
}
assert_eq!(res, Res::Err);
return Res::Err;
}

match res {
Res::Local(_) => {
use ResolutionError::*;
Expand All @@ -1153,7 +1143,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
| RibKind::FnOrCoroutine
| RibKind::Module(..)
| RibKind::MacroDefinition(..)
| RibKind::ForwardGenericParamBan => {
| RibKind::ForwardGenericParamBan(_) => {
// Nothing to do. Continue.
}
RibKind::Item(..) | RibKind::AssocItem => {
Expand Down Expand Up @@ -1247,12 +1237,27 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
| RibKind::MacroDefinition(..)
| RibKind::InlineAsmSym
| RibKind::AssocItem
| RibKind::ConstParamTy
| RibKind::ForwardGenericParamBan => {
| RibKind::ForwardGenericParamBan(_) => {
// Nothing to do. Continue.
continue;
}

RibKind::ConstParamTy => {
if !self.tcx.features().generic_const_parameter_types() {
if let Some(span) = finalize {
self.report_error(
span,
ResolutionError::ParamInTyOfConstParam {
name: rib_ident.name,
},
);
}
return Res::Err;
} else {
continue;
}
}

RibKind::ConstantItem(trivial, _) => {
if let ConstantHasGenerics::No(cause) = trivial {
// HACK(min_const_generics): If we encounter `Self` in an anonymous
Expand Down Expand Up @@ -1325,8 +1330,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
| RibKind::MacroDefinition(..)
| RibKind::InlineAsmSym
| RibKind::AssocItem
| RibKind::ConstParamTy
| RibKind::ForwardGenericParamBan => continue,
| RibKind::ForwardGenericParamBan(_) => continue,

RibKind::ConstParamTy => {
if !self.tcx.features().generic_const_parameter_types() {
if let Some(span) = finalize {
self.report_error(
span,
ResolutionError::ParamInTyOfConstParam {
name: rib_ident.name,
},
);
}
return Res::Err;
} else {
continue;
}
}

RibKind::ConstantItem(trivial, _) => {
if let ConstantHasGenerics::No(cause) = trivial {
Expand Down Expand Up @@ -1377,6 +1397,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
_ => {}
}

res
}

Expand Down
42 changes: 29 additions & 13 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ pub(crate) enum RibKind<'ra> {
/// 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.
ForwardGenericParamBan,
ForwardGenericParamBan(ForwardGenericParamBanReason),

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

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub(crate) enum ForwardGenericParamBanReason {
Default,
ConstParamTy,
}

impl RibKind<'_> {
/// Whether this rib kind contains generic parameters, as opposed to local
/// variables.
Expand All @@ -232,7 +238,7 @@ impl RibKind<'_> {
RibKind::ConstParamTy
| RibKind::AssocItem
| RibKind::Item(..)
| RibKind::ForwardGenericParamBan => true,
| RibKind::ForwardGenericParamBan(_) => true,
}
}

Expand All @@ -246,7 +252,7 @@ impl RibKind<'_> {
| RibKind::Item(..)
| RibKind::ConstantItem(..)
| RibKind::Module(..)
| RibKind::ForwardGenericParamBan
| RibKind::ForwardGenericParamBan(_)
| RibKind::ConstParamTy
| RibKind::InlineAsmSym => true,
}
Expand Down Expand Up @@ -1561,8 +1567,10 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, '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(RibKind::ForwardGenericParamBan);
let mut forward_const_ban_rib = Rib::new(RibKind::ForwardGenericParamBan);
let mut forward_ty_ban_rib =
Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default));
let mut forward_const_ban_rib =
Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default));
for param in params.iter() {
match param.kind {
GenericParamKind::Type { .. } => {
Expand Down Expand Up @@ -1593,16 +1601,24 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
forward_ty_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err);
}

// NOTE: We use different ribs here not for a technical reason, but just
// for better diagnostics.
let mut forward_ty_ban_rib_const_param_ty = Rib {
bindings: forward_ty_ban_rib.bindings.clone(),
patterns_with_skipped_bindings: FxHashMap::default(),
kind: RibKind::ConstParamTy,
kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy),
};
let mut forward_const_ban_rib_const_param_ty = Rib {
bindings: forward_const_ban_rib.bindings.clone(),
patterns_with_skipped_bindings: FxHashMap::default(),
kind: RibKind::ConstParamTy,
kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy),
};
// We'll ban these with a `ConstParamTy` rib, so just clear these ribs for better
// diagnostics, so we don't mention anything about const param tys having generics at all.
if !self.r.tcx.features().generic_const_parameter_types() {
forward_ty_ban_rib_const_param_ty.bindings.clear();
forward_const_ban_rib_const_param_ty.bindings.clear();
}

self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
for param in params {
Expand All @@ -1628,9 +1644,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
// Allow all following defaults to refer to this type parameter.
let i = &Ident::with_dummy_span(param.ident.name);
forward_ty_ban_rib.bindings.remove(i);
if this.r.tcx.features().generic_const_parameter_types() {
forward_ty_ban_rib_const_param_ty.bindings.remove(i);
}
forward_ty_ban_rib_const_param_ty.bindings.remove(i);
}
GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
// Const parameters can't have param bounds.
Expand All @@ -1641,9 +1655,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
if this.r.tcx.features().generic_const_parameter_types() {
this.visit_ty(ty)
} else {
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();
this.ribs[ValueNS].pop().unwrap();
}
forward_const_ban_rib_const_param_ty = this.ribs[ValueNS].pop().unwrap();
forward_ty_ban_rib_const_param_ty = this.ribs[TypeNS].pop().unwrap();
Expand All @@ -1662,9 +1680,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
// Allow all following defaults to refer to this const parameter.
let i = &Ident::with_dummy_span(param.ident.name);
forward_const_ban_rib.bindings.remove(i);
if this.r.tcx.features().generic_const_parameter_types() {
forward_const_ban_rib_const_param_ty.bindings.remove(i);
}
forward_const_ban_rib_const_param_ty.bindings.remove(i);
}
}
}
Expand Down
9 changes: 6 additions & 3 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
use effective_visibilities::EffectiveVisibilitiesVisitor;
use errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
use imports::{Import, ImportData, ImportKind, NameResolution};
use late::{HasGenericParams, PathSource, PatternSource, UnnecessaryQualification};
use late::{
ForwardGenericParamBanReason, HasGenericParams, PathSource, PatternSource,
UnnecessaryQualification,
};
use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
use rustc_arena::{DroplessArena, TypedArena};
use rustc_ast::expand::StrippedCfgItem;
Expand Down Expand Up @@ -273,7 +276,7 @@ enum ResolutionError<'ra> {
shadowed_binding_span: Span,
},
/// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
ForwardDeclaredGenericParam,
ForwardDeclaredGenericParam(Symbol, ForwardGenericParamBanReason),
// FIXME(generic_const_parameter_types): This should give custom output specifying it's only
// problematic to use *forward declared* parameters when the feature is enabled.
/// ERROR E0770: the type of const parameters must not depend on other generic parameters.
Expand All @@ -287,7 +290,7 @@ enum ResolutionError<'ra> {
/// 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,
ForwardDeclaredSelf(ForwardGenericParamBanReason),
/// Error E0767: use of unreachable label
UnreachableLabel { name: Symbol, definition_span: Span, suggestion: Option<LabelSuggestion> },
/// Error E0323, E0324, E0325: mismatch between trait item and impl item.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
// We may want to lift this restriction in the future.

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

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

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#![feature(adt_const_params)]

trait Trait<const N: usize> {
fn foo<const M: [u8; N]>() {}
//~^ ERROR the type of const parameters must not depend on other generic parameters
}

fn main() {}
Loading
Loading