From c318364d485a5673015678b3ad0037eff71d6a8e Mon Sep 17 00:00:00 2001 From: Ellen Date: Wed, 9 Jun 2021 19:28:41 +0100 Subject: [PATCH] Add more tests + visit_ty in some places --- compiler/rustc_privacy/src/lib.rs | 8 ++++---- .../src/traits/const_evaluatable.rs | 17 ++++++++++++---- .../src/traits/object_safety.rs | 16 +++++++-------- .../abstract-const-as-cast-2.rs | 13 +++++++++--- .../abstract-const-as-cast-2.stderr | 20 +++++++++++++++++-- .../abstract-const-as-cast.rs | 9 +++++++++ 6 files changed, 62 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 05139b9404f..5a79a9cc6ec 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -156,10 +156,10 @@ fn visit_abstract_const_expr( let leaf = leaf.subst(tcx, ct.substs); self.visit_const(leaf) } - ACNode::Binop(..) - | ACNode::UnaryOp(..) - | ACNode::FunctionCall(_, _) - | ACNode::Cast(_, _, _) => ControlFlow::CONTINUE, + ACNode::Cast(_, _, ty) => self.visit_ty(ty), + ACNode::Binop(..) | ACNode::UnaryOp(..) | ACNode::FunctionCall(_, _) => { + ControlFlow::CONTINUE + } }) } diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 8954918b43c..8094b01b380 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -97,10 +97,19 @@ enum FailureKind { ControlFlow::CONTINUE } - Node::Binop(_, _, _) - | Node::UnaryOp(_, _) - | Node::FunctionCall(_, _) - | Node::Cast(_, _, _) => ControlFlow::CONTINUE, + Node::Cast(_, _, ty) => { + let ty = ty.subst(tcx, ct.substs); + if ty.has_infer_types_or_consts() { + failure_kind = FailureKind::MentionsInfer; + } else if ty.has_param_types_or_consts() { + failure_kind = cmp::min(failure_kind, FailureKind::MentionsParam); + } + + ControlFlow::CONTINUE + } + Node::Binop(_, _, _) | Node::UnaryOp(_, _) | Node::FunctionCall(_, _) => { + ControlFlow::CONTINUE + } }); match failure_kind { diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index ac63f2e25db..7ebef7f8883 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -838,10 +838,10 @@ fn visit_const(&mut self, ct: &ty::Const<'tcx>) -> ControlFlow { let leaf = leaf.subst(self.tcx, ct.substs); self.visit_const(leaf) } - Node::Binop(..) - | Node::UnaryOp(..) - | Node::FunctionCall(_, _) - | Node::Cast(_, _, _) => ControlFlow::CONTINUE, + Node::Cast(_, _, ty) => self.visit_ty(ty), + Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => { + ControlFlow::CONTINUE + } }) } else { ControlFlow::CONTINUE @@ -860,10 +860,10 @@ fn visit_predicate(&mut self, pred: ty::Predicate<'tcx>) -> ControlFlow ControlFlow::CONTINUE, + Node::Cast(_, _, ty) => self.visit_ty(ty), + Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => { + ControlFlow::CONTINUE + } }) } else { ControlFlow::CONTINUE diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.rs b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.rs index a8f5b89d229..3711a9a87e8 100644 --- a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.rs +++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.rs @@ -1,13 +1,20 @@ #![feature(const_evaluatable_checked, const_generics)] #![allow(incomplete_features)] -trait Evaluatable {} -impl Evaluatable for () {} +struct Evaluatable {} struct Foo([u8; N as usize]) //~^ Error: unconstrained generic constant //~| help: try adding a `where` bound using this expression: `where [(); N as usize]:` where - (): Evaluatable<{N as u128}>; + Evaluatable<{N as u128}>:; + +struct Foo2(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:; +//~^ Error: unconstrained generic constant +//~| help: try adding a `where` bound using this expression: `where [(); {N as u128}]:` + +struct Bar([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:; +//~^ unconstrained generic constant +//~| help: try adding a `where` bound using this expression: `where [(); (N + 2) as usize]:` fn main() {} diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.stderr b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.stderr index 167e116f557..5ca04d25e55 100644 --- a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.stderr +++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.stderr @@ -1,10 +1,26 @@ error: unconstrained generic constant - --> $DIR/abstract-const-as-cast-2.rs:7:25 + --> $DIR/abstract-const-as-cast-2.rs:6:25 | LL | struct Foo([u8; N as usize]) | ^^^^^^^^^^^^^^^^ | = help: try adding a `where` bound using this expression: `where [(); N as usize]:` -error: aborting due to previous error +error: unconstrained generic constant + --> $DIR/abstract-const-as-cast-2.rs:12:26 + | +LL | struct Foo2(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try adding a `where` bound using this expression: `where [(); {N as u128}]:` + +error: unconstrained generic constant + --> $DIR/abstract-const-as-cast-2.rs:16:25 + | +LL | struct Bar([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:; + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try adding a `where` bound using this expression: `where [(); (N + 2) as usize]:` + +error: aborting due to 3 previous errors diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast.rs b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast.rs index 33146d95536..e486b91abee 100644 --- a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast.rs +++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast.rs @@ -6,4 +6,13 @@ where [(); N as usize]:; + +// unifying with subtrees +struct Evaluatable; +fn foo() where Evaluatable<{N as usize as u16 }>: { + let _ = Foo::([1; N as usize]); +} + +struct Bar([u8; (N + 2) as usize]) where [(); (N + 2) as usize]:; + fn main() {}