diff options
| author | bors <bors@rust-lang.org> | 2019-02-20 21:12:18 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-02-20 21:12:18 +0000 |
| commit | 1349c84a4fa0fca9b866b2e859d28ee185ca0c1b (patch) | |
| tree | 8276b142700103e31a1fc7e74bb1a71a71df4a73 /src/test | |
| parent | f66e4697ae286985ddefc53c3a047614568458bb (diff) | |
| parent | 9661ee6af47b39bc4c355b6aea2d0ebb14d203b8 (diff) | |
Auto merge of #58056 - nikomatsakis:issue-57843-universe-leak, r=pnkfelix
make generalization code create new variables in correct universe In our type inference system, when we "generalize" a type T to become a suitable value for a type variable V, we sometimes wind up creating new inference variables. So, for example, if we are making V be some subtype of `&'X u32`, then we might instantiate V with `&'Y u32`. This generalized type is then related `&'Y u32 <: &'X u32`, resulting in a region constriant `'Y: 'X`. Previously, however, we were making these fresh variables like `'Y` in the "current universe", but they should be created in the universe of V. Moreover, we sometimes cheat in an invariant context and avoid creating fresh variables if we know the result must be equal -- we can only do that when the universes work out. Fixes #57843 r? @pnkfelix
Diffstat (limited to 'src/test')
10 files changed, 60 insertions, 24 deletions
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr index 46901b44c4b..fa831ea81dc 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr @@ -9,15 +9,15 @@ LL | let a = bar(foo, y); //[krisskross]~ ERROR E0623 | ^ ...but data from `x` is returned here error[E0623]: lifetime mismatch - --> $DIR/project-fn-ret-invariant.rs:55:8 + --> $DIR/project-fn-ret-invariant.rs:54:21 | LL | fn transmute<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) { - | -------- -------------------- - | | - | this parameter and the return type are declared with different lifetimes... -... -LL | (a, b) //[krisskross]~ ERROR E0623 - | ^ ...but data from `x` is returned here + | -------- -------------------- + | | + | this parameter and the return type are declared with different lifetimes... +LL | let a = bar(foo, y); //[krisskross]~ ERROR E0623 +LL | let b = bar(foo, x); //[krisskross]~ ERROR E0623 + | ^ ...but data from `y` is returned here error: aborting due to 2 previous errors diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs b/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs index dfcf31b3b1f..54b6e3642c2 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs @@ -51,8 +51,8 @@ fn baz<'a,'b>(x: Type<'a>) -> Type<'static> { #[cfg(krisskross)] // two instantiations, mixing and matching: BAD fn transmute<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) { let a = bar(foo, y); //[krisskross]~ ERROR E0623 - let b = bar(foo, x); - (a, b) //[krisskross]~ ERROR E0623 + let b = bar(foo, x); //[krisskross]~ ERROR E0623 + (a, b) } #[rustc_error] diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr index 947844c45c4..dd1212eaac9 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr @@ -1,4 +1,4 @@ -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements +error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements --> $DIR/project-fn-ret-invariant.rs:48:8 | LL | bar(foo, x) //[transmute]~ ERROR E0495 diff --git a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr index 3bbf48cb37f..811c9a8f5e1 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr +++ b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr @@ -1,12 +1,12 @@ -error: implementation of `Mirror` is not general enough +error[E0308]: mismatched types --> $DIR/higher-ranked-projection.rs:25:5 | LL | foo(()); - | ^^^ + | ^^^ one type is more general than the other | - = note: Due to a where-clause on `foo`, - = note: `Mirror` would have to be implemented for the type `&'0 ()`, for any lifetime `'0` - = note: but `Mirror` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` + = note: expected type `&'a ()` + found type `&()` error: aborting due to previous error +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/associated-types/higher-ranked-projection.good.stderr b/src/test/ui/associated-types/higher-ranked-projection.good.stderr index c5c8451a5a9..92fd2562858 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.good.stderr +++ b/src/test/ui/associated-types/higher-ranked-projection.good.stderr @@ -3,7 +3,7 @@ error: compilation successful | LL | / fn main() { //[good]~ ERROR compilation successful LL | | foo(()); -LL | | //[bad]~^ ERROR not general enough +LL | | //[bad]~^ ERROR mismatched types LL | | } | |_^ diff --git a/src/test/ui/associated-types/higher-ranked-projection.rs b/src/test/ui/associated-types/higher-ranked-projection.rs index 1280c8cb4cb..fd7252f9e22 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.rs +++ b/src/test/ui/associated-types/higher-ranked-projection.rs @@ -23,5 +23,5 @@ fn foo<U, T>(_t: T) #[rustc_error] fn main() { //[good]~ ERROR compilation successful foo(()); - //[bad]~^ ERROR not general enough + //[bad]~^ ERROR mismatched types } diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.rs b/src/test/ui/hrtb/hrtb-perfect-forwarding.rs index 0094091c6bd..63db695f7e6 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.rs +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.rs @@ -43,7 +43,7 @@ fn foo_hrtb_bar_not<'b,T>(mut t: T) // be implemented. Thus to satisfy `&mut T : for<'a> Foo<&'a // isize>`, we require `T : for<'a> Bar<&'a isize>`, but the where // clause only specifies `T : Bar<&'b isize>`. - foo_hrtb_bar_not(&mut t); //~ ERROR not general enough + foo_hrtb_bar_not(&mut t); //~ ERROR mismatched types } fn foo_hrtb_bar_hrtb<T>(mut t: T) diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr index c7be3790aa1..ea08af01640 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr @@ -1,12 +1,12 @@ -error: implementation of `Foo` is not general enough +error[E0308]: mismatched types --> $DIR/hrtb-perfect-forwarding.rs:46:5 | -LL | foo_hrtb_bar_not(&mut t); //~ ERROR not general enough - | ^^^^^^^^^^^^^^^^ +LL | foo_hrtb_bar_not(&mut t); //~ ERROR mismatched types + | ^^^^^^^^^^^^^^^^ one type is more general than the other | - = note: Due to a where-clause on `foo_hrtb_bar_not`, - = note: `&mut T` must implement `Foo<&'0 isize>`, for any lifetime `'0` - = note: but `&mut T` actually implements `Foo<&'1 isize>`, for some specific lifetime `'1` + = note: expected type `Bar<&'a isize>` + found type `Bar<&'b isize>` error: aborting due to previous error +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issues/issue-57843.rs b/src/test/ui/issues/issue-57843.rs new file mode 100644 index 00000000000..46608255266 --- /dev/null +++ b/src/test/ui/issues/issue-57843.rs @@ -0,0 +1,24 @@ +// Regression test for an ICE that occurred with the universes code: +// +// The signature of the closure `|_|` was being inferred to +// `exists<'r> fn(&'r u8)`. This should result in a type error since +// the signature `for<'r> fn(&'r u8)` is required. However, due to a +// bug in the type variable generalization code, the placeholder for +// `'r` was leaking out into the writeback phase, causing an ICE. + +trait ClonableFn<T> { + fn clone(&self) -> Box<dyn Fn(T)>; +} + +impl<T, F: 'static> ClonableFn<T> for F +where F: Fn(T) + Clone { + fn clone(&self) -> Box<dyn Fn(T)> { + Box::new(self.clone()) + } +} + +struct Foo(Box<dyn for<'a> ClonableFn<&'a bool>>); + +fn main() { + Foo(Box::new(|_| ())); //~ ERROR mismatched types +} diff --git a/src/test/ui/issues/issue-57843.stderr b/src/test/ui/issues/issue-57843.stderr new file mode 100644 index 00000000000..4ef884cb3f5 --- /dev/null +++ b/src/test/ui/issues/issue-57843.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/issue-57843.rs:23:9 + | +LL | Foo(Box::new(|_| ())); //~ ERROR mismatched types + | ^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected type `std::ops::FnOnce<(&'a bool,)>` + found type `std::ops::FnOnce<(&bool,)>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. |
