allow concrete self types in consts
This commit is contained in:
parent
7402a39447
commit
e5b82a56c5
11 changed files with 141 additions and 18 deletions
|
@ -112,7 +112,7 @@ impl<'a> Resolver<'a> {
|
|||
match outer_res {
|
||||
Res::SelfTy(maybe_trait_defid, maybe_impl_defid) => {
|
||||
if let Some(impl_span) =
|
||||
maybe_impl_defid.and_then(|def_id| self.opt_span(def_id))
|
||||
maybe_impl_defid.and_then(|(def_id, _)| self.opt_span(def_id))
|
||||
{
|
||||
err.span_label(
|
||||
reduce_impl_span_to_impl_keyword(sm, impl_span),
|
||||
|
|
|
@ -110,6 +110,9 @@ crate enum RibKind<'a> {
|
|||
ItemRibKind(HasGenericParams),
|
||||
|
||||
/// We're in a constant item. Can't refer to dynamic stuff.
|
||||
///
|
||||
/// The `bool` indicates if this constant may reference generic parameters
|
||||
/// and is used to only allow generic parameters to be used in trivial constant expressions.
|
||||
ConstantItemRibKind(bool),
|
||||
|
||||
/// We passed through a module.
|
||||
|
@ -848,7 +851,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
self.with_current_self_item(item, |this| {
|
||||
this.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
|
||||
let item_def_id = this.r.local_def_id(item.id).to_def_id();
|
||||
this.with_self_rib(Res::SelfTy(None, Some(item_def_id)), |this| {
|
||||
this.with_self_rib(Res::SelfTy(None, Some((item_def_id, false))), |this| {
|
||||
visit::walk_item(this, item);
|
||||
});
|
||||
});
|
||||
|
@ -1215,7 +1218,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
// Resolve the trait reference, if necessary.
|
||||
this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
|
||||
let item_def_id = this.r.local_def_id(item_id).to_def_id();
|
||||
this.with_self_rib(Res::SelfTy(trait_id, Some(item_def_id)), |this| {
|
||||
this.with_self_rib(Res::SelfTy(trait_id, Some((item_def_id, false))), |this| {
|
||||
if let Some(trait_ref) = opt_trait_reference.as_ref() {
|
||||
// Resolve type arguments in the trait path.
|
||||
visit::walk_trait_ref(this, trait_ref);
|
||||
|
|
|
@ -2539,7 +2539,7 @@ impl<'a> Resolver<'a> {
|
|||
&mut self,
|
||||
rib_index: usize,
|
||||
rib_ident: Ident,
|
||||
res: Res,
|
||||
mut res: Res,
|
||||
record_used: bool,
|
||||
span: Span,
|
||||
all_ribs: &[Rib<'a>],
|
||||
|
@ -2627,15 +2627,26 @@ impl<'a> Resolver<'a> {
|
|||
continue;
|
||||
}
|
||||
ConstantItemRibKind(trivial) => {
|
||||
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
|
||||
if !trivial && self.session.features_untracked().min_const_generics {
|
||||
if record_used {
|
||||
self.report_error(
|
||||
span,
|
||||
ResolutionError::ParamInNonTrivialAnonConst(rib_ident.name),
|
||||
);
|
||||
if self.session.features_untracked().min_const_generics {
|
||||
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
|
||||
if !trivial {
|
||||
// HACK(min_const_generics): If we encounter `Self` in an anonymous constant
|
||||
// we can't easily tell if it's generic at this stage, so we instead remember
|
||||
// this and then enforce the self type to be concrete later on.
|
||||
if let Res::SelfTy(trait_def, Some((impl_def, _))) = res {
|
||||
res = Res::SelfTy(trait_def, Some((impl_def, true)));
|
||||
} else {
|
||||
if record_used {
|
||||
self.report_error(
|
||||
span,
|
||||
ResolutionError::ParamInNonTrivialAnonConst(
|
||||
rib_ident.name,
|
||||
),
|
||||
);
|
||||
}
|
||||
return Res::Err;
|
||||
}
|
||||
}
|
||||
return Res::Err;
|
||||
}
|
||||
|
||||
if in_ty_param_default {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue