diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:03 +0000 |
commit | 64d98f8ee037282c35007b64c2649055c56af1db (patch) | |
tree | 5492bcf97fce41ee1c0b1cc2add283f3e66cdab0 /tests/ui/chalkify | |
parent | Adding debian version 1.67.1+dfsg1-1. (diff) | |
download | rustc-64d98f8ee037282c35007b64c2649055c56af1db.tar.xz rustc-64d98f8ee037282c35007b64c2649055c56af1db.zip |
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/chalkify')
38 files changed, 829 insertions, 0 deletions
diff --git a/tests/ui/chalkify/arithmetic.rs b/tests/ui/chalkify/arithmetic.rs new file mode 100644 index 000000000..6c78a71b0 --- /dev/null +++ b/tests/ui/chalkify/arithmetic.rs @@ -0,0 +1,20 @@ +// check-pass +// compile-flags: -Z trait-solver=chalk + +fn main() { + 1 + 2; + 3 * 6; + 2 - 5; + 17 / 6; + 23 % 11; + 4 & 6; + 7 | 15; + 4 << 7; + 123 >> 3; + 1 == 2; + 5 != 5; + 6 < 2; + 7 > 11; + 3 <= 1; + 9 >= 14; +} diff --git a/tests/ui/chalkify/assert.rs b/tests/ui/chalkify/assert.rs new file mode 100644 index 000000000..834c8935e --- /dev/null +++ b/tests/ui/chalkify/assert.rs @@ -0,0 +1,6 @@ +// run-pass +// compile-flags: -Z trait-solver=chalk + +fn main() { + assert_eq!(1, 1); +} diff --git a/tests/ui/chalkify/basic.rs b/tests/ui/chalkify/basic.rs new file mode 100644 index 000000000..4a7cd9396 --- /dev/null +++ b/tests/ui/chalkify/basic.rs @@ -0,0 +1,12 @@ +// check-pass +// compile-flags: -Z trait-solver=chalk + +trait Foo {} + +struct Bar {} + +impl Foo for Bar {} + +fn main() -> () { + let _ = Bar {}; +} diff --git a/tests/ui/chalkify/bugs/async.rs b/tests/ui/chalkify/bugs/async.rs new file mode 100644 index 000000000..3169e4781 --- /dev/null +++ b/tests/ui/chalkify/bugs/async.rs @@ -0,0 +1,25 @@ +// edition:2021 +// known-bug: unknown +// unset-rustc-env:RUST_BACKTRACE +// compile-flags:-Z trait-solver=chalk +// error-pattern:internal compiler error +// failure-status:101 +// normalize-stderr-test "DefId([^)]*)" -> "..." +// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" +// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" +// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" +// normalize-stderr-test "note: compiler flags.*\n\n" -> "" +// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" +// normalize-stderr-test "thread.*panicked.*\n" -> "" +// normalize-stderr-test "stack backtrace:\n" -> "" +// normalize-stderr-test "\s\d{1,}: .*\n" -> "" +// normalize-stderr-test "\s at .*\n" -> "" +// normalize-stderr-test ".*note: Some details.*\n" -> "" +// normalize-stderr-test "\n\n[ ]*\n" -> "" +// normalize-stderr-test "compiler/.*: projection" -> "projection" + +fn main() -> () {} + +async fn foo(x: u32) -> u32 { + x +} diff --git a/tests/ui/chalkify/bugs/async.stderr b/tests/ui/chalkify/bugs/async.stderr new file mode 100644 index 000000000..8043f1e5a --- /dev/null +++ b/tests/ui/chalkify/bugs/async.stderr @@ -0,0 +1,58 @@ +error[E0277]: `[async fn body@$DIR/async.rs:23:29: 25:2]` is not a future + --> $DIR/async.rs:23:29 + | +LL | async fn foo(x: u32) -> u32 { + | _____________________________- +LL | | x +LL | | } + | | ^ + | | | + | |_`[async fn body@$DIR/async.rs:23:29: 25:2]` is not a future + | required by a bound introduced by this call + | + = help: the trait `Future` is not implemented for `[async fn body@$DIR/async.rs:23:29: 25:2]` + = note: [async fn body@$DIR/async.rs:23:29: 25:2] must be a future or must implement `IntoFuture` to be awaited +note: required by a bound in `identity_future` + --> $SRC_DIR/core/src/future/mod.rs:LL:COL + +error[E0277]: the size for values of type `<[async fn body@$DIR/async.rs:23:29: 25:2] as Future>::Output` cannot be known at compilation time + --> $DIR/async.rs:23:29 + | +LL | async fn foo(x: u32) -> u32 { + | _____________________________^ +LL | | x +LL | | } + | |_^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `<[async fn body@$DIR/async.rs:23:29: 25:2] as Future>::Output` +note: required by a bound in `identity_future` + --> $SRC_DIR/core/src/future/mod.rs:LL:COL + +error[E0277]: `[async fn body@$DIR/async.rs:23:29: 25:2]` is not a future + --> $DIR/async.rs:23:25 + | +LL | async fn foo(x: u32) -> u32 { + | ^^^ `[async fn body@$DIR/async.rs:23:29: 25:2]` is not a future + | + = help: the trait `Future` is not implemented for `[async fn body@$DIR/async.rs:23:29: 25:2]` + = note: [async fn body@$DIR/async.rs:23:29: 25:2] must be a future or must implement `IntoFuture` to be awaited + +error: internal compiler error: projection clauses should be implied from elsewhere. obligation: `Obligation(predicate=Binder(ProjectionPredicate(AliasTy { substs: [[async fn body@$DIR/async.rs:23:29: 25:2]], def_id: ...) }, Term::Ty(u32)), []), depth=0)` + --> $DIR/async.rs:23:25 + | +LL | async fn foo(x: u32) -> u32 { + | ^^^query stack during panic: +#0 [typeck] type-checking `foo` +#1 [thir_body] building THIR for `foo` +#2 [mir_built] building MIR for `foo` +#3 [unsafety_check_result] unsafety-checking `foo` +#4 [mir_const] preparing `foo` for borrow checking +#5 [mir_promoted] processing MIR for `foo` +#6 [mir_borrowck] borrow-checking `foo` +#7 [type_of] computing type of `foo::{opaque#0}` +#8 [check_mod_item_types] checking item types in top-level module +#9 [analysis] running analysis passes on this crate +end of query stack +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/chalkify/builtin-copy-clone.rs b/tests/ui/chalkify/builtin-copy-clone.rs new file mode 100644 index 000000000..a478c006e --- /dev/null +++ b/tests/ui/chalkify/builtin-copy-clone.rs @@ -0,0 +1,45 @@ +// run-pass +// compile-flags: -Z trait-solver=chalk + +// Test that `Clone` is correctly implemented for builtin types. + +#[derive(Copy, Clone)] +struct S(#[allow(unused_tuple_struct_fields)] i32); + +fn test_clone<T: Clone>(arg: T) { + let _ = arg.clone(); +} + +fn test_copy<T: Copy>(arg: T) { + let _ = arg; + let _ = arg; +} + +fn test_copy_clone<T: Copy + Clone>(arg: T) { + test_copy(arg); + test_clone(arg); +} + +fn foo() { } + +fn main() { + // FIXME: add closures when they're considered WF + test_copy_clone(foo); + let f: fn() = foo; + test_copy_clone(f); + // FIXME(#86252): reinstate array test after chalk upgrade + //test_copy_clone([1; 56]); + test_copy_clone((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)); + test_copy_clone((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, true, 'a', 1.1)); + test_copy_clone(()); + test_copy_clone(((1, 1), (1, 1, 1), (1.1, 1, 1, 'a'), ())); + + let a = ( + (S(1), S(0)), + ( + (S(0), S(0), S(1)), + S(0) + ) + ); + test_copy_clone(a); +} diff --git a/tests/ui/chalkify/chalk_initial_program.rs b/tests/ui/chalkify/chalk_initial_program.rs new file mode 100644 index 000000000..21de72b6f --- /dev/null +++ b/tests/ui/chalkify/chalk_initial_program.rs @@ -0,0 +1,16 @@ +// compile-flags: -Z trait-solver=chalk + +trait Foo { } + +impl Foo for i32 { } + +impl Foo for u32 { } + +fn gimme<F: Foo>() { } + +// Note: this also tests that `std::process::Termination` is implemented for `()`. +fn main() { + gimme::<i32>(); + gimme::<u32>(); + gimme::<f32>(); //~ERROR the trait bound `f32: Foo` is not satisfied +} diff --git a/tests/ui/chalkify/chalk_initial_program.stderr b/tests/ui/chalkify/chalk_initial_program.stderr new file mode 100644 index 000000000..343c0a318 --- /dev/null +++ b/tests/ui/chalkify/chalk_initial_program.stderr @@ -0,0 +1,18 @@ +error[E0277]: the trait bound `f32: Foo` is not satisfied + --> $DIR/chalk_initial_program.rs:15:13 + | +LL | gimme::<f32>(); + | ^^^ the trait `Foo` is not implemented for `f32` + | + = help: the following other types implement trait `Foo`: + i32 + u32 +note: required by a bound in `gimme` + --> $DIR/chalk_initial_program.rs:9:13 + | +LL | fn gimme<F: Foo>() { } + | ^^^ required by this bound in `gimme` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/chalkify/closure.rs b/tests/ui/chalkify/closure.rs new file mode 100644 index 000000000..a908a1e97 --- /dev/null +++ b/tests/ui/chalkify/closure.rs @@ -0,0 +1,38 @@ +// compile-flags: -Z trait-solver=chalk + +fn main() -> () { + let t = || {}; + t(); + + let mut a = 0; + let mut b = move || { + a = 1; + }; + b(); + + let mut c = b; + + c(); + b(); + + let mut a = 0; + let mut b = || { + a = 1; + }; + b(); + + let mut c = b; + + c(); + b(); //~ ERROR + + // FIXME(chalk): this doesn't quite work + /* + let b = |c| { + c + }; + + let a = &32; + b(a); + */ +} diff --git a/tests/ui/chalkify/closure.stderr b/tests/ui/chalkify/closure.stderr new file mode 100644 index 000000000..a33c0ba0d --- /dev/null +++ b/tests/ui/chalkify/closure.stderr @@ -0,0 +1,22 @@ +error[E0382]: borrow of moved value: `b` + --> $DIR/closure.rs:27:5 + | +LL | let mut c = b; + | - value moved here +... +LL | b(); + | ^ value borrowed here after move + | +note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `a` out of its environment + --> $DIR/closure.rs:20:9 + | +LL | a = 1; + | ^ +help: consider mutably borrowing `b` + | +LL | let mut c = &mut b; + | ++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/chalkify/generic_impls.rs b/tests/ui/chalkify/generic_impls.rs new file mode 100644 index 000000000..7d33e12d8 --- /dev/null +++ b/tests/ui/chalkify/generic_impls.rs @@ -0,0 +1,18 @@ +// compile-flags: -Z trait-solver=chalk + +trait Foo { } + +impl<T> Foo for (T, u32) { } + +fn gimme<F: Foo>() { } + +fn foo<T>() { + gimme::<(T, u32)>(); + gimme::<(Option<T>, u32)>(); + gimme::<(Option<T>, f32)>(); //~ ERROR +} + +fn main() { + gimme::<(i32, u32)>(); + gimme::<(i32, f32)>(); //~ ERROR +} diff --git a/tests/ui/chalkify/generic_impls.stderr b/tests/ui/chalkify/generic_impls.stderr new file mode 100644 index 000000000..d4a8354d3 --- /dev/null +++ b/tests/ui/chalkify/generic_impls.stderr @@ -0,0 +1,29 @@ +error[E0277]: the trait bound `(Option<T>, f32): Foo` is not satisfied + --> $DIR/generic_impls.rs:12:13 + | +LL | gimme::<(Option<T>, f32)>(); + | ^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `(Option<T>, f32)` + | + = help: the trait `Foo` is implemented for `(T, u32)` +note: required by a bound in `gimme` + --> $DIR/generic_impls.rs:7:13 + | +LL | fn gimme<F: Foo>() { } + | ^^^ required by this bound in `gimme` + +error[E0277]: the trait bound `(i32, f32): Foo` is not satisfied + --> $DIR/generic_impls.rs:17:13 + | +LL | gimme::<(i32, f32)>(); + | ^^^^^^^^^^ the trait `Foo` is not implemented for `(i32, f32)` + | + = help: the trait `Foo` is implemented for `(T, u32)` +note: required by a bound in `gimme` + --> $DIR/generic_impls.rs:7:13 + | +LL | fn gimme<F: Foo>() { } + | ^^^ required by this bound in `gimme` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/chalkify/impl_wf.rs b/tests/ui/chalkify/impl_wf.rs new file mode 100644 index 000000000..c8dfd4c3a --- /dev/null +++ b/tests/ui/chalkify/impl_wf.rs @@ -0,0 +1,26 @@ +// compile-flags: -Z trait-solver=chalk + +trait Foo: Sized { } + +trait Bar { + type Item: Foo; +} + +impl Foo for i32 { } + +impl Foo for str { } +//~^ ERROR the size for values of type `str` cannot be known at compilation time + + +// Implicit `T: Sized` bound. +impl<T> Foo for Option<T> { } + +trait Baz<U: ?Sized> where U: Foo { } + +impl Baz<i32> for i32 { } + +impl Baz<f32> for f32 { } +//~^ ERROR the trait bound `f32: Foo` is not satisfied + +fn main() { +} diff --git a/tests/ui/chalkify/impl_wf.stderr b/tests/ui/chalkify/impl_wf.stderr new file mode 100644 index 000000000..84c32fa37 --- /dev/null +++ b/tests/ui/chalkify/impl_wf.stderr @@ -0,0 +1,29 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/impl_wf.rs:11:14 + | +LL | impl Foo for str { } + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` +note: required by a bound in `Foo` + --> $DIR/impl_wf.rs:3:12 + | +LL | trait Foo: Sized { } + | ^^^^^ required by this bound in `Foo` + +error[E0277]: the trait bound `f32: Foo` is not satisfied + --> $DIR/impl_wf.rs:22:19 + | +LL | impl Baz<f32> for f32 { } + | ^^^ the trait `Foo` is not implemented for `f32` + | + = help: the trait `Foo` is implemented for `i32` +note: required by a bound in `Baz` + --> $DIR/impl_wf.rs:18:31 + | +LL | trait Baz<U: ?Sized> where U: Foo { } + | ^^^ required by this bound in `Baz` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/chalkify/impl_wf_2.rs b/tests/ui/chalkify/impl_wf_2.rs new file mode 100644 index 000000000..325044ad6 --- /dev/null +++ b/tests/ui/chalkify/impl_wf_2.rs @@ -0,0 +1,33 @@ +// Split out of impl_wf.rs to work around rust aborting compilation early + +// compile-flags: -Z trait-solver=chalk + +trait Foo: Sized { } + +trait Bar { + type Item: Foo; +} + +impl Foo for i32 { } + +// Implicit `T: Sized` bound. +impl<T> Foo for Option<T> { } + +impl Bar for () { + type Item = i32; +} + +impl<T> Bar for Option<T> { + type Item = Option<T>; +} + +impl Bar for f32 { + type Item = f32; + //~^ ERROR the trait bound `f32: Foo` is not satisfied +} + +trait Baz<U: ?Sized> where U: Foo { } + +impl Baz<i32> for i32 { } + +fn main() {} diff --git a/tests/ui/chalkify/impl_wf_2.stderr b/tests/ui/chalkify/impl_wf_2.stderr new file mode 100644 index 000000000..1c1df644b --- /dev/null +++ b/tests/ui/chalkify/impl_wf_2.stderr @@ -0,0 +1,16 @@ +error[E0277]: the trait bound `f32: Foo` is not satisfied + --> $DIR/impl_wf_2.rs:25:17 + | +LL | type Item = f32; + | ^^^ the trait `Foo` is not implemented for `f32` + | + = help: the trait `Foo` is implemented for `i32` +note: required by a bound in `Bar::Item` + --> $DIR/impl_wf_2.rs:8:16 + | +LL | type Item: Foo; + | ^^^ required by this bound in `Bar::Item` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/chalkify/inherent_impl.rs b/tests/ui/chalkify/inherent_impl.rs new file mode 100644 index 000000000..f0f24d485 --- /dev/null +++ b/tests/ui/chalkify/inherent_impl.rs @@ -0,0 +1,42 @@ +// run-pass +// compile-flags: -Z trait-solver=chalk + +trait Foo { } + +impl Foo for i32 { } + +struct S<T: Foo> { + x: T, +} + +fn only_foo<T: Foo>(_x: &T) { } + +impl<T> S<T> { + // Test that we have the correct environment inside an inherent method. + fn dummy_foo(&self) { + only_foo(&self.x) + } +} + +trait Bar { } +impl Bar for u32 { } + +fn only_bar<T: Bar>() { } + +impl<T> S<T> { + // Test that the environment of `dummy_bar` adds up with the environment + // of the inherent impl. + fn dummy_bar<U: Bar>(&self) { + only_foo(&self.x); + only_bar::<U>(); + } +} + +fn main() { + let s = S { + x: 5, + }; + + s.dummy_bar::<u32>(); + s.dummy_foo(); +} diff --git a/tests/ui/chalkify/inherent_impl_min.rs b/tests/ui/chalkify/inherent_impl_min.rs new file mode 100644 index 000000000..3eda7102d --- /dev/null +++ b/tests/ui/chalkify/inherent_impl_min.rs @@ -0,0 +1,27 @@ +// run-pass +// compile-flags: -Z trait-solver=chalk + +trait Foo { } + +impl Foo for i32 { } + +struct S<T: Foo> { + x: T, +} + +fn only_foo<T: Foo>(_x: &T) { } + +impl<T> S<T> { + // Test that we have the correct environment inside an inherent method. + fn dummy_foo(&self) { + only_foo(&self.x) + } +} + +fn main() { + let s = S { + x: 5, + }; + + s.dummy_foo(); +} diff --git a/tests/ui/chalkify/lower_env1.rs b/tests/ui/chalkify/lower_env1.rs new file mode 100644 index 000000000..c8762001e --- /dev/null +++ b/tests/ui/chalkify/lower_env1.rs @@ -0,0 +1,14 @@ +// check-pass +// compile-flags: -Z trait-solver=chalk + +#![allow(dead_code)] + +trait Foo { } + +trait Bar where Self: Foo { } + +fn bar<T: Bar + ?Sized>() { +} + +fn main() { +} diff --git a/tests/ui/chalkify/lower_env2.rs b/tests/ui/chalkify/lower_env2.rs new file mode 100644 index 000000000..7d4f81f12 --- /dev/null +++ b/tests/ui/chalkify/lower_env2.rs @@ -0,0 +1,16 @@ +// check-pass +// compile-flags: -Z trait-solver=chalk + +#![allow(dead_code)] + +trait Foo { } + +struct S<'a, T: ?Sized> where T: Foo { + data: &'a T, +} + +fn bar<T: Foo>(_x: S<'_, T>) { // note that we have an implicit `T: Sized` bound +} + +fn main() { +} diff --git a/tests/ui/chalkify/lower_env3.rs b/tests/ui/chalkify/lower_env3.rs new file mode 100644 index 000000000..5b70c4abb --- /dev/null +++ b/tests/ui/chalkify/lower_env3.rs @@ -0,0 +1,16 @@ +// check-pass +// compile-flags: -Z trait-solver=chalk + +#![allow(dead_code)] + +trait Foo { + fn foo(&self); +} + +impl<T> Foo for T where T: Clone { + fn foo(&self) { + } +} + +fn main() { +} diff --git a/tests/ui/chalkify/lower_impl.rs b/tests/ui/chalkify/lower_impl.rs new file mode 100644 index 000000000..6f79b3ba3 --- /dev/null +++ b/tests/ui/chalkify/lower_impl.rs @@ -0,0 +1,17 @@ +// check-pass +// compile-flags: -Z trait-solver=chalk + +trait Foo { } + +impl<T: 'static> Foo for T where T: Iterator<Item = i32> { } + +trait Bar { + type Assoc; +} + +impl<T> Bar for T where T: Iterator<Item = i32> { + type Assoc = Vec<T>; +} + +fn main() { +} diff --git a/tests/ui/chalkify/lower_struct.rs b/tests/ui/chalkify/lower_struct.rs new file mode 100644 index 000000000..6be0d4dd5 --- /dev/null +++ b/tests/ui/chalkify/lower_struct.rs @@ -0,0 +1,8 @@ +// check-pass +// compile-flags: -Z trait-solver=chalk + +struct Foo<'a, T> where Box<T>: Clone { + _x: std::marker::PhantomData<&'a T>, +} + +fn main() { } diff --git a/tests/ui/chalkify/lower_trait.rs b/tests/ui/chalkify/lower_trait.rs new file mode 100644 index 000000000..8f5b35822 --- /dev/null +++ b/tests/ui/chalkify/lower_trait.rs @@ -0,0 +1,11 @@ +// check-pass +// compile-flags: -Z trait-solver=chalk + +trait Bar { } + +trait Foo<S, T: ?Sized> { + type Assoc: Bar + ?Sized; +} + +fn main() { +} diff --git a/tests/ui/chalkify/lower_trait_higher_rank.rs b/tests/ui/chalkify/lower_trait_higher_rank.rs new file mode 100644 index 000000000..f04a1deea --- /dev/null +++ b/tests/ui/chalkify/lower_trait_higher_rank.rs @@ -0,0 +1,9 @@ +// check-pass +// compile-flags: -Z trait-solver=chalk + +trait Foo<F: ?Sized> where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8 +{ +} + +fn main() { +} diff --git a/tests/ui/chalkify/lower_trait_where_clause.rs b/tests/ui/chalkify/lower_trait_where_clause.rs new file mode 100644 index 000000000..a21d2f319 --- /dev/null +++ b/tests/ui/chalkify/lower_trait_where_clause.rs @@ -0,0 +1,16 @@ +// check-pass +// compile-flags: -Z trait-solver=chalk + +use std::borrow::Borrow; + +trait Foo<'a, 'b, T, U> +where + T: Borrow<U> + ?Sized, + U: ?Sized + 'b, + 'a: 'b, + Box<T>:, // NOTE(#53696) this checks an empty list of bounds. +{ +} + +fn main() { +} diff --git a/tests/ui/chalkify/println.rs b/tests/ui/chalkify/println.rs new file mode 100644 index 000000000..edddc3821 --- /dev/null +++ b/tests/ui/chalkify/println.rs @@ -0,0 +1,6 @@ +// check-pass +// compile-flags: -Z trait-solver=chalk + +fn main() { + println!("hello"); +} diff --git a/tests/ui/chalkify/projection.rs b/tests/ui/chalkify/projection.rs new file mode 100644 index 000000000..19bb2ae14 --- /dev/null +++ b/tests/ui/chalkify/projection.rs @@ -0,0 +1,25 @@ +// run-pass +// compile-flags: -Z trait-solver=chalk + +trait Foo { } + +trait Bar { + type Item: Foo; +} + +impl Foo for i32 { } +impl Bar for i32 { + type Item = i32; +} + +fn only_foo<T: Foo>() { } + +fn only_bar<T: Bar>() { + // `T` implements `Bar` hence `<T as Bar>::Item` must also implement `Bar` + only_foo::<T::Item>() +} + +fn main() { + only_bar::<i32>(); + only_foo::<<i32 as Bar>::Item>(); +} diff --git a/tests/ui/chalkify/recursive_where_clause_on_type.rs b/tests/ui/chalkify/recursive_where_clause_on_type.rs new file mode 100644 index 000000000..c2c8aa6aa --- /dev/null +++ b/tests/ui/chalkify/recursive_where_clause_on_type.rs @@ -0,0 +1,30 @@ +// FIXME(chalk): should fail, see comments +// check-fail +// compile-flags: -Z trait-solver=chalk + +#![feature(trivial_bounds)] + +trait Bar { + fn foo(); +} +trait Foo: Bar { } + +struct S where S: Foo; + +impl Foo for S { +} + +fn bar<T: Bar>() { + T::foo(); +} + +fn foo<T: Foo>() { + bar::<T>() +} + +fn main() { + // For some reason, the error is duplicated... + + foo::<S>() //~ ERROR the type `S` is not well-formed + //~^ ERROR the type `S` is not well-formed +} diff --git a/tests/ui/chalkify/recursive_where_clause_on_type.stderr b/tests/ui/chalkify/recursive_where_clause_on_type.stderr new file mode 100644 index 000000000..cead5adea --- /dev/null +++ b/tests/ui/chalkify/recursive_where_clause_on_type.stderr @@ -0,0 +1,14 @@ +error: the type `S` is not well-formed + --> $DIR/recursive_where_clause_on_type.rs:28:11 + | +LL | foo::<S>() + | ^ + +error: the type `S` is not well-formed + --> $DIR/recursive_where_clause_on_type.rs:28:5 + | +LL | foo::<S>() + | ^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/chalkify/super_trait.rs b/tests/ui/chalkify/super_trait.rs new file mode 100644 index 000000000..540ae51e5 --- /dev/null +++ b/tests/ui/chalkify/super_trait.rs @@ -0,0 +1,19 @@ +// run-pass +// compile-flags: -Z trait-solver=chalk + +trait Foo { } +trait Bar: Foo { } + +impl Foo for i32 { } +impl Bar for i32 { } + +fn only_foo<T: Foo>() { } + +fn only_bar<T: Bar>() { + // `T` implements `Bar` hence `T` must also implement `Foo` + only_foo::<T>() +} + +fn main() { + only_bar::<i32>() +} diff --git a/tests/ui/chalkify/trait-objects.rs b/tests/ui/chalkify/trait-objects.rs new file mode 100644 index 000000000..144d9788b --- /dev/null +++ b/tests/ui/chalkify/trait-objects.rs @@ -0,0 +1,12 @@ +// check-pass +// compile-flags: -Z trait-solver=chalk + +use std::fmt::Display; + +fn main() { + let d: &dyn Display = &mut 3; + d.to_string(); + (&d).to_string(); + let f: &dyn Fn(i32) -> _ = &|x| x + x; + f(2); +} diff --git a/tests/ui/chalkify/trait_implied_bound.rs b/tests/ui/chalkify/trait_implied_bound.rs new file mode 100644 index 000000000..f97dbf6b7 --- /dev/null +++ b/tests/ui/chalkify/trait_implied_bound.rs @@ -0,0 +1,18 @@ +// run-pass +// compile-flags: -Z trait-solver=chalk + +trait Foo { } +trait Bar<U> where U: Foo { } + +impl Foo for i32 { } +impl Bar<i32> for i32 { } + +fn only_foo<T: Foo>() { } + +fn only_bar<U, T: Bar<U>>() { + only_foo::<U>() +} + +fn main() { + only_bar::<i32, i32>() +} diff --git a/tests/ui/chalkify/type_implied_bound.rs b/tests/ui/chalkify/type_implied_bound.rs new file mode 100644 index 000000000..70f1b4265 --- /dev/null +++ b/tests/ui/chalkify/type_implied_bound.rs @@ -0,0 +1,29 @@ +// run-pass +// compile-flags: -Z trait-solver=chalk + +trait Eq { } +trait Hash: Eq { } + +impl Eq for i32 { } +impl Hash for i32 { } + +struct Set<T: Hash> { + _x: T, +} + +fn only_eq<T: Eq>() { } + +fn take_a_set<T>(_: &Set<T>) { + // `Set<T>` is an input type of `take_a_set`, hence we know that + // `T` must implement `Hash`, and we know in turn that `T` must + // implement `Eq`. + only_eq::<T>() +} + +fn main() { + let set = Set { + _x: 5, + }; + + take_a_set(&set); +} diff --git a/tests/ui/chalkify/type_inference.rs b/tests/ui/chalkify/type_inference.rs new file mode 100644 index 000000000..d7167d0dc --- /dev/null +++ b/tests/ui/chalkify/type_inference.rs @@ -0,0 +1,28 @@ +// compile-flags: -Z trait-solver=chalk + +trait Foo { } +impl Foo for i32 { } + +trait Bar { } +impl Bar for i32 { } +impl Bar for u32 { } + +fn only_foo<T: Foo>(_x: T) { } + +fn only_bar<T: Bar>(_x: T) { } + +fn main() { + let x = 5.0; + + // The only type which implements `Foo` is `i32`, so the chalk trait solver + // is expecting a variable of type `i32`. This behavior differs from the + // old-style trait solver. I guess this will change, that's why I'm + // adding that test. + // FIXME(chalk): order of these two errors is non-deterministic, + // so let's just hide one for now + //only_foo(x); // ERROR the trait bound `f64: Foo` is not satisfied + + // Here we have two solutions so we get back the behavior of the old-style + // trait solver. + only_bar(x); //~ ERROR the trait bound `{float}: Bar` is not satisfied +} diff --git a/tests/ui/chalkify/type_inference.stderr b/tests/ui/chalkify/type_inference.stderr new file mode 100644 index 000000000..508a6dd13 --- /dev/null +++ b/tests/ui/chalkify/type_inference.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `{float}: Bar` is not satisfied + --> $DIR/type_inference.rs:27:14 + | +LL | only_bar(x); + | -------- ^ the trait `Bar` is not implemented for `{float}` + | | + | required by a bound introduced by this call + | + = help: the following other types implement trait `Bar`: + i32 + u32 +note: required by a bound in `only_bar` + --> $DIR/type_inference.rs:12:16 + | +LL | fn only_bar<T: Bar>(_x: T) { } + | ^^^ required by this bound in `only_bar` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/chalkify/type_wf.rs b/tests/ui/chalkify/type_wf.rs new file mode 100644 index 000000000..37d2f5ca8 --- /dev/null +++ b/tests/ui/chalkify/type_wf.rs @@ -0,0 +1,25 @@ +// check-fail +// compile-flags: -Z trait-solver=chalk + +trait Foo { } + +struct S<T: Foo> { + x: T, +} + +impl Foo for i32 { } +impl<T> Foo for Option<T> { } + +fn main() { + let s = S { + x: 5, + }; + + let s = S { + x: 5.0, //~ ERROR the trait bound `{float}: Foo` is not satisfied + }; + + let s = S { + x: Some(5.0), + }; +} diff --git a/tests/ui/chalkify/type_wf.stderr b/tests/ui/chalkify/type_wf.stderr new file mode 100644 index 000000000..6e8daf635 --- /dev/null +++ b/tests/ui/chalkify/type_wf.stderr @@ -0,0 +1,16 @@ +error[E0277]: the trait bound `{float}: Foo` is not satisfied + --> $DIR/type_wf.rs:19:12 + | +LL | x: 5.0, + | ^^^ the trait `Foo` is not implemented for `{float}` + | + = help: the trait `Foo` is implemented for `i32` +note: required by a bound in `S` + --> $DIR/type_wf.rs:6:13 + | +LL | struct S<T: Foo> { + | ^^^ required by this bound in `S` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. |