diff options
Diffstat (limited to 'tests/ui/traits/new-solver')
37 files changed, 759 insertions, 44 deletions
diff --git a/tests/ui/traits/new-solver/alias_eq_cant_be_furthur_normalized.rs b/tests/ui/traits/new-solver/alias_eq_cant_be_furthur_normalized.rs new file mode 100644 index 000000000..dc726ba51 --- /dev/null +++ b/tests/ui/traits/new-solver/alias_eq_cant_be_furthur_normalized.rs @@ -0,0 +1,29 @@ +// check-pass +// compile-flags: -Ztrait-solver=next + +// check that a goal such as `alias-eq(<T as TraitB>::Assoc<bool>, <T as TraitB>::Assoc<?0>)` +// succeeds with a constraint that `?0 = bool` + +// FIXME(deferred_projection_equality): add a test that this is true during coherence + +trait TraitA {} + +trait TraitB { + type Assoc<T: ?Sized>; +} + +impl<T: TraitB> TraitA for (T, T::Assoc<bool>) {} + +impl TraitB for i32 { + type Assoc<T: ?Sized> = u32; +} + +fn needs_a<T: TraitA>() {} + +fn bar<T: TraitB>() { + needs_a::<(T, <T as TraitB>::Assoc<_>)>(); +} + +fn main() { + bar::<i32>(); +} diff --git a/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs b/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs new file mode 100644 index 000000000..fd5d0e3b1 --- /dev/null +++ b/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs @@ -0,0 +1,45 @@ +// compile-flags: -Ztrait-solver=next + +// check that when computing `alias-eq(<() as Foo<u16, T>>::Assoc, <() as Foo<?0, T>>::Assoc)` +// we do not infer `?0 = u8` via the `for<STOP> (): Foo<u8, STOP>` impl or `?0 = u16` by +// relating substs as either could be a valid solution. + +trait Foo<T, STOP> { + type Assoc; +} + +impl<STOP> Foo<u8, STOP> for () +where + (): Foo<u16, STOP>, +{ + type Assoc = <() as Foo<u16, STOP>>::Assoc; +} + +impl Foo<u16, i8> for () { + type Assoc = u8; +} + +impl Foo<u16, i16> for () { + type Assoc = u16; +} + +fn output<T, U>() -> <() as Foo<T, U>>::Assoc +where + (): Foo<T, U>, +{ + todo!() +} + +fn incomplete<T>() +where + (): Foo<u16, T>, +{ + // `<() as Foo<u16, STOP>>::Assoc == <() as Foo<_, STOP>>::Assoc` + let _: <() as Foo<u16, T>>::Assoc = output::<_, T>(); + //~^ error: type annotations needed + + // let _: <() as Foo<u16, T>>::Assoc = output::<u8, T>(); // OK + // let _: <() as Foo<u16, T>>::Assoc = output::<u16, T>(); // OK +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.stderr b/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.stderr new file mode 100644 index 000000000..a6712332c --- /dev/null +++ b/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/alias_eq_dont_use_normalizes_to_if_substs_eq.rs:38:41 + | +LL | let _: <() as Foo<u16, T>>::Assoc = output::<_, T>(); + | ^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `output` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/traits/new-solver/alias_eq_simple.rs b/tests/ui/traits/new-solver/alias_eq_simple.rs new file mode 100644 index 000000000..6792cf3ce --- /dev/null +++ b/tests/ui/traits/new-solver/alias_eq_simple.rs @@ -0,0 +1,22 @@ +// check-pass +// compile-flags: -Ztrait-solver=next + +// test that the new solver can handle `alias-eq(<i32 as TraitB>::Assoc, u32)` + +trait TraitA {} + +trait TraitB { + type Assoc; +} + +impl<T: TraitB> TraitA for (T, T::Assoc) {} + +impl TraitB for i32 { + type Assoc = u32; +} + +fn needs_a<T: TraitA>() {} + +fn main() { + needs_a::<(i32, u32)>(); +} diff --git a/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.rs b/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.rs new file mode 100644 index 000000000..d4cc380fa --- /dev/null +++ b/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.rs @@ -0,0 +1,20 @@ +// compile-flags: -Ztrait-solver=next + +// check that a `alias-eq(<?0 as TraitB>::Assoc, <T as TraitB>::Assoc)` goal fails. + +// FIXME(deferred_projection_equality): add a test that this is true during coherence + +trait TraitB { + type Assoc; +} + +fn needs_a<T: TraitB>() -> T::Assoc { + unimplemented!() +} + +fn bar<T: TraitB>() { + let _: <_ as TraitB>::Assoc = needs_a::<T>(); + //~^ error: type annotations needed +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.stderr b/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.stderr new file mode 100644 index 000000000..d063d8fce --- /dev/null +++ b/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/alias_eq_substs_eq_not_intercrate.rs:16:12 + | +LL | let _: <_ as TraitB>::Assoc = needs_a::<T>(); + | ^^^^^^^^^^^^^^^^^^^^ cannot infer type for associated type `<_ as TraitB>::Assoc` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/traits/new-solver/async.fail.stderr b/tests/ui/traits/new-solver/async.fail.stderr new file mode 100644 index 000000000..b395c23ae --- /dev/null +++ b/tests/ui/traits/new-solver/async.fail.stderr @@ -0,0 +1,17 @@ +error[E0271]: expected `[async block@$DIR/async.rs:12:17: 12:25]` to be a future that resolves to `i32`, but it resolves to `()` + --> $DIR/async.rs:12:17 + | +LL | needs_async(async {}); + | ----------- ^^^^^^^^ expected `i32`, found `()` + | | + | required by a bound introduced by this call + | +note: required by a bound in `needs_async` + --> $DIR/async.rs:8:31 + | +LL | fn needs_async(_: impl Future<Output = i32>) {} + | ^^^^^^^^^^^^ required by this bound in `needs_async` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/new-solver/async.rs b/tests/ui/traits/new-solver/async.rs new file mode 100644 index 000000000..195cc35ca --- /dev/null +++ b/tests/ui/traits/new-solver/async.rs @@ -0,0 +1,19 @@ +// compile-flags: -Ztrait-solver=next +// edition: 2021 +// revisions: pass fail +//[pass] check-pass + +use std::future::Future; + +fn needs_async(_: impl Future<Output = i32>) {} + +#[cfg(fail)] +fn main() { + needs_async(async {}); + //[fail]~^ ERROR to be a future that resolves to `i32`, but it resolves to `()` +} + +#[cfg(pass)] +fn main() { + needs_async(async { 1i32 }); +} diff --git a/tests/ui/traits/new-solver/builtin-fn-must-return-sized.rs b/tests/ui/traits/new-solver/builtin-fn-must-return-sized.rs new file mode 100644 index 000000000..ba473653e --- /dev/null +++ b/tests/ui/traits/new-solver/builtin-fn-must-return-sized.rs @@ -0,0 +1,17 @@ +// compile-flags: -Ztrait-solver=next + +#![feature(fn_traits)] +#![feature(unboxed_closures)] +#![feature(tuple_trait)] + +use std::ops::Fn; +use std::marker::Tuple; + +fn foo<F: Fn<T>, T: Tuple>(f: Option<F>, t: T) { + let y = (f.unwrap()).call(t); +} + +fn main() { + foo::<fn() -> str, _>(None, ()); + //~^ expected a `Fn<_>` closure, found `fn() -> str` +} diff --git a/tests/ui/traits/new-solver/builtin-fn-must-return-sized.stderr b/tests/ui/traits/new-solver/builtin-fn-must-return-sized.stderr new file mode 100644 index 000000000..f7551739b --- /dev/null +++ b/tests/ui/traits/new-solver/builtin-fn-must-return-sized.stderr @@ -0,0 +1,18 @@ +error[E0277]: expected a `Fn<_>` closure, found `fn() -> str` + --> $DIR/builtin-fn-must-return-sized.rs:15:27 + | +LL | foo::<fn() -> str, _>(None, ()); + | --------------------- ^^^^ expected an `Fn<_>` closure, found `fn() -> str` + | | + | required by a bound introduced by this call + | + = help: the trait `Fn<_>` is not implemented for `fn() -> str` +note: required by a bound in `foo` + --> $DIR/builtin-fn-must-return-sized.rs:10:11 + | +LL | fn foo<F: Fn<T>, T: Tuple>(f: Option<F>, t: T) { + | ^^^^^ required by this bound in `foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/new-solver/elaborate-item-bounds.rs b/tests/ui/traits/new-solver/elaborate-item-bounds.rs new file mode 100644 index 000000000..076aefcf8 --- /dev/null +++ b/tests/ui/traits/new-solver/elaborate-item-bounds.rs @@ -0,0 +1,12 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +trait Foo { + type Bar: Bar; +} + +trait Bar: Baz {} + +trait Baz {} + +fn main() {} diff --git a/tests/ui/traits/new-solver/fn-trait-closure.rs b/tests/ui/traits/new-solver/fn-trait-closure.rs index c0ecf1c91..bd65737ee 100644 --- a/tests/ui/traits/new-solver/fn-trait-closure.rs +++ b/tests/ui/traits/new-solver/fn-trait-closure.rs @@ -1,12 +1,5 @@ // compile-flags: -Ztrait-solver=next -// known-bug: unknown -// failure-status: 101 -// dont-check-compiler-stderr - -// This test will fail until we fix `FulfillmentCtxt::relationships`. That's -// because we create a type variable for closure upvar types, which is not -// constrained until after we try to do fallback on diverging type variables. -// Thus, we will call that function, which is unimplemented. +// check-pass fn require_fn(_: impl Fn() -> i32) {} diff --git a/tests/ui/traits/new-solver/generator.fail.stderr b/tests/ui/traits/new-solver/generator.fail.stderr new file mode 100644 index 000000000..d94d41e35 --- /dev/null +++ b/tests/ui/traits/new-solver/generator.fail.stderr @@ -0,0 +1,64 @@ +error[E0277]: the trait bound `[generator@$DIR/generator.rs:18:21: 18:23]: Generator<A>` is not satisfied + --> $DIR/generator.rs:18:21 + | +LL | needs_generator(|| { + | _____---------------_^ + | | | + | | required by a bound introduced by this call +LL | | +LL | | +LL | | +LL | | yield (); +LL | | }); + | |_____^ the trait `Generator<A>` is not implemented for `[generator@$DIR/generator.rs:18:21: 18:23]` + | +note: required by a bound in `needs_generator` + --> $DIR/generator.rs:14:28 + | +LL | fn needs_generator(_: impl Generator<A, Yield = B, Return = C>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `needs_generator` + +error[E0271]: type mismatch resolving `<[generator@$DIR/generator.rs:18:21: 18:23] as Generator<A>>::Yield == B` + --> $DIR/generator.rs:18:21 + | +LL | needs_generator(|| { + | _____---------------_^ + | | | + | | required by a bound introduced by this call +LL | | +LL | | +LL | | +LL | | yield (); +LL | | }); + | |_____^ types differ + | +note: required by a bound in `needs_generator` + --> $DIR/generator.rs:14:41 + | +LL | fn needs_generator(_: impl Generator<A, Yield = B, Return = C>) {} + | ^^^^^^^^^ required by this bound in `needs_generator` + +error[E0271]: type mismatch resolving `<[generator@$DIR/generator.rs:18:21: 18:23] as Generator<A>>::Return == C` + --> $DIR/generator.rs:18:21 + | +LL | needs_generator(|| { + | _____---------------_^ + | | | + | | required by a bound introduced by this call +LL | | +LL | | +LL | | +LL | | yield (); +LL | | }); + | |_____^ types differ + | +note: required by a bound in `needs_generator` + --> $DIR/generator.rs:14:52 + | +LL | fn needs_generator(_: impl Generator<A, Yield = B, Return = C>) {} + | ^^^^^^^^^^ required by this bound in `needs_generator` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/new-solver/generator.rs b/tests/ui/traits/new-solver/generator.rs new file mode 100644 index 000000000..364373ca8 --- /dev/null +++ b/tests/ui/traits/new-solver/generator.rs @@ -0,0 +1,32 @@ +// compile-flags: -Ztrait-solver=next +// edition: 2021 +// revisions: pass fail +//[pass] check-pass + +#![feature(generator_trait, generators)] + +use std::ops::Generator; + +struct A; +struct B; +struct C; + +fn needs_generator(_: impl Generator<A, Yield = B, Return = C>) {} + +#[cfg(fail)] +fn main() { + needs_generator(|| { + //[fail]~^ ERROR Generator<A>` is not satisfied + //[fail]~| ERROR as Generator<A>>::Yield == B` + //[fail]~| ERROR as Generator<A>>::Return == C` + yield (); + }); +} + +#[cfg(pass)] +fn main() { + needs_generator(|_: A| { + let _: A = yield B; + C + }) +} diff --git a/tests/ui/traits/new-solver/higher-ranked-dyn-bounds.rs b/tests/ui/traits/new-solver/higher-ranked-dyn-bounds.rs new file mode 100644 index 000000000..c886aeeda --- /dev/null +++ b/tests/ui/traits/new-solver/higher-ranked-dyn-bounds.rs @@ -0,0 +1,17 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +trait Trait<'a> { + type Item: for<'b> Trait2<'b>; +} + +trait Trait2<'a> {} +impl Trait2<'_> for () {} + +fn needs_trait(_: Box<impl for<'a> Trait<'a> + ?Sized>) {} + +fn foo(x: Box<dyn for<'a> Trait<'a, Item = ()>>) { + needs_trait(x); +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/more-object-bound.rs b/tests/ui/traits/new-solver/more-object-bound.rs new file mode 100644 index 000000000..712759ef0 --- /dev/null +++ b/tests/ui/traits/new-solver/more-object-bound.rs @@ -0,0 +1,27 @@ +// compile-flags: -Ztrait-solver=next +// From #80800 + +trait SuperTrait { + type A; + type B; +} + +trait Trait: SuperTrait<A = <Self as SuperTrait>::B> {} + +fn transmute<A, B>(x: A) -> B { + foo::<A, B, dyn Trait<A = A, B = B>>(x) + //~^ ERROR type annotations needed: cannot satisfy `dyn Trait<A = A, B = B>: Trait` +} + +fn foo<A, B, T: ?Sized>(x: T::A) -> B +where + T: Trait<B = B>, +{ + x +} + +static X: u8 = 0; +fn main() { + let x = transmute::<&u8, &[u8; 1_000_000]>(&X); + println!("{:?}", x[100_000]); +} diff --git a/tests/ui/traits/new-solver/more-object-bound.stderr b/tests/ui/traits/new-solver/more-object-bound.stderr new file mode 100644 index 000000000..208fdecb0 --- /dev/null +++ b/tests/ui/traits/new-solver/more-object-bound.stderr @@ -0,0 +1,19 @@ +error[E0283]: type annotations needed: cannot satisfy `dyn Trait<A = A, B = B>: Trait` + --> $DIR/more-object-bound.rs:12:5 + | +LL | foo::<A, B, dyn Trait<A = A, B = B>>(x) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: cannot satisfy `dyn Trait<A = A, B = B>: Trait` +note: required by a bound in `foo` + --> $DIR/more-object-bound.rs:18:8 + | +LL | fn foo<A, B, T: ?Sized>(x: T::A) -> B + | --- required by a bound in this function +LL | where +LL | T: Trait<B = B>, + | ^^^^^^^^^^^^ required by this bound in `foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.rs b/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.rs new file mode 100644 index 000000000..46343241b --- /dev/null +++ b/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.rs @@ -0,0 +1,40 @@ +// [no_self_infer] check-pass +// compile-flags: -Ztrait-solver=next +// revisions: self_infer no_self_infer + +// checks that the new solver is smart enough to infer `?0 = U` when solving: +// `normalizes-to(<Vec<?0> as Trait>::Assoc, u8)` +// with `normalizes-to(<Vec<U> as Trait>::Assoc, u8)` in the paramenv even when +// there is a separate `Vec<T>: Trait` bound in the paramenv. +// +// FIXME(-Ztrait-solver=next) +// This could also compile for `normalizes-to(<?0 as Trait>::Assoc, u8)` but +// we currently immediately consider a goal ambiguous if the self type is an +// inference variable. + +trait Trait { + type Assoc; +} + +fn foo<T: Trait<Assoc = u8>>(x: T) {} + +#[cfg(self_infer)] +fn unconstrained<T>() -> T { + todo!() +} + +#[cfg(no_self_infer)] +fn unconstrained<T>() -> Vec<T> { + todo!() +} + +fn bar<T, U>() +where + Vec<T>: Trait, + Vec<U>: Trait<Assoc = u8>, +{ + foo(unconstrained()) + //[self_infer]~^ ERROR type annotations needed +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr b/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr new file mode 100644 index 000000000..062832012 --- /dev/null +++ b/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed + --> $DIR/normalizes_to_ignores_unnormalizable_candidate.rs:36:5 + | +LL | foo(unconstrained()) + | ^^^ cannot infer type of the type parameter `T` declared on the function `foo` + | +help: consider specifying the generic argument + | +LL | foo::<T>(unconstrained()) + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/traits/new-solver/object-unsafety.rs b/tests/ui/traits/new-solver/object-unsafety.rs new file mode 100644 index 000000000..7bdd863a7 --- /dev/null +++ b/tests/ui/traits/new-solver/object-unsafety.rs @@ -0,0 +1,20 @@ +// compile-flags: -Ztrait-solver=next + +trait Setup { + type From: Copy; +} + +fn copy<U: Setup + ?Sized>(from: &U::From) -> U::From { + *from +} + +pub fn copy_any<T>(t: &T) -> T { + copy::<dyn Setup<From=T>>(t) + //~^ ERROR the trait bound `dyn Setup<From = T>: Setup` is not satisfied +} + +fn main() { + let x = String::from("Hello, world"); + let y = copy_any(&x); + println!("{y}"); +} diff --git a/tests/ui/traits/new-solver/object-unsafety.stderr b/tests/ui/traits/new-solver/object-unsafety.stderr new file mode 100644 index 000000000..198ac623d --- /dev/null +++ b/tests/ui/traits/new-solver/object-unsafety.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `dyn Setup<From = T>: Setup` is not satisfied + --> $DIR/object-unsafety.rs:12:12 + | +LL | copy::<dyn Setup<From=T>>(t) + | ^^^^^^^^^^^^^^^^^ the trait `Setup` is not implemented for `dyn Setup<From = T>` + | +note: required by a bound in `copy` + --> $DIR/object-unsafety.rs:7:12 + | +LL | fn copy<U: Setup + ?Sized>(from: &U::From) -> U::From { + | ^^^^^ required by this bound in `copy` +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | pub fn copy_any<T>(t: &T) -> T where dyn Setup<From = T>: Setup { + | ++++++++++++++++++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/new-solver/param-candidate-doesnt-shadow-project.rs b/tests/ui/traits/new-solver/param-candidate-doesnt-shadow-project.rs new file mode 100644 index 000000000..bdf999ec5 --- /dev/null +++ b/tests/ui/traits/new-solver/param-candidate-doesnt-shadow-project.rs @@ -0,0 +1,25 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +trait Foo { + type Assoc; +} + +trait Bar {} + +impl<T> Foo for T { + type Assoc = i32; +} + +impl<T> Bar for T where T: Foo<Assoc = i32> {} + +fn require_bar<T: Bar>() {} + +fn foo<T: Foo>() { + // Unlike the classic solver, `<T as Foo>::Assoc = _` will still project + // down to `i32` even though there's a param-env candidate here, since we + // don't assemble any param-env projection candidates for `T: Foo` alone. + require_bar::<T>(); +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/pointee.rs b/tests/ui/traits/new-solver/pointee.rs new file mode 100644 index 000000000..fa6ee2e2d --- /dev/null +++ b/tests/ui/traits/new-solver/pointee.rs @@ -0,0 +1,23 @@ +// compile-flags: -Ztrait-solver=next +// check-pass +#![feature(ptr_metadata)] + +use std::ptr::{DynMetadata, Pointee}; + +trait Trait<U> {} +struct MyDst<T: ?Sized>(T); + +fn works<T>() { + let _: <T as Pointee>::Metadata = (); + let _: <[T] as Pointee>::Metadata = 1_usize; + let _: <str as Pointee>::Metadata = 1_usize; + let _: <dyn Trait<T> as Pointee>::Metadata = give::<DynMetadata<dyn Trait<T>>>(); + let _: <MyDst<T> as Pointee>::Metadata = (); + let _: <((((([u8],),),),),) as Pointee>::Metadata = 1_usize; +} + +fn give<U>() -> U { + loop {} +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/pointer-like.rs b/tests/ui/traits/new-solver/pointer-like.rs new file mode 100644 index 000000000..3745a075e --- /dev/null +++ b/tests/ui/traits/new-solver/pointer-like.rs @@ -0,0 +1,14 @@ +// compile-flags: -Ztrait-solver=next + +#![feature(pointer_like_trait)] + +use std::marker::PointerLike; + +fn require_(_: impl PointerLike) {} + +fn main() { + require_(1usize); + require_(1u16); + //~^ ERROR `u16` needs to have the same alignment and size as a pointer + require_(&1i16); +} diff --git a/tests/ui/traits/new-solver/pointer-like.stderr b/tests/ui/traits/new-solver/pointer-like.stderr new file mode 100644 index 000000000..f695e6418 --- /dev/null +++ b/tests/ui/traits/new-solver/pointer-like.stderr @@ -0,0 +1,24 @@ +error[E0277]: `u16` needs to have the same alignment and size as a pointer + --> $DIR/pointer-like.rs:11:14 + | +LL | require_(1u16); + | -------- ^^^^ the trait `PointerLike` is not implemented for `u16` + | | + | required by a bound introduced by this call + | + = note: the trait bound `u16: PointerLike` is not satisfied +note: required by a bound in `require_` + --> $DIR/pointer-like.rs:7:21 + | +LL | fn require_(_: impl PointerLike) {} + | ^^^^^^^^^^^ required by this bound in `require_` +help: consider borrowing here + | +LL | require_(&1u16); + | + +LL | require_(&mut 1u16); + | ++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/new-solver/pointer-sized.rs b/tests/ui/traits/new-solver/pointer-sized.rs deleted file mode 100644 index 15681cd13..000000000 --- a/tests/ui/traits/new-solver/pointer-sized.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![feature(pointer_sized_trait)] - -use std::marker::PointerSized; - -fn require_pointer_sized(_: impl PointerSized) {} - -fn main() { - require_pointer_sized(1usize); - require_pointer_sized(1u16); - //~^ ERROR `u16` needs to be a pointer-sized type - require_pointer_sized(&1i16); -} diff --git a/tests/ui/traits/new-solver/pointer-sized.stderr b/tests/ui/traits/new-solver/pointer-sized.stderr deleted file mode 100644 index b250b1331..000000000 --- a/tests/ui/traits/new-solver/pointer-sized.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error[E0277]: `u16` needs to be a pointer-sized type - --> $DIR/pointer-sized.rs:9:27 - | -LL | require_pointer_sized(1u16); - | --------------------- ^^^^ the trait `PointerSized` is not implemented for `u16` - | | - | required by a bound introduced by this call - | - = note: the trait bound `u16: PointerSized` is not satisfied -note: required by a bound in `require_pointer_sized` - --> $DIR/pointer-sized.rs:5:34 - | -LL | fn require_pointer_sized(_: impl PointerSized) {} - | ^^^^^^^^^^^^ required by this bound in `require_pointer_sized` -help: consider borrowing here - | -LL | require_pointer_sized(&1u16); - | + -LL | require_pointer_sized(&mut 1u16); - | ++++ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/new-solver/provisional-result-done.rs b/tests/ui/traits/new-solver/provisional-result-done.rs new file mode 100644 index 000000000..589d34dd7 --- /dev/null +++ b/tests/ui/traits/new-solver/provisional-result-done.rs @@ -0,0 +1,33 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +// This tests checks that we update results in the provisional cache when +// we pop a goal from the stack. +#![feature(auto_traits)] +auto trait Coinductive {} +struct Foo<T>(T); +struct Bar<T>(T); + +impl<T> Coinductive for Foo<T> +where + Bar<T>: Coinductive +{} + +impl<T> Coinductive for Bar<T> +where + Foo<T>: Coinductive, + Bar<T>: ConstrainInfer, +{} + +trait ConstrainInfer {} +impl ConstrainInfer for Bar<u8> {} +impl ConstrainInfer for Foo<u16> {} + +fn impls<T: Coinductive>() -> T { todo!() } + +fn constrain<T: ConstrainInfer>(_: T) {} + +fn main() { + // This should constrain `_` to `u8`. + impls::<Foo<_>>(); +} diff --git a/tests/ui/traits/new-solver/temporary-ambiguity.rs b/tests/ui/traits/new-solver/temporary-ambiguity.rs new file mode 100644 index 000000000..18ee05457 --- /dev/null +++ b/tests/ui/traits/new-solver/temporary-ambiguity.rs @@ -0,0 +1,22 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +// Checks that we don't explode when we assemble >1 candidate for a goal. + +struct Wrapper<T>(T); + +trait Foo {} + +impl Foo for Wrapper<i32> {} + +impl Foo for Wrapper<()> {} + +fn needs_foo(_: impl Foo) {} + +fn main() { + let mut x = Default::default(); + let w = Wrapper(x); + needs_foo(w); + x = 1; + drop(x); +} diff --git a/tests/ui/traits/new-solver/try-example.rs b/tests/ui/traits/new-solver/try-example.rs new file mode 100644 index 000000000..e826f3a00 --- /dev/null +++ b/tests/ui/traits/new-solver/try-example.rs @@ -0,0 +1,28 @@ +// check-pass +// compile-flags: -Ztrait-solver=next + +use std::error::Error; + +fn main() -> Result<(), Box<dyn Error>> { + let x: i32 = parse()?; + Ok(()) +} + +trait Parse {} + +impl Parse for i32 {} + +#[derive(Debug)] +struct ParseError; + +impl std::fmt::Display for ParseError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "ParseError") + } +} + +impl Error for ParseError {} + +fn parse<T: Parse>() -> Result<T, ParseError> { + todo!() +} diff --git a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs new file mode 100644 index 000000000..cde2059ca --- /dev/null +++ b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs @@ -0,0 +1,30 @@ +// compile-flags: -Ztrait-solver=next + +// When we're solving `<T as Foo>::Assoc = i32`, we actually first solve +// `<T as Foo>::Assoc = _#1t`, then unify `_#1t` with `i32`. That goal +// with the inference variable is ambiguous when there are >1 param-env +// candidates. + +// We don't unify the RHS of a projection goal eagerly when solving, both +// for caching reasons and partly to make sure that we don't make the new +// trait solver smarter than it should be. + +// This is (as far as I can tell) a forwards-compatible decision, but if you +// make this test go from fail to pass, be sure you understand the implications! + +trait Foo { + type Assoc; +} + +trait Bar {} + +impl<T> Bar for T where T: Foo<Assoc = i32> {} + +fn needs_bar<T: Bar>() {} + +fn foo<T: Foo<Assoc = i32> + Foo<Assoc = u32>>() { + needs_bar::<T>(); + //~^ ERROR type annotations needed: cannot satisfy `T: Bar` +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr new file mode 100644 index 000000000..fa5e780ee --- /dev/null +++ b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr @@ -0,0 +1,16 @@ +error[E0283]: type annotations needed: cannot satisfy `T: Bar` + --> $DIR/two-projection-param-candidates-are-ambiguous.rs:26:5 + | +LL | needs_bar::<T>(); + | ^^^^^^^^^^^^^^ + | + = note: cannot satisfy `T: Bar` +note: required by a bound in `needs_bar` + --> $DIR/two-projection-param-candidates-are-ambiguous.rs:23:17 + | +LL | fn needs_bar<T: Bar>() {} + | ^^^ required by this bound in `needs_bar` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/traits/new-solver/unsafe-auto-trait-impl.rs b/tests/ui/traits/new-solver/unsafe-auto-trait-impl.rs new file mode 100644 index 000000000..bcfc747eb --- /dev/null +++ b/tests/ui/traits/new-solver/unsafe-auto-trait-impl.rs @@ -0,0 +1,8 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +struct Foo(*mut ()); + +unsafe impl Sync for Foo {} + +fn main() {} diff --git a/tests/ui/traits/new-solver/unsize-good.rs b/tests/ui/traits/new-solver/unsize-good.rs new file mode 100644 index 000000000..87ed9cfd1 --- /dev/null +++ b/tests/ui/traits/new-solver/unsize-good.rs @@ -0,0 +1,25 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +#![feature(unsized_tuple_coercion)] + +trait Foo {} + +impl Foo for i32 {} + +fn main() { + // Unsizing via struct + let _: Box<dyn Foo> = Box::new(1i32); + + // Slice unsizing + let y = [1, 2, 3]; + let _: &[i32] = &y; + + // Tuple unsizing + let hi = (1i32,); + let _: &(dyn Foo,) = &hi; + + // Dropping auto traits + let a: &(dyn Foo + Send) = &1; + let _: &dyn Foo = a; +} diff --git a/tests/ui/traits/new-solver/upcast-right-substs.rs b/tests/ui/traits/new-solver/upcast-right-substs.rs new file mode 100644 index 000000000..c19c82acf --- /dev/null +++ b/tests/ui/traits/new-solver/upcast-right-substs.rs @@ -0,0 +1,14 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +#![feature(trait_upcasting)] + +trait Foo: Bar<i32> + Bar<u32> {} + +trait Bar<T> {} + +fn main() { + let x: &dyn Foo = todo!(); + let y: &dyn Bar<i32> = x; + let z: &dyn Bar<u32> = x; +} diff --git a/tests/ui/traits/new-solver/upcast-wrong-substs.rs b/tests/ui/traits/new-solver/upcast-wrong-substs.rs new file mode 100644 index 000000000..f2d04d932 --- /dev/null +++ b/tests/ui/traits/new-solver/upcast-wrong-substs.rs @@ -0,0 +1,13 @@ +// compile-flags: -Ztrait-solver=next + +#![feature(trait_upcasting)] + +trait Foo: Bar<i32> + Bar<u32> {} + +trait Bar<T> {} + +fn main() { + let x: &dyn Foo = todo!(); + let y: &dyn Bar<usize> = x; + //~^ ERROR mismatched types +} diff --git a/tests/ui/traits/new-solver/upcast-wrong-substs.stderr b/tests/ui/traits/new-solver/upcast-wrong-substs.stderr new file mode 100644 index 000000000..8623f395f --- /dev/null +++ b/tests/ui/traits/new-solver/upcast-wrong-substs.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/upcast-wrong-substs.rs:11:30 + | +LL | let y: &dyn Bar<usize> = x; + | --------------- ^ expected trait `Bar`, found trait `Foo` + | | + | expected due to this + | + = note: expected reference `&dyn Bar<usize>` + found reference `&dyn Foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. |