Disentangle ForwardGenericParamBan and ConstParamTy ribs
This commit is contained in:
parent
0998d4095b
commit
42773bfcac
29 changed files with 196 additions and 114 deletions
|
@ -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>;
|
||||
|
@ -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 })
|
||||
}
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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)]
|
||||
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -1117,13 +1117,14 @@ 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);
|
||||
}
|
||||
|
@ -1131,17 +1132,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
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::*;
|
||||
|
@ -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 => {
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -1377,6 +1397,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -232,7 +238,7 @@ impl RibKind<'_> {
|
|||
RibKind::ConstParamTy
|
||||
| RibKind::AssocItem
|
||||
| RibKind::Item(..)
|
||||
| RibKind::ForwardGenericParamBan => true,
|
||||
| RibKind::ForwardGenericParamBan(_) => true,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,7 +252,7 @@ impl RibKind<'_> {
|
|||
| RibKind::Item(..)
|
||||
| RibKind::ConstantItem(..)
|
||||
| RibKind::Module(..)
|
||||
| RibKind::ForwardGenericParamBan
|
||||
| RibKind::ForwardGenericParamBan(_)
|
||||
| RibKind::ConstParamTy
|
||||
| RibKind::InlineAsmSym => true,
|
||||
}
|
||||
|
@ -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 { .. } => {
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue