make ascribe_user_type a TypeOp
Projection types in user annotations may contain inference variables. This makes the normalization depend on the unification with the actual type and thus requires a separate TypeOp to track the obligations. Otherwise simply calling `TypeChecker::normalize` would ICE with "unexpected ambiguity"
This commit is contained in:
parent
37b40e471a
commit
c6a17bf8bc
15 changed files with 350 additions and 186 deletions
|
|
@ -5,7 +5,7 @@ LL | fn uninit<'a>() {
|
|||
| -- lifetime `'a` defined here
|
||||
LL | return;
|
||||
LL | let x: &'static &'a ();
|
||||
| ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
| ^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/wf-unreachable.rs:11:12
|
||||
|
|
@ -14,7 +14,7 @@ LL | fn var_type<'a>() {
|
|||
| -- lifetime `'a` defined here
|
||||
LL | return;
|
||||
LL | let x: &'static &'a () = &&();
|
||||
| ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
| ^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/wf-unreachable.rs:15:12
|
||||
|
|
@ -22,7 +22,7 @@ error: lifetime may not live long enough
|
|||
LL | fn uninit_infer<'a>() {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | let x: &'static &'a _;
|
||||
| ^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
| ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/wf-unreachable.rs:21:12
|
||||
|
|
@ -31,7 +31,7 @@ LL | fn infer<'a>() {
|
|||
| -- lifetime `'a` defined here
|
||||
LL | return;
|
||||
LL | let x: &'static &'a _ = &&();
|
||||
| ^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
| ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/wf-unreachable.rs:26:12
|
||||
|
|
@ -40,7 +40,7 @@ LL | fn uninit_no_var<'a>() {
|
|||
| -- lifetime `'a` defined here
|
||||
LL | return;
|
||||
LL | let _: &'static &'a ();
|
||||
| ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
| ^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/wf-unreachable.rs:31:12
|
||||
|
|
@ -49,7 +49,7 @@ LL | fn no_var<'a>() {
|
|||
| -- lifetime `'a` defined here
|
||||
LL | return;
|
||||
LL | let _: &'static &'a () = &&();
|
||||
| ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
| ^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/wf-unreachable.rs:36:12
|
||||
|
|
@ -58,7 +58,7 @@ LL | fn infer_no_var<'a>() {
|
|||
| -- lifetime `'a` defined here
|
||||
LL | return;
|
||||
LL | let _: &'static &'a _ = &&();
|
||||
| ^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
| ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/wf-unreachable.rs:49:12
|
||||
|
|
@ -67,7 +67,7 @@ LL | fn required_substs<'a>() {
|
|||
| -- lifetime `'a` defined here
|
||||
LL | return;
|
||||
LL | let _: C<'static, 'a, _> = C((), &(), &());
|
||||
| ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
| ^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
|
|
|||
15
src/test/ui/nll/user-annotations/closure-sig.rs
Normal file
15
src/test/ui/nll/user-annotations/closure-sig.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
// This test fails if #104478 is fixed before #104477.
|
||||
|
||||
// check-pass
|
||||
|
||||
struct Printer<'a, 'b>(&'a (), &'b ());
|
||||
|
||||
impl Printer<'_, '_> {
|
||||
fn test(self) {
|
||||
let clo = |_: &'_ Self| {};
|
||||
clo(&self);
|
||||
clo(&self);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
40
src/test/ui/nll/user-annotations/normalization-infer.rs
Normal file
40
src/test/ui/nll/user-annotations/normalization-infer.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// Annnotations may contain projection types with inference variables as input.
|
||||
// Make sure we don't get ambiguities when normalizing them.
|
||||
|
||||
// check-fail
|
||||
|
||||
// Single impl.
|
||||
fn test1<A, B, C, D>(a: A, b: B, c: C) {
|
||||
trait Tr { type Ty; }
|
||||
impl<T: 'static> Tr for (T,) { type Ty = T; }
|
||||
|
||||
let _: <(_,) as Tr>::Ty = a; //~ ERROR type `A`
|
||||
Some::<<(_,) as Tr>::Ty>(b); //~ ERROR type `B`
|
||||
|| -> <(_,) as Tr>::Ty { c }; //~ ERROR type `C`
|
||||
|d: <(_,) as Tr>::Ty| -> D { d }; //~ ERROR type `D`
|
||||
}
|
||||
|
||||
|
||||
// Two impls. The selected impl depends on the actual type.
|
||||
fn test2<A, B, C>(a: A, b: B, c: C) {
|
||||
trait Tr { type Ty; }
|
||||
impl<T: 'static> Tr for (u8, T) { type Ty = T; }
|
||||
impl<T> Tr for (i8, T) { type Ty = T; }
|
||||
type Alias<X, Y> = (<(X, Y) as Tr>::Ty, X);
|
||||
|
||||
fn temp() -> String { todo!() }
|
||||
|
||||
// `u8` impl, requires static.
|
||||
let _: Alias<_, _> = (a, 0u8); //~ ERROR type `A`
|
||||
Some::<Alias<_, _>>((b, 0u8)); //~ ERROR type `B`
|
||||
|| -> Alias<_, _> { (c, 0u8) }; //~ ERROR type `C`
|
||||
|
||||
let _: Alias<_, _> = (&temp(), 0u8); //~ ERROR temporary value
|
||||
Some::<Alias<_, _>>((&temp(), 0u8)); //~ ERROR temporary value
|
||||
|
||||
// `i8` impl, no region constraints.
|
||||
let _: Alias<_, _> = (&temp(), 0i8);
|
||||
Some::<Alias<_, _>>((&temp(), 0i8));
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
101
src/test/ui/nll/user-annotations/normalization-infer.stderr
Normal file
101
src/test/ui/nll/user-annotations/normalization-infer.stderr
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
error[E0310]: the parameter type `A` may not live long enough
|
||||
--> $DIR/normalization-infer.rs:11:12
|
||||
|
|
||||
LL | let _: <(_,) as Tr>::Ty = a;
|
||||
| ^^^^^^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds
|
||||
|
|
||||
help: consider adding an explicit lifetime bound...
|
||||
|
|
||||
LL | fn test1<A: 'static, B, C, D>(a: A, b: B, c: C) {
|
||||
| +++++++++
|
||||
|
||||
error[E0310]: the parameter type `B` may not live long enough
|
||||
--> $DIR/normalization-infer.rs:12:5
|
||||
|
|
||||
LL | Some::<<(_,) as Tr>::Ty>(b);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `B` will meet its required lifetime bounds
|
||||
|
|
||||
help: consider adding an explicit lifetime bound...
|
||||
|
|
||||
LL | fn test1<A, B: 'static, C, D>(a: A, b: B, c: C) {
|
||||
| +++++++++
|
||||
|
||||
error[E0310]: the parameter type `C` may not live long enough
|
||||
--> $DIR/normalization-infer.rs:13:11
|
||||
|
|
||||
LL | || -> <(_,) as Tr>::Ty { c };
|
||||
| ^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds
|
||||
|
|
||||
help: consider adding an explicit lifetime bound...
|
||||
|
|
||||
LL | fn test1<A, B, C: 'static, D>(a: A, b: B, c: C) {
|
||||
| +++++++++
|
||||
|
||||
error[E0310]: the parameter type `D` may not live long enough
|
||||
--> $DIR/normalization-infer.rs:14:6
|
||||
|
|
||||
LL | |d: <(_,) as Tr>::Ty| -> D { d };
|
||||
| ^ ...so that the type `D` will meet its required lifetime bounds
|
||||
|
|
||||
help: consider adding an explicit lifetime bound...
|
||||
|
|
||||
LL | fn test1<A, B, C, D: 'static>(a: A, b: B, c: C) {
|
||||
| +++++++++
|
||||
|
||||
error[E0310]: the parameter type `A` may not live long enough
|
||||
--> $DIR/normalization-infer.rs:28:12
|
||||
|
|
||||
LL | let _: Alias<_, _> = (a, 0u8);
|
||||
| ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds
|
||||
|
|
||||
help: consider adding an explicit lifetime bound...
|
||||
|
|
||||
LL | fn test2<A: 'static, B, C>(a: A, b: B, c: C) {
|
||||
| +++++++++
|
||||
|
||||
error[E0310]: the parameter type `B` may not live long enough
|
||||
--> $DIR/normalization-infer.rs:29:5
|
||||
|
|
||||
LL | Some::<Alias<_, _>>((b, 0u8));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `B` will meet its required lifetime bounds
|
||||
|
|
||||
help: consider adding an explicit lifetime bound...
|
||||
|
|
||||
LL | fn test2<A, B: 'static, C>(a: A, b: B, c: C) {
|
||||
| +++++++++
|
||||
|
||||
error[E0310]: the parameter type `C` may not live long enough
|
||||
--> $DIR/normalization-infer.rs:30:11
|
||||
|
|
||||
LL | || -> Alias<_, _> { (c, 0u8) };
|
||||
| ^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds
|
||||
|
|
||||
help: consider adding an explicit lifetime bound...
|
||||
|
|
||||
LL | fn test2<A, B, C: 'static>(a: A, b: B, c: C) {
|
||||
| +++++++++
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/normalization-infer.rs:32:28
|
||||
|
|
||||
LL | let _: Alias<_, _> = (&temp(), 0u8);
|
||||
| ----------- ^^^^^^ creates a temporary value which is freed while still in use
|
||||
| |
|
||||
| type annotation requires that borrow lasts for `'static`
|
||||
...
|
||||
LL | }
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/normalization-infer.rs:33:27
|
||||
|
|
||||
LL | Some::<Alias<_, _>>((&temp(), 0u8));
|
||||
| --^^^^^^------ - temporary value is freed at the end of this statement
|
||||
| | |
|
||||
| | creates a temporary value which is freed while still in use
|
||||
| this usage requires that borrow lasts for `'static`
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0310, E0716.
|
||||
For more information about an error, try `rustc --explain E0310`.
|
||||
|
|
@ -7,7 +7,7 @@ LL | fn with_assoc<'a,'b>() {
|
|||
| lifetime `'a` defined here
|
||||
...
|
||||
LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
|
||||
|
|
||||
= help: consider adding the following bound: `'b: 'a`
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
|
|||
| |
|
||||
| lifetime `'a` defined here
|
||||
LL | let z: Option<&'b &'a usize> = None;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'b`
|
||||
|
|
||||
= help: consider adding the following bound: `'a: 'b`
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) {
|
|||
| lifetime `'a` defined here
|
||||
LL | let y: Paramd<'a> = Paramd { x: a };
|
||||
LL | let z: Option<&'b Paramd<'a>> = None;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'b`
|
||||
|
|
||||
= help: consider adding the following bound: `'a: 'b`
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
|
|||
| |
|
||||
| lifetime `'a` defined here
|
||||
LL | let z: Option<&'a &'b usize> = None;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
|
||||
|
|
||||
= help: consider adding the following bound: `'b: 'a`
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ LL | fn with_assoc<'a,'b>() {
|
|||
| lifetime `'a` defined here
|
||||
...
|
||||
LL | let _: &'a WithHrAssoc<TheType<'b>> = loop { };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
|
||||
|
|
||||
= help: consider adding the following bound: `'b: 'a`
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ LL | fn with_assoc_sub<'a,'b>() {
|
|||
| lifetime `'a` defined here
|
||||
...
|
||||
LL | let _: &'a WithHrAssocSub<TheType<'b>> = loop { };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
|
||||
|
|
||||
= help: consider adding the following bound: `'b: 'a`
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ LL | fn with_assoc<'a,'b>() {
|
|||
| lifetime `'a` defined here
|
||||
...
|
||||
LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
|
||||
|
|
||||
= help: consider adding the following bound: `'b: 'a`
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ LL | fn with_assoc<'a,'b>() {
|
|||
| lifetime `'a` defined here
|
||||
...
|
||||
LL | let _x: &'a WithAssoc<TheType<'b>> = loop { };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
|
||||
|
|
||||
= help: consider adding the following bound: `'b: 'a`
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ LL | fn without_assoc<'a,'b>() {
|
|||
| lifetime `'a` defined here
|
||||
...
|
||||
LL | let _x: &'a WithoutAssoc<TheType<'b>> = loop { };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
|
||||
|
|
||||
= help: consider adding the following bound: `'b: 'a`
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue