-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #100315 - compiler-errors:norm-ct-in-proj, r=lcnr
Keep going if normalized projection has unevaluated consts in `QueryNormalizer` #100312 was the wrong approach, I think this is the right one. When normalizing a type, if we see that it's a projection, we currently defer to `tcx.normalize_projection_ty`, which normalizes the projections away but doesn't touch the unevaluated constants. So now we just continue to fold the type if it has unevaluated constants so we make sure to evaluate those too, if we can. Fixes #100217 Fixes #83972 Fixes #84669 Fixes #86710 Fixes #82268 Fixes #73298
- Loading branch information
Showing
7 changed files
with
299 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
src/test/ui/const-generics/generic_const_exprs/issue-100217.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// build-pass | ||
|
||
#![allow(incomplete_features)] | ||
#![feature(generic_const_exprs)] | ||
|
||
trait TraitOne { | ||
const MY_NUM: usize; | ||
type MyErr: std::fmt::Debug; | ||
|
||
fn do_one_stuff(arr: [u8; Self::MY_NUM]) -> Result<(), Self::MyErr>; | ||
} | ||
|
||
trait TraitTwo { | ||
fn do_two_stuff(); | ||
} | ||
|
||
impl<O: TraitOne> TraitTwo for O | ||
where | ||
[(); Self::MY_NUM]:, | ||
{ | ||
fn do_two_stuff() { | ||
O::do_one_stuff([5; Self::MY_NUM]).unwrap() | ||
} | ||
} | ||
|
||
struct Blargotron; | ||
|
||
#[derive(Debug)] | ||
struct ErrTy<const N: usize>([(); N]); | ||
|
||
impl TraitOne for Blargotron { | ||
const MY_NUM: usize = 3; | ||
type MyErr = ErrTy<{ Self::MY_NUM }>; | ||
|
||
fn do_one_stuff(_arr: [u8; Self::MY_NUM]) -> Result<(), Self::MyErr> { | ||
Ok(()) | ||
} | ||
} | ||
|
||
fn main() { | ||
Blargotron::do_two_stuff(); | ||
} |
23 changes: 23 additions & 0 deletions
23
src/test/ui/const-generics/generic_const_exprs/issue-73298.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// build-pass | ||
|
||
#![allow(incomplete_features)] | ||
#![feature(generic_const_exprs)] | ||
|
||
use std::convert::AsMut; | ||
use std::default::Default; | ||
|
||
trait Foo: Sized { | ||
type Baz: Default + AsMut<[u8]>; | ||
fn bar() { | ||
Self::Baz::default().as_mut(); | ||
} | ||
} | ||
|
||
impl Foo for () { | ||
type Baz = [u8; 1 * 1]; | ||
//type Baz = [u8; 1]; | ||
} | ||
|
||
fn main() { | ||
<() as Foo>::bar(); | ||
} |
73 changes: 73 additions & 0 deletions
73
src/test/ui/const-generics/generic_const_exprs/issue-82268.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// build-pass | ||
|
||
#![allow(incomplete_features)] | ||
#![feature(generic_const_exprs)] | ||
|
||
trait Collate<Op> { | ||
type Pass; | ||
type Fail; | ||
|
||
fn collate(self) -> (Self::Pass, Self::Fail); | ||
} | ||
|
||
impl<Op> Collate<Op> for () { | ||
type Pass = (); | ||
type Fail = (); | ||
|
||
fn collate(self) -> ((), ()) { | ||
((), ()) | ||
} | ||
} | ||
|
||
trait CollateStep<X, Prev> { | ||
type Pass; | ||
type Fail; | ||
fn collate_step(x: X, prev: Prev) -> (Self::Pass, Self::Fail); | ||
} | ||
|
||
impl<X, P, F> CollateStep<X, (P, F)> for () { | ||
type Pass = (X, P); | ||
type Fail = F; | ||
|
||
fn collate_step(x: X, (p, f): (P, F)) -> ((X, P), F) { | ||
((x, p), f) | ||
} | ||
} | ||
|
||
struct CollateOpImpl<const MASK: u32>; | ||
trait CollateOpStep { | ||
type NextOp; | ||
type Apply; | ||
} | ||
|
||
impl<const MASK: u32> CollateOpStep for CollateOpImpl<MASK> | ||
where | ||
CollateOpImpl<{ MASK >> 1 }>: Sized, | ||
{ | ||
type NextOp = CollateOpImpl<{ MASK >> 1 }>; | ||
type Apply = (); | ||
} | ||
|
||
impl<H, T, Op: CollateOpStep> Collate<Op> for (H, T) | ||
where | ||
T: Collate<Op::NextOp>, | ||
Op::Apply: CollateStep<H, (T::Pass, T::Fail)>, | ||
{ | ||
type Pass = <Op::Apply as CollateStep<H, (T::Pass, T::Fail)>>::Pass; | ||
type Fail = <Op::Apply as CollateStep<H, (T::Pass, T::Fail)>>::Fail; | ||
|
||
fn collate(self) -> (Self::Pass, Self::Fail) { | ||
<Op::Apply as CollateStep<H, (T::Pass, T::Fail)>>::collate_step(self.0, self.1.collate()) | ||
} | ||
} | ||
|
||
fn collate<X, const MASK: u32>(x: X) -> (X::Pass, X::Fail) | ||
where | ||
X: Collate<CollateOpImpl<MASK>>, | ||
{ | ||
x.collate() | ||
} | ||
|
||
fn main() { | ||
dbg!(collate::<_, 5>(("Hello", (42, ('!', ()))))); | ||
} |
38 changes: 38 additions & 0 deletions
38
src/test/ui/const-generics/generic_const_exprs/issue-83972.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// build-pass | ||
|
||
#![allow(incomplete_features)] | ||
#![feature(generic_const_exprs)] | ||
|
||
pub trait Foo { | ||
fn foo(&self); | ||
} | ||
|
||
pub struct FooImpl<const N: usize>; | ||
impl<const N: usize> Foo for FooImpl<N> { | ||
fn foo(&self) {} | ||
} | ||
|
||
pub trait Bar: 'static { | ||
type Foo: Foo; | ||
fn get() -> &'static Self::Foo; | ||
} | ||
|
||
struct BarImpl; | ||
impl Bar for BarImpl { | ||
type Foo = FooImpl< | ||
{ | ||
{ 4 } | ||
}, | ||
>; | ||
fn get() -> &'static Self::Foo { | ||
&FooImpl | ||
} | ||
} | ||
|
||
pub fn boom<B: Bar>() { | ||
B::get().foo(); | ||
} | ||
|
||
fn main() { | ||
boom::<BarImpl>(); | ||
} |
30 changes: 30 additions & 0 deletions
30
src/test/ui/const-generics/generic_const_exprs/issue-84669.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// build-pass | ||
|
||
#![feature(generic_const_exprs)] | ||
#![allow(incomplete_features)] | ||
|
||
trait Foo { | ||
type Output; | ||
|
||
fn foo() -> Self::Output; | ||
} | ||
|
||
impl Foo for [u8; 3] { | ||
type Output = [u8; 1 + 2]; | ||
|
||
fn foo() -> [u8; 3] { | ||
[1u8; 3] | ||
} | ||
} | ||
|
||
fn bug<const N: usize>() | ||
where | ||
[u8; N]: Foo, | ||
<[u8; N] as Foo>::Output: AsRef<[u8]>, | ||
{ | ||
<[u8; N]>::foo().as_ref(); | ||
} | ||
|
||
fn main() { | ||
bug::<3>(); | ||
} |
73 changes: 73 additions & 0 deletions
73
src/test/ui/const-generics/generic_const_exprs/issue-86710.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// build-pass | ||
|
||
#![allow(incomplete_features)] | ||
#![feature(generic_const_exprs)] | ||
|
||
use std::marker::PhantomData; | ||
|
||
fn main() { | ||
let x = FooImpl::<BarImpl<1>> { phantom: PhantomData }; | ||
let _ = x.foo::<BarImpl<1>>(); | ||
} | ||
|
||
trait Foo<T> | ||
where | ||
T: Bar, | ||
{ | ||
fn foo<U>(&self) | ||
where | ||
T: Operation<U>, | ||
<T as Operation<U>>::Output: Bar; | ||
} | ||
|
||
struct FooImpl<T> | ||
where | ||
T: Bar, | ||
{ | ||
phantom: PhantomData<T>, | ||
} | ||
|
||
impl<T> Foo<T> for FooImpl<T> | ||
where | ||
T: Bar, | ||
{ | ||
fn foo<U>(&self) | ||
where | ||
T: Operation<U>, | ||
<T as Operation<U>>::Output: Bar, | ||
{ | ||
<<T as Operation<U>>::Output as Bar>::error_occurs_here(); | ||
} | ||
} | ||
|
||
trait Bar { | ||
fn error_occurs_here(); | ||
} | ||
|
||
struct BarImpl<const N: usize>; | ||
|
||
impl<const N: usize> Bar for BarImpl<N> { | ||
fn error_occurs_here() {} | ||
} | ||
|
||
trait Operation<Rhs> { | ||
type Output; | ||
} | ||
|
||
//// Part-A: This causes error. | ||
impl<const M: usize, const N: usize> Operation<BarImpl<M>> for BarImpl<N> | ||
where | ||
BarImpl<{ N + M }>: Sized, | ||
{ | ||
type Output = BarImpl<{ N + M }>; | ||
} | ||
|
||
//// Part-B: This doesn't cause error. | ||
// impl<const M: usize, const N: usize> Operation<BarImpl<M>> for BarImpl<N> { | ||
// type Output = BarImpl<M>; | ||
// } | ||
|
||
//// Part-C: This also doesn't cause error. | ||
// impl<const M: usize, const N: usize> Operation<BarImpl<M>> for BarImpl<N> { | ||
// type Output = BarImpl<{ M }>; | ||
// } |