Extract AssocItem handling.
This commit is contained in:
parent
cdcc53b7dc
commit
228def7e20
1 changed files with 131 additions and 166 deletions
|
@ -1732,72 +1732,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
|this| {
|
|this| {
|
||||||
this.visit_generics(generics);
|
this.visit_generics(generics);
|
||||||
walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits);
|
walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits);
|
||||||
|
this.resolve_trait_items(items);
|
||||||
let walk_assoc_item =
|
|
||||||
|this: &mut Self,
|
|
||||||
generics: &Generics,
|
|
||||||
kind,
|
|
||||||
item: &'ast AssocItem| {
|
|
||||||
this.with_generic_param_rib(
|
|
||||||
&generics.params,
|
|
||||||
AssocItemRibKind,
|
|
||||||
LifetimeRibKind::Generics {
|
|
||||||
binder: item.id,
|
|
||||||
span: generics.span,
|
|
||||||
kind,
|
|
||||||
},
|
|
||||||
|this| {
|
|
||||||
visit::walk_assoc_item(this, item, AssocCtxt::Trait)
|
|
||||||
},
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.with_trait_items(items, |this| {
|
|
||||||
for item in items {
|
|
||||||
match &item.kind {
|
|
||||||
AssocItemKind::Const(_, ty, default) => {
|
|
||||||
this.visit_ty(ty);
|
|
||||||
// Only impose the restrictions of `ConstRibKind` for an
|
|
||||||
// actual constant expression in a provided default.
|
|
||||||
if let Some(expr) = default {
|
|
||||||
// We allow arbitrary const expressions inside of associated consts,
|
|
||||||
// even if they are potentially not const evaluatable.
|
|
||||||
//
|
|
||||||
// Type parameters can already be used and as associated consts are
|
|
||||||
// not used as part of the type system, this is far less surprising.
|
|
||||||
this.with_constant_rib(
|
|
||||||
IsRepeatExpr::No,
|
|
||||||
HasGenericParams::Yes,
|
|
||||||
None,
|
|
||||||
|this| this.visit_expr(expr),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AssocItemKind::Fn(box Fn { generics, .. }) => {
|
|
||||||
walk_assoc_item(
|
|
||||||
this,
|
|
||||||
generics,
|
|
||||||
LifetimeBinderKind::Function,
|
|
||||||
item,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
AssocItemKind::TyAlias(box TyAlias {
|
|
||||||
generics,
|
|
||||||
..
|
|
||||||
}) => {
|
|
||||||
walk_assoc_item(
|
|
||||||
this,
|
|
||||||
generics,
|
|
||||||
LifetimeBinderKind::Item,
|
|
||||||
item,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
AssocItemKind::MacCall(_) => {
|
|
||||||
panic!("unexpanded macro in resolve!")
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -2073,16 +2008,53 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When evaluating a `trait` use its associated types' idents for suggestions in E0412.
|
/// When evaluating a `trait` use its associated types' idents for suggestions in E0412.
|
||||||
fn with_trait_items<T>(
|
fn resolve_trait_items(&mut self, trait_items: &'ast [P<AssocItem>]) {
|
||||||
&mut self,
|
|
||||||
trait_items: &'ast [P<AssocItem>],
|
|
||||||
f: impl FnOnce(&mut Self) -> T,
|
|
||||||
) -> T {
|
|
||||||
let trait_assoc_items =
|
let trait_assoc_items =
|
||||||
replace(&mut self.diagnostic_metadata.current_trait_assoc_items, Some(&trait_items));
|
replace(&mut self.diagnostic_metadata.current_trait_assoc_items, Some(&trait_items));
|
||||||
let result = f(self);
|
|
||||||
|
let walk_assoc_item =
|
||||||
|
|this: &mut Self, generics: &Generics, kind, item: &'ast AssocItem| {
|
||||||
|
this.with_generic_param_rib(
|
||||||
|
&generics.params,
|
||||||
|
AssocItemRibKind,
|
||||||
|
LifetimeRibKind::Generics { binder: item.id, span: generics.span, kind },
|
||||||
|
|this| visit::walk_assoc_item(this, item, AssocCtxt::Trait),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
for item in trait_items {
|
||||||
|
match &item.kind {
|
||||||
|
AssocItemKind::Const(_, ty, default) => {
|
||||||
|
self.visit_ty(ty);
|
||||||
|
// Only impose the restrictions of `ConstRibKind` for an
|
||||||
|
// actual constant expression in a provided default.
|
||||||
|
if let Some(expr) = default {
|
||||||
|
// We allow arbitrary const expressions inside of associated consts,
|
||||||
|
// even if they are potentially not const evaluatable.
|
||||||
|
//
|
||||||
|
// Type parameters can already be used and as associated consts are
|
||||||
|
// not used as part of the type system, this is far less surprising.
|
||||||
|
self.with_constant_rib(
|
||||||
|
IsRepeatExpr::No,
|
||||||
|
HasGenericParams::Yes,
|
||||||
|
None,
|
||||||
|
|this| this.visit_expr(expr),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AssocItemKind::Fn(box Fn { generics, .. }) => {
|
||||||
|
walk_assoc_item(self, generics, LifetimeBinderKind::Function, item);
|
||||||
|
}
|
||||||
|
AssocItemKind::TyAlias(box TyAlias { generics, .. }) => {
|
||||||
|
walk_assoc_item(self, generics, LifetimeBinderKind::Item, item);
|
||||||
|
}
|
||||||
|
AssocItemKind::MacCall(_) => {
|
||||||
|
panic!("unexpanded macro in resolve!")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
self.diagnostic_metadata.current_trait_assoc_items = trait_assoc_items;
|
self.diagnostic_metadata.current_trait_assoc_items = trait_assoc_items;
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is called to resolve a trait reference from an `impl` (i.e., `impl Trait for Foo`).
|
/// This is called to resolve a trait reference from an `impl` (i.e., `impl Trait for Foo`).
|
||||||
|
@ -2173,13 +2145,27 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
this.with_self_rib_ns(ValueNS, Res::SelfCtor(item_def_id), |this| {
|
this.with_self_rib_ns(ValueNS, Res::SelfCtor(item_def_id), |this| {
|
||||||
debug!("resolve_implementation with_self_rib_ns(ValueNS, ...)");
|
debug!("resolve_implementation with_self_rib_ns(ValueNS, ...)");
|
||||||
for item in impl_items {
|
for item in impl_items {
|
||||||
|
this.resolve_impl_item(&**item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resolve_impl_item(&mut self, item: &'ast AssocItem) {
|
||||||
use crate::ResolutionError::*;
|
use crate::ResolutionError::*;
|
||||||
match &item.kind {
|
match &item.kind {
|
||||||
AssocItemKind::Const(_default, _ty, _expr) => {
|
AssocItemKind::Const(_default, _ty, _expr) => {
|
||||||
debug!("resolve_implementation AssocItemKind::Const");
|
debug!("resolve_implementation AssocItemKind::Const");
|
||||||
// If this is a trait impl, ensure the const
|
// If this is a trait impl, ensure the const
|
||||||
// exists in trait
|
// exists in trait
|
||||||
this.check_trait_item(
|
self.check_trait_item(
|
||||||
item.id,
|
item.id,
|
||||||
item.ident,
|
item.ident,
|
||||||
&item.kind,
|
&item.kind,
|
||||||
|
@ -2193,26 +2179,21 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
//
|
//
|
||||||
// Type parameters can already be used and as associated consts are
|
// Type parameters can already be used and as associated consts are
|
||||||
// not used as part of the type system, this is far less surprising.
|
// not used as part of the type system, this is far less surprising.
|
||||||
this.with_constant_rib(
|
self.with_constant_rib(IsRepeatExpr::No, HasGenericParams::Yes, None, |this| {
|
||||||
IsRepeatExpr::No,
|
visit::walk_assoc_item(this, item, AssocCtxt::Impl)
|
||||||
HasGenericParams::Yes,
|
});
|
||||||
None,
|
|
||||||
|this| {
|
|
||||||
visit::walk_assoc_item(
|
|
||||||
this,
|
|
||||||
item,
|
|
||||||
AssocCtxt::Impl,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
AssocItemKind::Fn(box Fn { generics, .. }) => {
|
AssocItemKind::Fn(box Fn { generics, .. }) => {
|
||||||
debug!("resolve_implementation AssocItemKind::Fn");
|
debug!("resolve_implementation AssocItemKind::Fn");
|
||||||
// We also need a new scope for the impl item type parameters.
|
// We also need a new scope for the impl item type parameters.
|
||||||
this.with_generic_param_rib(
|
self.with_generic_param_rib(
|
||||||
&generics.params,
|
&generics.params,
|
||||||
AssocItemRibKind,
|
AssocItemRibKind,
|
||||||
LifetimeRibKind::Generics { binder: item.id, span: generics.span, kind: LifetimeBinderKind::Function },
|
LifetimeRibKind::Generics {
|
||||||
|
binder: item.id,
|
||||||
|
span: generics.span,
|
||||||
|
kind: LifetimeBinderKind::Function,
|
||||||
|
},
|
||||||
|this| {
|
|this| {
|
||||||
// If this is a trait impl, ensure the method
|
// If this is a trait impl, ensure the method
|
||||||
// exists in trait
|
// exists in trait
|
||||||
|
@ -2225,23 +2206,21 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
|i, s, c| MethodNotMemberOfTrait(i, s, c),
|
|i, s, c| MethodNotMemberOfTrait(i, s, c),
|
||||||
);
|
);
|
||||||
|
|
||||||
visit::walk_assoc_item(
|
visit::walk_assoc_item(this, item, AssocCtxt::Impl)
|
||||||
this,
|
|
||||||
item,
|
|
||||||
AssocCtxt::Impl,
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
AssocItemKind::TyAlias(box TyAlias {
|
AssocItemKind::TyAlias(box TyAlias { generics, .. }) => {
|
||||||
generics, ..
|
|
||||||
}) => {
|
|
||||||
debug!("resolve_implementation AssocItemKind::TyAlias");
|
debug!("resolve_implementation AssocItemKind::TyAlias");
|
||||||
// We also need a new scope for the impl item type parameters.
|
// We also need a new scope for the impl item type parameters.
|
||||||
this.with_generic_param_rib(
|
self.with_generic_param_rib(
|
||||||
&generics.params,
|
&generics.params,
|
||||||
AssocItemRibKind,
|
AssocItemRibKind,
|
||||||
LifetimeRibKind::Generics { binder: item.id, span: generics.span, kind: LifetimeBinderKind::Item },
|
LifetimeRibKind::Generics {
|
||||||
|
binder: item.id,
|
||||||
|
span: generics.span,
|
||||||
|
kind: LifetimeBinderKind::Item,
|
||||||
|
},
|
||||||
|this| {
|
|this| {
|
||||||
// If this is a trait impl, ensure the type
|
// If this is a trait impl, ensure the type
|
||||||
// exists in trait
|
// exists in trait
|
||||||
|
@ -2254,11 +2233,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
|i, s, c| TypeNotMemberOfTrait(i, s, c),
|
|i, s, c| TypeNotMemberOfTrait(i, s, c),
|
||||||
);
|
);
|
||||||
|
|
||||||
visit::walk_assoc_item(
|
visit::walk_assoc_item(this, item, AssocCtxt::Impl)
|
||||||
this,
|
|
||||||
item,
|
|
||||||
AssocCtxt::Impl,
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2267,16 +2242,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_trait_item<F>(
|
fn check_trait_item<F>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue