diff options
| author | bors <bors@rust-lang.org> | 2017-11-17 22:16:11 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-11-17 22:16:11 +0000 |
| commit | 18d8acf41d21c19eedcb732d161ae943c438fd57 (patch) | |
| tree | d0ea741999f6186f0926448d7a6812a58c8cd38c /src/test | |
| parent | aabfed5e0c84211005c1cb2ecec2206a574a5146 (diff) | |
| parent | 9877fa048d66e7181a87de889768a67ea5ea3cd4 (diff) | |
| download | rust-18d8acf41d21c19eedcb732d161ae943c438fd57.tar.gz rust-18d8acf41d21c19eedcb732d161ae943c438fd57.zip | |
Auto merge of #45853 - nikomatsakis:chalk-simplify-hr-lub-glb, r=arielb1
Simplify higher-ranked LUB/GLB This is a better version of https://github.com/rust-lang/rust/pull/44211. It still makes higher-ranked LUB/GLB into a hard equality test, however, it does try to identify that something changed and issue a notice to the user. I wroteup https://github.com/rust-lang/rust/issues/45852 as a tracking issue for this change. Currently, this moves straight to a hard-error, on the basis that the crater run in #44211 saw no impact. It might be good to retest -- or perhaps to try for a warning period. Trying to do the latter in a precise way would be somewhat painful, but an imprecise way might suffice -- that is, we could issue warning *whenever* a LUB/GLB operation succeeds that will later fail, even if it doesn't ultimately impact the type check. I could experiment with this. ~~I am *mildly* wary about landing this independently of other code that moves to a universe-based system. In particular, I was nervous that this change would make coherence accepts new pairs of impls that will later be errors. I have the code for the universe-based approach available, I hope to open an PR and run some tests on its impact very shortly.~~ @arielb1 points out that I was being silly. r? @arielb1
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/run-pass/lub-glb-with-unbound-infer-var.rs | 24 | ||||
| -rw-r--r-- | src/test/ui/lub-glb/old-lub-glb-hr.rs | 36 | ||||
| -rw-r--r-- | src/test/ui/lub-glb/old-lub-glb-hr.stderr | 22 | ||||
| -rw-r--r-- | src/test/ui/lub-glb/old-lub-glb-object.rs | 38 | ||||
| -rw-r--r-- | src/test/ui/lub-glb/old-lub-glb-object.stderr | 22 |
5 files changed, 142 insertions, 0 deletions
diff --git a/src/test/run-pass/lub-glb-with-unbound-infer-var.rs b/src/test/run-pass/lub-glb-with-unbound-infer-var.rs new file mode 100644 index 00000000000..6b9bd67f9a5 --- /dev/null +++ b/src/test/run-pass/lub-glb-with-unbound-infer-var.rs @@ -0,0 +1,24 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test for a specific corner case: when we compute the LUB of two fn +// types and their parameters have unbound variables. In that case, we +// wind up relating those two variables. This was causing an ICE in an +// in-progress PR. + +fn main() { + let a_f: fn(_) = |_| (); + let b_f: fn(_) = |_| (); + let c_f = match 22 { + 0 => a_f, + _ => b_f, + }; + c_f(4); +} diff --git a/src/test/ui/lub-glb/old-lub-glb-hr.rs b/src/test/ui/lub-glb/old-lub-glb-hr.rs new file mode 100644 index 00000000000..85c90bb375f --- /dev/null +++ b/src/test/ui/lub-glb/old-lub-glb-hr.rs @@ -0,0 +1,36 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that we give a note when the old LUB/GLB algorithm would have +// succeeded but the new code (which is stricter) gives an error. + +fn foo( + x: fn(&u8, &u8), + y: for<'a> fn(&'a u8, &'a u8), +) { + let z = match 22 { + 0 => x, + _ => y, + }; +} + +fn bar( + x: fn(&u8, &u8), + y: for<'a> fn(&'a u8, &'a u8), +) { + let z = match 22 { + // No error with an explicit cast: + 0 => x as for<'a> fn(&'a u8, &'a u8), + _ => y, + }; +} + +fn main() { +} diff --git a/src/test/ui/lub-glb/old-lub-glb-hr.stderr b/src/test/ui/lub-glb/old-lub-glb-hr.stderr new file mode 100644 index 00000000000..4a310a5e6b2 --- /dev/null +++ b/src/test/ui/lub-glb/old-lub-glb-hr.stderr @@ -0,0 +1,22 @@ +error[E0308]: match arms have incompatible types + --> $DIR/old-lub-glb-hr.rs:18:13 + | +18 | let z = match 22 { + | _____________^ +19 | | 0 => x, +20 | | _ => y, +21 | | }; + | |_____^ expected bound lifetime parameter, found concrete lifetime + | + = note: expected type `for<'r, 's> fn(&'r u8, &'s u8)` + found type `for<'a> fn(&'a u8, &'a u8)` + = note: this was previously accepted by the compiler but has been phased out + = note: for more information, see https://github.com/rust-lang/rust/issues/45852 +note: match arm with an incompatible type + --> $DIR/old-lub-glb-hr.rs:20:14 + | +20 | _ => y, + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/lub-glb/old-lub-glb-object.rs b/src/test/ui/lub-glb/old-lub-glb-object.rs new file mode 100644 index 00000000000..7cf89b68be1 --- /dev/null +++ b/src/test/ui/lub-glb/old-lub-glb-object.rs @@ -0,0 +1,38 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that we give a note when the old LUB/GLB algorithm would have +// succeeded but the new code (which is stricter) gives an error. + +trait Foo<T, U> { } + +fn foo( + x: &for<'a, 'b> Foo<&'a u8, &'b u8>, + y: &for<'a> Foo<&'a u8, &'a u8>, +) { + let z = match 22 { + 0 => x, + _ => y, + }; +} + +fn bar( + x: &for<'a, 'b> Foo<&'a u8, &'b u8>, + y: &for<'a> Foo<&'a u8, &'a u8>, +) { + // Accepted with explicit case: + let z = match 22 { + 0 => x as &for<'a> Foo<&'a u8, &'a u8>, + _ => y, + }; +} + +fn main() { +} diff --git a/src/test/ui/lub-glb/old-lub-glb-object.stderr b/src/test/ui/lub-glb/old-lub-glb-object.stderr new file mode 100644 index 00000000000..a1077f40bf5 --- /dev/null +++ b/src/test/ui/lub-glb/old-lub-glb-object.stderr @@ -0,0 +1,22 @@ +error[E0308]: match arms have incompatible types + --> $DIR/old-lub-glb-object.rs:20:13 + | +20 | let z = match 22 { + | _____________^ +21 | | 0 => x, +22 | | _ => y, +23 | | }; + | |_____^ expected bound lifetime parameter 'a, found concrete lifetime + | + = note: expected type `&for<'a, 'b> Foo<&'a u8, &'b u8>` + found type `&for<'a> Foo<&'a u8, &'a u8>` + = note: this was previously accepted by the compiler but has been phased out + = note: for more information, see https://github.com/rust-lang/rust/issues/45852 +note: match arm with an incompatible type + --> $DIR/old-lub-glb-object.rs:22:14 + | +22 | _ => y, + | ^ + +error: aborting due to previous error + |
