From 93e29823a9eb8de01c33fe48e9f47caf822a2fda Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 5 Jun 2020 21:14:34 +0000 Subject: [PATCH] add new coherence tests and update the documentation --- .../coherence-fn-covariant-bound-vs-static.rs | 26 +++++++++++++++++++ ...erence-fn-covariant-bound-vs-static.stderr | 13 ++++++++++ .../coherence/coherence-fn-implied-bounds.rs | 14 +++++++++- src/test/ui/coherence/coherence-fn-inputs.rs | 2 -- .../ui/coherence/coherence-fn-inputs.stderr | 2 +- 5 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.rs create mode 100644 src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr diff --git a/src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.rs b/src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.rs new file mode 100644 index 0000000000000..99f805f7f0f63 --- /dev/null +++ b/src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.rs @@ -0,0 +1,26 @@ +// Test that impls for these two types are considered ovelapping: +// +// * `for<'r> fn(fn(&'r u32))` +// * `fn(fn(&'a u32)` where `'a` is free +// +// This is because, for `'a = 'static`, the two types overlap. +// Effectively for them to be equal to you get: +// +// * `for<'r> fn(fn(&'r u32)) <: fn(fn(&'static u32))` +// * true if `exists<'r> { 'r: 'static }` (obviously true) +// * `fn(fn(&'static u32)) <: for<'r> fn(fn(&'r u32))` +// * true if `forall<'r> { 'static: 'r }` (also true) + +trait Trait {} + +impl Trait for for<'r> fn(fn(&'r ())) {} +impl<'a> Trait for fn(fn(&'a ())) {} +//~^ ERROR conflicting implementations +// +// Note in particular that we do NOT get a future-compatibility warning +// here. This is because the new leak-check proposed in [MCP 295] does not +// "error" when these two types are equated. +// +// [MCP 295]: https://github.com/rust-lang/compiler-team/issues/295 + +fn main() {} diff --git a/src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr b/src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr new file mode 100644 index 0000000000000..1f3a18c7fad9a --- /dev/null +++ b/src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr @@ -0,0 +1,13 @@ +error[E0119]: conflicting implementations of trait `Trait` for type `for<'r> fn(fn(&'r ()))`: + --> $DIR/coherence-fn-covariant-bound-vs-static.rs:14:1 + | +LL | impl Trait for for<'r> fn(fn(&'r ())) {} + | ------------------------------------- first implementation here +LL | impl<'a> Trait for fn(fn(&'a ())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'r> fn(fn(&'r ()))` + | + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-fn-implied-bounds.rs b/src/test/ui/coherence/coherence-fn-implied-bounds.rs index ba89a072f3441..4539af9a32e38 100644 --- a/src/test/ui/coherence/coherence-fn-implied-bounds.rs +++ b/src/test/ui/coherence/coherence-fn-implied-bounds.rs @@ -1,4 +1,16 @@ -// Example of coherence impls that we accept +// Test that our leak-check is not smart enough to take implied bounds +// into account (yet). Here we have two types that look like they +// should not be equivalent, but because of the rules on implied +// bounds we ought to know that, in fact, `'a = 'b` must always hold, +// and hence they are. +// +// Rustc can't figure this out and hence it accepts the impls but +// gives a future-compatibility warning (because we'd like to make +// this an error someday). +// +// Note that while we would like to make this a hard error, we also +// give the same warning for `coherence-wasm-bindgen.rs`, which ought +// to be accepted. #![deny(coherence_leak_check)] diff --git a/src/test/ui/coherence/coherence-fn-inputs.rs b/src/test/ui/coherence/coherence-fn-inputs.rs index 8c10899304127..3afec5c5459af 100644 --- a/src/test/ui/coherence/coherence-fn-inputs.rs +++ b/src/test/ui/coherence/coherence-fn-inputs.rs @@ -10,8 +10,6 @@ // * `'c` can be the intersection of `'a` and `'b` (and there is always an intersection) // * `'a` and `'b` can both be equal to `'c` -#![deny(coherence_leak_check)] - trait Trait {} impl Trait for for<'a, 'b> fn(&'a u32, &'b u32) {} impl Trait for for<'c> fn(&'c u32, &'c u32) { diff --git a/src/test/ui/coherence/coherence-fn-inputs.stderr b/src/test/ui/coherence/coherence-fn-inputs.stderr index a80357526e09d..56ab873a39320 100644 --- a/src/test/ui/coherence/coherence-fn-inputs.stderr +++ b/src/test/ui/coherence/coherence-fn-inputs.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait` for type `for<'a, 'b> fn(&'a u32, &'b u32)`: - --> $DIR/coherence-fn-inputs.rs:17:1 + --> $DIR/coherence-fn-inputs.rs:15:1 | LL | impl Trait for for<'a, 'b> fn(&'a u32, &'b u32) {} | ----------------------------------------------- first implementation here