diff options
| author | Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> | 2022-03-25 01:34:30 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-03-25 01:34:30 +0100 |
| commit | 1fcb8fc3e0bc82fc63bbb8baa6c6325d361115fc (patch) | |
| tree | 5453b5ffbb5164b6b6afde0b0b1e45ecb978cb54 /src | |
| parent | c66e0c87267859a46f1a8851f30892985760cfd6 (diff) | |
| parent | 11a70dbc8ac49416598b0ff4525096845a0dc498 (diff) | |
| download | rust-1fcb8fc3e0bc82fc63bbb8baa6c6325d361115fc.tar.gz rust-1fcb8fc3e0bc82fc63bbb8baa6c6325d361115fc.zip | |
Rollup merge of #95179 - b-naber:eval-in-try-unify, r=lcnr
Try to evaluate in try unify and postpone resolution of constants that contain inference variables We want code like that in [`ui/const-generics/generic_const_exprs/eval-try-unify.rs`](https://github.com/rust-lang/rust/compare/master...b-naber:eval-in-try-unify?expand=1#diff-8027038201cf07a6c96abf3cbf0b0f4fdd8a64ce6292435f01c8ed995b87fe9b) to compile. To do that we need to try to evaluate constants in `try_unify_abstract_consts`, this requires us to be more careful about what constants we try to resolve, specifically we cannot try to resolve constants that still contain inference variables. r? `@lcnr`
Diffstat (limited to 'src')
4 files changed, 114 insertions, 189 deletions
diff --git a/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.rs b/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.rs new file mode 100644 index 00000000000..c59d62e576d --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.rs @@ -0,0 +1,26 @@ +// build-pass + +#![feature(generic_const_exprs)] +//~^ WARNING the feature `generic_const_exprs` is incomplete + +trait Generic { + const ASSOC: usize; +} + +impl Generic for u8 { + const ASSOC: usize = 17; +} +impl Generic for u16 { + const ASSOC: usize = 13; +} + + +fn uses_assoc_type<T: Generic, const N: usize>() -> [u8; N + T::ASSOC] { + [0; N + T::ASSOC] +} + +fn only_generic_n<const N: usize>() -> [u8; N + 13] { + uses_assoc_type::<u16, N>() +} + +fn main() {} diff --git a/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.stderr b/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.stderr new file mode 100644 index 00000000000..b5719b3fe1d --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.stderr @@ -0,0 +1,11 @@ +warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/eval-try-unify.rs:3:12 + | +LL | #![feature(generic_const_exprs)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/const-generics/issues/issue-83765.rs b/src/test/ui/const-generics/issues/issue-83765.rs index 68536348d38..71c164ab0a5 100644 --- a/src/test/ui/const-generics/issues/issue-83765.rs +++ b/src/test/ui/const-generics/issues/issue-83765.rs @@ -2,114 +2,115 @@ #![allow(incomplete_features)] trait TensorDimension { - const DIM : usize; - const ISSCALAR : bool = Self::DIM == 0; - fn is_scalar(&self) -> bool {Self::ISSCALAR} + const DIM: usize; + //~^ ERROR cycle detected when resolving instance + // FIXME Given the current state of the compiler its expected that we cycle here, + // but the cycle is still wrong. + const ISSCALAR: bool = Self::DIM == 0; + fn is_scalar(&self) -> bool { + Self::ISSCALAR + } } -trait TensorSize : TensorDimension { - fn size(&self) -> [usize;Self::DIM]; - fn inbounds(&self,index : [usize;Self::DIM]) -> bool { - index.iter().zip(self.size().iter()).all(|(i,s)| i < s) +trait TensorSize: TensorDimension { + fn size(&self) -> [usize; Self::DIM]; + fn inbounds(&self, index: [usize; Self::DIM]) -> bool { + index.iter().zip(self.size().iter()).all(|(i, s)| i < s) } } - trait Broadcastable: TensorSize + Sized { type Element; - fn bget(&self, index:[usize;Self::DIM]) -> Option<Self::Element>; - fn lazy_updim<const NEWDIM : usize>(&self, size : [usize;NEWDIM] ) -> - LazyUpdim<Self,{Self::DIM},NEWDIM> - { - assert!(NEWDIM >= Self::DIM, - "Updimmed tensor cannot have fewer indices than the initial one."); - LazyUpdim {size,reference:&self} + fn bget(&self, index: [usize; Self::DIM]) -> Option<Self::Element>; + fn lazy_updim<const NEWDIM: usize>( + &self, + size: [usize; NEWDIM], + ) -> LazyUpdim<Self, { Self::DIM }, NEWDIM> { + assert!( + NEWDIM >= Self::DIM, + "Updimmed tensor cannot have fewer indices than the initial one." + ); + LazyUpdim { size, reference: &self } } - fn bmap<T,F :Fn(Self::Element) -> T>(&self,foo : F) -> BMap<T,Self,F,{Self::DIM}>{ - BMap {reference:self,closure : foo} + fn bmap<T, F: Fn(Self::Element) -> T>(&self, foo: F) -> BMap<T, Self, F, { Self::DIM }> { + BMap { reference: self, closure: foo } } } - -struct LazyUpdim<'a,T : Broadcastable,const OLDDIM : usize, const DIM : usize> { - size : [usize;DIM], - reference : &'a T +struct LazyUpdim<'a, T: Broadcastable, const OLDDIM: usize, const DIM: usize> { + size: [usize; DIM], + reference: &'a T, } -impl<'a,T : Broadcastable,const DIM : usize> TensorDimension for LazyUpdim<'a,T,{T::DIM},DIM> { - const DIM : usize = DIM; +impl<'a, T: Broadcastable, const DIM: usize> TensorDimension for LazyUpdim<'a, T, { T::DIM }, DIM> { + const DIM: usize = DIM; } -impl<'a,T : Broadcastable,const DIM : usize> TensorSize for LazyUpdim<'a,T,{T::DIM},DIM> { - fn size(&self) -> [usize;DIM] {self.size} - //~^ ERROR method not compatible with trait +impl<'a, T: Broadcastable, const DIM: usize> TensorSize for LazyUpdim<'a, T, { T::DIM }, DIM> { + fn size(&self) -> [usize; DIM] { + self.size + } } -impl<'a,T : Broadcastable,const DIM : usize> Broadcastable for LazyUpdim<'a,T,{T::DIM},DIM> -{ +impl<'a, T: Broadcastable, const DIM: usize> Broadcastable for LazyUpdim<'a, T, { T::DIM }, DIM> { type Element = T::Element; - fn bget(&self,index:[usize;DIM]) -> Option<Self::Element> { - //~^ ERROR method not compatible with trait + fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> { assert!(DIM >= T::DIM); - if !self.inbounds(index) {return None} - //~^ ERROR unconstrained generic constant - //~| ERROR mismatched types + if !self.inbounds(index) { + return None; + } let size = self.size(); - //~^ ERROR unconstrained generic constant - let newindex : [usize;T::DIM] = Default::default(); - //~^ ERROR the trait bound `[usize; _]: Default` is not satisfied + let newindex: [usize; T::DIM] = Default::default(); self.reference.bget(newindex) } } -struct BMap<'a,R, T : Broadcastable, F : Fn(T::Element) -> R , const DIM: usize> { - reference : &'a T, - closure : F +struct BMap<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> { + reference: &'a T, + closure: F, } -impl<'a,R, T : Broadcastable, F : Fn(T::Element) -> R, - const DIM: usize> TensorDimension for BMap<'a,R,T,F,DIM> { - - const DIM : usize = DIM; +impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> TensorDimension + for BMap<'a, R, T, F, DIM> +{ + const DIM: usize = DIM; } -impl<'a,R, T : Broadcastable, F : Fn(T::Element) -> R , - const DIM: usize> TensorSize for BMap<'a,R,T,F,DIM> { - - fn size(&self) -> [usize;DIM] {self.reference.size()} - //~^ ERROR unconstrained generic constant - //~| ERROR mismatched types - //~| ERROR method not compatible with trait +impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> TensorSize + for BMap<'a, R, T, F, DIM> +{ + fn size(&self) -> [usize; DIM] { + self.reference.size() + } } -impl<'a,R, T : Broadcastable, F : Fn(T::Element) -> R , - const DIM: usize> Broadcastable for BMap<'a,R,T,F,DIM> { - +impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> Broadcastable + for BMap<'a, R, T, F, DIM> +{ type Element = R; - fn bget(&self,index:[usize;DIM]) -> Option<Self::Element> { - //~^ ERROR method not compatible with trait + fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> { self.reference.bget(index).map(&self.closure) - //~^ ERROR unconstrained generic constant - //~| ERROR mismatched types } } impl<T> TensorDimension for Vec<T> { - const DIM : usize = 1; + const DIM: usize = 1; } impl<T> TensorSize for Vec<T> { - fn size(&self) -> [usize;1] {[self.len()]} + fn size(&self) -> [usize; 1] { + [self.len()] + } } impl<T: Clone> Broadcastable for Vec<T> { type Element = T; - fn bget(& self,index : [usize;1]) -> Option<T> { + fn bget(&self, index: [usize; 1]) -> Option<T> { self.get(index[0]).cloned() } } fn main() { - let v = vec![1,2,3]; - let bv = v.lazy_updim([3,4]); - let bbv = bv.bmap(|x| x*x); + let v = vec![1, 2, 3]; + let bv = v.lazy_updim([3, 4]); + let bbv = bv.bmap(|x| x * x); - println!("The size of v is {:?}",bbv.bget([0,2]).expect("Out of bounds.")); + println!("The size of v is {:?}", bbv.bget([0, 2]).expect("Out of bounds.")); } diff --git a/src/test/ui/const-generics/issues/issue-83765.stderr b/src/test/ui/const-generics/issues/issue-83765.stderr index a49f850717f..8705a39fa4b 100644 --- a/src/test/ui/const-generics/issues/issue-83765.stderr +++ b/src/test/ui/const-generics/issues/issue-83765.stderr @@ -1,130 +1,17 @@ -error[E0308]: method not compatible with trait - --> $DIR/issue-83765.rs:44:5 +error[E0391]: cycle detected when resolving instance `<LazyUpdim<T, { T::DIM }, DIM> as TensorDimension>::DIM` + --> $DIR/issue-83765.rs:5:5 | -LL | fn size(&self) -> [usize;DIM] {self.size} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM` +LL | const DIM: usize; + | ^^^^^^^^^^^^^^^^^ | - = note: expected type `Self::DIM` - found type `DIM` - -error[E0308]: method not compatible with trait - --> $DIR/issue-83765.rs:51:5 - | -LL | fn bget(&self,index:[usize;DIM]) -> Option<Self::Element> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM` - | - = note: expected type `Self::DIM` - found type `DIM` - -error[E0308]: method not compatible with trait - --> $DIR/issue-83765.rs:78:5 - | -LL | fn size(&self) -> [usize;DIM] {self.reference.size()} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM` - | - = note: expected type `Self::DIM` - found type `DIM` - -error[E0308]: method not compatible with trait - --> $DIR/issue-83765.rs:88:5 - | -LL | fn bget(&self,index:[usize;DIM]) -> Option<Self::Element> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM` - | - = note: expected type `Self::DIM` - found type `DIM` - -error: unconstrained generic constant - --> $DIR/issue-83765.rs:54:18 - | -LL | if !self.inbounds(index) {return None} - | ^^^^^^^^ - | - = help: try adding a `where` bound using this expression: `where [(); Self::DIM]:` -note: required by a bound in `TensorSize::inbounds` - --> $DIR/issue-83765.rs:12:38 - | -LL | fn inbounds(&self,index : [usize;Self::DIM]) -> bool { - | ^^^^^^^^^ required by this bound in `TensorSize::inbounds` - -error[E0308]: mismatched types - --> $DIR/issue-83765.rs:54:27 - | -LL | if !self.inbounds(index) {return None} - | ^^^^^ expected `Self::DIM`, found `DIM` - | - = note: expected type `Self::DIM` - found type `DIM` - -error: unconstrained generic constant - --> $DIR/issue-83765.rs:57:25 - | -LL | let size = self.size(); - | ^^^^ - | - = help: try adding a `where` bound using this expression: `where [(); Self::DIM]:` -note: required by a bound in `TensorSize::size` - --> $DIR/issue-83765.rs:11:30 - | -LL | fn size(&self) -> [usize;Self::DIM]; - | ^^^^^^^^^ required by this bound in `TensorSize::size` - -error[E0277]: the trait bound `[usize; _]: Default` is not satisfied - --> $DIR/issue-83765.rs:59:41 - | -LL | let newindex : [usize;T::DIM] = Default::default(); - | ^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `[usize; _]` - | -help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement - | -LL | impl<'a,T : Broadcastable,const DIM : usize> Broadcastable for LazyUpdim<'a,T,{T::DIM},DIM> where [usize; _]: Default - | +++++++++++++++++++++++++ - -error: unconstrained generic constant - --> $DIR/issue-83765.rs:78:51 - | -LL | fn size(&self) -> [usize;DIM] {self.reference.size()} - | ^^^^ - | - = help: try adding a `where` bound using this expression: `where [(); Self::DIM]:` -note: required by a bound in `TensorSize::size` - --> $DIR/issue-83765.rs:11:30 - | -LL | fn size(&self) -> [usize;Self::DIM]; - | ^^^^^^^^^ required by this bound in `TensorSize::size` - -error[E0308]: mismatched types - --> $DIR/issue-83765.rs:78:36 - | -LL | fn size(&self) -> [usize;DIM] {self.reference.size()} - | ^^^^^^^^^^^^^^^^^^^^^ expected `DIM`, found `Self::DIM` - | - = note: expected type `DIM` - found type `Self::DIM` - -error: unconstrained generic constant - --> $DIR/issue-83765.rs:90:24 - | -LL | self.reference.bget(index).map(&self.closure) - | ^^^^ - | - = help: try adding a `where` bound using this expression: `where [(); Self::DIM]:` -note: required by a bound in `Broadcastable::bget` - --> $DIR/issue-83765.rs:20:33 - | -LL | fn bget(&self, index:[usize;Self::DIM]) -> Option<Self::Element>; - | ^^^^^^^^^ required by this bound in `Broadcastable::bget` - -error[E0308]: mismatched types - --> $DIR/issue-83765.rs:90:29 - | -LL | self.reference.bget(index).map(&self.closure) - | ^^^^^ expected `Self::DIM`, found `DIM` +note: ...which requires checking if `TensorDimension` fulfills its obligations... + --> $DIR/issue-83765.rs:4:1 | - = note: expected type `Self::DIM` - found type `DIM` +LL | trait TensorDimension { + | ^^^^^^^^^^^^^^^^^^^^^ + = note: ...which again requires resolving instance `<LazyUpdim<T, { T::DIM }, DIM> as TensorDimension>::DIM`, completing the cycle + = note: cycle used when normalizing `<LazyUpdim<T, { T::DIM }, DIM> as TensorDimension>::DIM` -error: aborting due to 12 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0391`. |
