min_const_generics: allow ty param in repeat expr
This commit is contained in:
parent
8f0fa9d51f
commit
4a15a25662
9 changed files with 192 additions and 38 deletions
|
@ -57,6 +57,12 @@ enum PatternSource {
|
|||
FnParam,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
enum IsRepeatExpr {
|
||||
No,
|
||||
Yes,
|
||||
}
|
||||
|
||||
impl PatternSource {
|
||||
fn descr(self) -> &'static str {
|
||||
match self {
|
||||
|
@ -437,10 +443,8 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
self.resolve_block(block);
|
||||
}
|
||||
fn visit_anon_const(&mut self, constant: &'ast AnonConst) {
|
||||
debug!("visit_anon_const {:?}", constant);
|
||||
self.with_constant_rib(constant.value.is_potential_trivial_const_param(), |this| {
|
||||
visit::walk_anon_const(this, constant);
|
||||
});
|
||||
// We deal with repeat expressions explicitly in `resolve_expr`.
|
||||
self.resolve_anon_const(constant, IsRepeatExpr::No);
|
||||
}
|
||||
fn visit_expr(&mut self, expr: &'ast Expr) {
|
||||
self.resolve_expr(expr, None);
|
||||
|
@ -647,7 +651,11 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
if !check_ns(TypeNS) && check_ns(ValueNS) {
|
||||
// This must be equivalent to `visit_anon_const`, but we cannot call it
|
||||
// directly due to visitor lifetimes so we have to copy-paste some code.
|
||||
self.with_constant_rib(true, |this| {
|
||||
//
|
||||
// Note that we might not be inside of an repeat expression here,
|
||||
// but considering that `IsRepeatExpr` is only relevant for
|
||||
// non-trivial constants this is doesn't matter.
|
||||
self.with_constant_rib(IsRepeatExpr::No, true, |this| {
|
||||
this.smart_resolve_path(
|
||||
ty.id,
|
||||
qself.as_ref(),
|
||||
|
@ -980,9 +988,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
//
|
||||
// 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(true, |this| {
|
||||
this.visit_expr(expr)
|
||||
});
|
||||
this.with_constant_rib(
|
||||
IsRepeatExpr::No,
|
||||
true,
|
||||
|this| this.visit_expr(expr),
|
||||
);
|
||||
}
|
||||
}
|
||||
AssocItemKind::Fn(_, _, generics, _) => {
|
||||
|
@ -1023,7 +1033,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
self.with_item_rib(HasGenericParams::No, |this| {
|
||||
this.visit_ty(ty);
|
||||
if let Some(expr) = expr {
|
||||
this.with_constant_rib(expr.is_potential_trivial_const_param(), |this| {
|
||||
// We already forbid generic params because of the above item rib,
|
||||
// so it doesn't matter whether this is a trivial constant.
|
||||
this.with_constant_rib(IsRepeatExpr::No, true, |this| {
|
||||
this.visit_expr(expr)
|
||||
});
|
||||
}
|
||||
|
@ -1122,12 +1134,29 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
self.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f))
|
||||
}
|
||||
|
||||
fn with_constant_rib(&mut self, trivial: bool, f: impl FnOnce(&mut Self)) {
|
||||
debug!("with_constant_rib");
|
||||
self.with_rib(ValueNS, ConstantItemRibKind(trivial), |this| {
|
||||
this.with_rib(TypeNS, ConstantItemRibKind(trivial), |this| {
|
||||
this.with_label_rib(ConstantItemRibKind(trivial), f);
|
||||
})
|
||||
// HACK(min_const_generics,const_evaluatable_unchecked): We
|
||||
// want to keep allowing `[0; std::mem::size_of::<*mut T>()]`
|
||||
// with a future compat lint for now. We do this by adding an
|
||||
// additional special case for repeat expressions.
|
||||
//
|
||||
// Note that we intentionally still forbid `[0; N + 1]` during
|
||||
// name resolution so that we don't extend the future
|
||||
// compat lint to new cases.
|
||||
fn with_constant_rib(
|
||||
&mut self,
|
||||
is_repeat: IsRepeatExpr,
|
||||
is_trivial: bool,
|
||||
f: impl FnOnce(&mut Self),
|
||||
) {
|
||||
debug!("with_constant_rib: is_repeat={:?} is_trivial={}", is_repeat, is_trivial);
|
||||
self.with_rib(ValueNS, ConstantItemRibKind(is_trivial), |this| {
|
||||
this.with_rib(
|
||||
TypeNS,
|
||||
ConstantItemRibKind(is_repeat == IsRepeatExpr::Yes || is_trivial),
|
||||
|this| {
|
||||
this.with_label_rib(ConstantItemRibKind(is_trivial), f);
|
||||
},
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1272,9 +1301,17 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
//
|
||||
// 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(true, |this| {
|
||||
visit::walk_assoc_item(this, item, AssocCtxt::Impl)
|
||||
});
|
||||
this.with_constant_rib(
|
||||
IsRepeatExpr::No,
|
||||
true,
|
||||
|this| {
|
||||
visit::walk_assoc_item(
|
||||
this,
|
||||
item,
|
||||
AssocCtxt::Impl,
|
||||
)
|
||||
},
|
||||
);
|
||||
}
|
||||
AssocItemKind::Fn(_, _, generics, _) => {
|
||||
// We also need a new scope for the impl item type parameters.
|
||||
|
@ -2199,6 +2236,17 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
debug!("(resolving block) leaving block");
|
||||
}
|
||||
|
||||
fn resolve_anon_const(&mut self, constant: &'ast AnonConst, is_repeat: IsRepeatExpr) {
|
||||
debug!("resolve_anon_const {:?} is_repeat: {:?}", constant, is_repeat);
|
||||
self.with_constant_rib(
|
||||
is_repeat,
|
||||
constant.value.is_potential_trivial_const_param(),
|
||||
|this| {
|
||||
visit::walk_anon_const(this, constant);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) {
|
||||
// First, record candidate traits for this expression if it could
|
||||
// result in the invocation of a method call.
|
||||
|
@ -2322,6 +2370,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
ExprKind::Async(..) | ExprKind::Closure(..) => {
|
||||
self.with_label_rib(ClosureOrAsyncRibKind, |this| visit::walk_expr(this, expr));
|
||||
}
|
||||
ExprKind::Repeat(ref elem, ref ct) => {
|
||||
self.visit_expr(elem);
|
||||
self.resolve_anon_const(ct, IsRepeatExpr::Yes);
|
||||
}
|
||||
_ => {
|
||||
visit::walk_expr(self, expr);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue