From 8e7299dfcd4628965b58da10ec7393ab8f2c7e14 Mon Sep 17 00:00:00 2001 From: Ellen Date: Tue, 8 Jun 2021 08:02:12 +0100 Subject: [PATCH 1/3] Support as casts in abstract consts --- .../rustc_middle/src/mir/abstract_const.rs | 5 +++-- compiler/rustc_privacy/src/lib.rs | 7 +++--- .../src/traits/const_evaluatable.rs | 22 ++++++++++++++++--- .../src/traits/object_safety.rs | 14 +++++++----- .../abstract-const-as-cast-2.rs | 13 +++++++++++ .../abstract-const-as-cast-2.stderr | 10 +++++++++ .../abstract-const-as-cast.rs | 9 ++++++++ 7 files changed, 66 insertions(+), 14 deletions(-) create mode 100644 src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.rs create mode 100644 src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.stderr create mode 100644 src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast.rs diff --git a/compiler/rustc_middle/src/mir/abstract_const.rs b/compiler/rustc_middle/src/mir/abstract_const.rs index 776a777b1bdb..1ef10241143b 100644 --- a/compiler/rustc_middle/src/mir/abstract_const.rs +++ b/compiler/rustc_middle/src/mir/abstract_const.rs @@ -1,6 +1,6 @@ //! A subset of a mir body used for const evaluatability checking. -use crate::mir; -use crate::ty; +use crate::mir::{self, CastKind}; +use crate::ty::{self, Ty}; rustc_index::newtype_index! { /// An index into an `AbstractConst`. @@ -17,6 +17,7 @@ pub enum Node<'tcx> { Binop(mir::BinOp, NodeId, NodeId), UnaryOp(mir::UnOp, NodeId), FunctionCall(NodeId, &'tcx [NodeId]), + Cast(CastKind, NodeId, Ty<'tcx>), } #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index e64f12ef48f2..05139b9404f4 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -156,9 +156,10 @@ where let leaf = leaf.subst(tcx, ct.substs); self.visit_const(leaf) } - ACNode::Binop(..) | ACNode::UnaryOp(..) | ACNode::FunctionCall(_, _) => { - ControlFlow::CONTINUE - } + ACNode::Binop(..) + | ACNode::UnaryOp(..) + | ACNode::FunctionCall(_, _) + | ACNode::Cast(_, _, _) => 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 8961cdaebf34..8954918b43c7 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -97,9 +97,10 @@ pub fn is_const_evaluatable<'cx, 'tcx>( ControlFlow::CONTINUE } - Node::Binop(_, _, _) | Node::UnaryOp(_, _) | Node::FunctionCall(_, _) => { - ControlFlow::CONTINUE - } + Node::Binop(_, _, _) + | Node::UnaryOp(_, _) + | Node::FunctionCall(_, _) + | Node::Cast(_, _, _) => ControlFlow::CONTINUE, }); match failure_kind { @@ -304,6 +305,9 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { self.nodes[func].used = true; nodes.iter().for_each(|&n| self.nodes[n].used = true); } + Node::Cast(_, operand, _) => { + self.nodes[operand].used = true; + } } // Nodes start as unused. @@ -408,6 +412,12 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { self.locals[local] = self.add_node(Node::UnaryOp(op, operand), span); Ok(()) } + Rvalue::Cast(cast_kind, ref operand, ty) => { + let operand = self.operand_to_node(span, operand)?; + self.locals[local] = + self.add_node(Node::Cast(cast_kind, operand, ty), span); + Ok(()) + } _ => self.error(Some(span), "unsupported rvalue")?, } } @@ -594,6 +604,7 @@ where recurse(tcx, ct.subtree(func), f)?; args.iter().try_for_each(|&arg| recurse(tcx, ct.subtree(arg), f)) } + Node::Cast(_, operand, _) => recurse(tcx, ct.subtree(operand), f), } } @@ -676,6 +687,11 @@ pub(super) fn try_unify<'tcx>( && iter::zip(a_args, b_args) .all(|(&an, &bn)| try_unify(tcx, a.subtree(an), b.subtree(bn))) } + (Node::Cast(a_cast_kind, a_operand, a_ty), Node::Cast(b_cast_kind, b_operand, b_ty)) + if (a_ty == b_ty) && (a_cast_kind == b_cast_kind) => + { + try_unify(tcx, a.subtree(a_operand), b.subtree(b_operand)) + } _ => false, } } diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index d5e1bd3f9ea2..ac63f2e25dba 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -838,9 +838,10 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( let leaf = leaf.subst(self.tcx, ct.substs); self.visit_const(leaf) } - Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => { - ControlFlow::CONTINUE - } + Node::Binop(..) + | Node::UnaryOp(..) + | Node::FunctionCall(_, _) + | Node::Cast(_, _, _) => ControlFlow::CONTINUE, }) } else { ControlFlow::CONTINUE @@ -859,9 +860,10 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( let leaf = leaf.subst(self.tcx, ct.substs); self.visit_const(leaf) } - Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => { - ControlFlow::CONTINUE - } + Node::Binop(..) + | Node::UnaryOp(..) + | Node::FunctionCall(_, _) + | Node::Cast(_, _, _) => 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 new file mode 100644 index 000000000000..a8f5b89d229a --- /dev/null +++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.rs @@ -0,0 +1,13 @@ +#![feature(const_evaluatable_checked, const_generics)] +#![allow(incomplete_features)] + +trait Evaluatable {} +impl Evaluatable for () {} + +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}>; + +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 new file mode 100644 index 000000000000..167e116f5570 --- /dev/null +++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.stderr @@ -0,0 +1,10 @@ +error: unconstrained generic constant + --> $DIR/abstract-const-as-cast-2.rs:7: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 + 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 new file mode 100644 index 000000000000..33146d95536e --- /dev/null +++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast.rs @@ -0,0 +1,9 @@ +// check-pass +#![feature(const_evaluatable_checked, const_generics)] +#![allow(incomplete_features)] + +struct Foo([u8; N as usize]) +where + [(); N as usize]:; + +fn main() {} From c318364d485a5673015678b3ad0037eff71d6a8e Mon Sep 17 00:00:00 2001 From: Ellen Date: Wed, 9 Jun 2021 19:28:41 +0100 Subject: [PATCH 2/3] 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 05139b9404f4..5a79a9cc6ecf 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -156,10 +156,10 @@ where 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 8954918b43c7..8094b01b3801 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 @@ pub fn is_const_evaluatable<'cx, 'tcx>( 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 ac63f2e25dba..7ebef7f8883a 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 contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( 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 contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( 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 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 a8f5b89d229a..3711a9a87e8a 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 167e116f5570..5ca04d25e556 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 33146d95536e..e486b91abee0 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 @@ struct Foo([u8; N as usize]) 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() {} From 17cd79090efdc8e41ee7535839b6ea0f6909c1d6 Mon Sep 17 00:00:00 2001 From: Ellen Date: Thu, 10 Jun 2021 14:53:38 +0100 Subject: [PATCH 3/3] support `as _` and add tests --- .../src/traits/const_evaluatable.rs | 4 +- ...as-cast.rs => abstract-const-as-cast-1.rs} | 2 +- .../abstract-const-as-cast-2.rs | 2 +- .../abstract-const-as-cast-3.rs | 47 ++++++ .../abstract-const-as-cast-3.stderr | 139 ++++++++++++++++++ .../abstract-const-as-cast-4.rs | 29 ++++ 6 files changed, 220 insertions(+), 3 deletions(-) rename src/test/ui/const-generics/const_evaluatable_checked/{abstract-const-as-cast.rs => abstract-const-as-cast-1.rs} (100%) create mode 100644 src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.rs create mode 100644 src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.stderr create mode 100644 src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-4.rs diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 8094b01b3801..b1a938836b70 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -431,7 +431,9 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { } } // These are not actually relevant for us here, so we can ignore them. - StatementKind::StorageLive(_) | StatementKind::StorageDead(_) => Ok(()), + StatementKind::AscribeUserType(..) + | StatementKind::StorageLive(_) + | StatementKind::StorageDead(_) => Ok(()), _ => self.error(Some(stmt.source_info.span), "unsupported statement")?, } } 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-1.rs similarity index 100% rename from src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast.rs rename to src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-1.rs index e486b91abee0..744a1c4de48c 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-1.rs @@ -6,6 +6,7 @@ struct Foo([u8; N as usize]) where [(); N as usize]:; +struct Bar([u8; (N + 2) as usize]) where [(); (N + 2) as usize]:; // unifying with subtrees struct Evaluatable; @@ -13,6 +14,5 @@ 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() {} 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 3711a9a87e8a..543774649ed5 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 @@ -14,7 +14,7 @@ struct Foo2(Evaluatable::<{N as u128}>) where Evaluatable<{N as usi //~| 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 +//~^ Error: 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-3.rs b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.rs new file mode 100644 index 000000000000..2ca06bd1cb71 --- /dev/null +++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.rs @@ -0,0 +1,47 @@ +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +trait Trait {} +pub struct EvaluatableU128; + +struct HasCastInTraitImpl; +impl Trait for HasCastInTraitImpl {} + +pub fn use_trait_impl() +where + [(); { N + 1}]:, + EvaluatableU128<{N as u128}>:, { + fn assert_impl() {} + + // errors are bad but seems to be pre-existing issue #86198 + assert_impl::>(); + //~^ Error: mismatched types + //~^^ Error: unconstrained generic constant + assert_impl::>(); + //~^ Error: mismatched types + //~^^ Error: unconstrained generic constant + assert_impl::>(); + //~^ Error: mismatched types + assert_impl::>(); + //~^ Error: mismatched types +} +pub fn use_trait_impl_2() +where + [(); { N + 1}]:, + EvaluatableU128<{N as _}>:, { + fn assert_impl() {} + + // errors are bad but seems to be pre-existing issue #86198 + assert_impl::>(); + //~^ Error: mismatched types + //~^^ Error: unconstrained generic constant + assert_impl::>(); + //~^ Error: mismatched types + //~^^ Error: unconstrained generic constant + assert_impl::>(); + //~^ Error: mismatched types + assert_impl::>(); + //~^ Error: mismatched types +} + +fn main() {} diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.stderr b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.stderr new file mode 100644 index 000000000000..c5237fc6f2b3 --- /dev/null +++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.stderr @@ -0,0 +1,139 @@ +error: unconstrained generic constant + --> $DIR/abstract-const-as-cast-3.rs:17:5 + | +LL | fn assert_impl() {} + | ----- required by this bound in `use_trait_impl::assert_impl` +... +LL | assert_impl::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:` +note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` + --> $DIR/abstract-const-as-cast-3.rs:8:22 + | +LL | impl Trait for HasCastInTraitImpl {} + | ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/abstract-const-as-cast-3.rs:17:5 + | +LL | assert_impl::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }` + | + = note: expected type `{ N as u128 }` + found type `{ O as u128 }` + +error: unconstrained generic constant + --> $DIR/abstract-const-as-cast-3.rs:20:5 + | +LL | fn assert_impl() {} + | ----- required by this bound in `use_trait_impl::assert_impl` +... +LL | assert_impl::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:` +note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` + --> $DIR/abstract-const-as-cast-3.rs:8:22 + | +LL | impl Trait for HasCastInTraitImpl {} + | ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/abstract-const-as-cast-3.rs:20:5 + | +LL | assert_impl::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }` + | + = note: expected type `{ N as _ }` + found type `{ O as u128 }` + +error[E0308]: mismatched types + --> $DIR/abstract-const-as-cast-3.rs:23:5 + | +LL | assert_impl::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12_u128`, found `13_u128` + | + = note: expected type `12_u128` + found type `13_u128` + +error[E0308]: mismatched types + --> $DIR/abstract-const-as-cast-3.rs:25:5 + | +LL | assert_impl::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13_u128`, found `14_u128` + | + = note: expected type `13_u128` + found type `14_u128` + +error: unconstrained generic constant + --> $DIR/abstract-const-as-cast-3.rs:35:5 + | +LL | fn assert_impl() {} + | ----- required by this bound in `use_trait_impl_2::assert_impl` +... +LL | assert_impl::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:` +note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` + --> $DIR/abstract-const-as-cast-3.rs:8:22 + | +LL | impl Trait for HasCastInTraitImpl {} + | ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/abstract-const-as-cast-3.rs:35:5 + | +LL | assert_impl::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }` + | + = note: expected type `{ N as u128 }` + found type `{ O as u128 }` + +error: unconstrained generic constant + --> $DIR/abstract-const-as-cast-3.rs:38:5 + | +LL | fn assert_impl() {} + | ----- required by this bound in `use_trait_impl_2::assert_impl` +... +LL | assert_impl::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:` +note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` + --> $DIR/abstract-const-as-cast-3.rs:8:22 + | +LL | impl Trait for HasCastInTraitImpl {} + | ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/abstract-const-as-cast-3.rs:38:5 + | +LL | assert_impl::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }` + | + = note: expected type `{ N as _ }` + found type `{ O as u128 }` + +error[E0308]: mismatched types + --> $DIR/abstract-const-as-cast-3.rs:41:5 + | +LL | assert_impl::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12_u128`, found `13_u128` + | + = note: expected type `12_u128` + found type `13_u128` + +error[E0308]: mismatched types + --> $DIR/abstract-const-as-cast-3.rs:43:5 + | +LL | assert_impl::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13_u128`, found `14_u128` + | + = note: expected type `13_u128` + found type `14_u128` + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-4.rs b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-4.rs new file mode 100644 index 000000000000..0bb4fcff4d0b --- /dev/null +++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-4.rs @@ -0,0 +1,29 @@ +// check-pass +#![feature(const_evaluatable_checked, const_generics)] +#![allow(incomplete_features)] + +trait Trait {} +pub struct EvaluatableU128; + +struct HasCastInTraitImpl; +impl Trait for HasCastInTraitImpl {} + +pub fn use_trait_impl() where EvaluatableU128<{N as u128}>:, { + fn assert_impl() {} + + assert_impl::>(); + assert_impl::>(); + assert_impl::>(); + assert_impl::>(); +} +pub fn use_trait_impl_2() where EvaluatableU128<{N as _}>:, { + fn assert_impl() {} + + assert_impl::>(); + assert_impl::>(); + assert_impl::>(); + assert_impl::>(); +} + + +fn main() {}