Auto merge of #55093 - nikomatsakis:nll-issue-54574-multisegment-path, r=pnkfelix
nll type annotations in multisegment path This turned out to be sort of tricky. The problem is that if you have a path like ``` <Foo<&'static u32>>::bar ``` and it comes from an impl like `impl<T> Foo<T>` then the self-type the user gave doesn't *directly* map to the substitutions that the impl wants. To handle this, then, we have to preserve not just the "user-given substs" we used to do, but also a "user-given self-ty", which we have to apply later. This PR makes those changes. It also removes the code from NLL relate-ops that handled canonical variables and moves to use normal inference variables instead. This simplifies a few things and gives us a bit more flexibility (for example, I predict we are going to have to start normalizing at some point, and it would be easy now). r? @matthewjasper -- you were just touching this code, do you feel comfortable reviewing this? Fixes #54574
This commit is contained in:
commit
01ca85becd
31 changed files with 1256 additions and 844 deletions
|
|
@ -1,4 +1,4 @@
|
|||
error: user substs: Canonical { variables: [], value: [u32] }
|
||||
error: user substs: Canonical { variables: [], value: UserSubsts { substs: [u32], user_self_ty: None } }
|
||||
--> $DIR/dump-adt-brace-struct.rs:28:5
|
||||
|
|
||||
LL | SomeStruct::<u32> { t: 22 }; //~ ERROR [u32]
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
error: user substs: Canonical { variables: [], value: [u32] }
|
||||
error: user substs: Canonical { variables: [], value: UserSubsts { substs: [u32], user_self_ty: None } }
|
||||
--> $DIR/dump-fn-method.rs:36:13
|
||||
|
|
||||
LL | let x = foo::<u32>; //~ ERROR [u32]
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: user substs: Canonical { variables: [CanonicalVarInfo { kind: Ty(General) }, CanonicalVarInfo { kind: Ty(General) }], value: [?0, u32, ?1] }
|
||||
error: user substs: Canonical { variables: [CanonicalVarInfo { kind: Ty(General) }, CanonicalVarInfo { kind: Ty(General) }], value: UserSubsts { substs: [?0, u32, ?1], user_self_ty: None } }
|
||||
--> $DIR/dump-fn-method.rs:42:13
|
||||
|
|
||||
LL | let x = <_ as Bazoom<u32>>::method::<_>; //~ ERROR [?0, u32, ?1]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: user substs: Canonical { variables: [], value: [u8, u16, u32] }
|
||||
error: user substs: Canonical { variables: [], value: UserSubsts { substs: [u8, u16, u32], user_self_ty: None } }
|
||||
--> $DIR/dump-fn-method.rs:46:13
|
||||
|
|
||||
LL | let x = <u8 as Bazoom<u16>>::method::<u32>; //~ ERROR [u8, u16, u32]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: user substs: Canonical { variables: [CanonicalVarInfo { kind: Ty(General) }, CanonicalVarInfo { kind: Ty(General) }], value: [?0, ?1, u32] }
|
||||
error: user substs: Canonical { variables: [CanonicalVarInfo { kind: Ty(General) }, CanonicalVarInfo { kind: Ty(General) }], value: UserSubsts { substs: [?0, ?1, u32], user_self_ty: None } }
|
||||
--> $DIR/dump-fn-method.rs:54:5
|
||||
|
|
||||
LL | y.method::<u32>(44, 66); //~ ERROR [?0, ?1, u32]
|
||||
|
|
|
|||
20
src/test/ui/nll/user-annotations/method-ufcs-inherent-1.rs
Normal file
20
src/test/ui/nll/user-annotations/method-ufcs-inherent-1.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#![feature(nll)]
|
||||
|
||||
// Check that substitutions given on the self type (here, `A`) carry
|
||||
// through to NLL.
|
||||
|
||||
struct A<'a> { x: &'a u32 }
|
||||
|
||||
impl<'a> A<'a> {
|
||||
fn new<'b, T>(x: &'a u32, y: T) -> Self {
|
||||
Self { x }
|
||||
}
|
||||
}
|
||||
|
||||
fn foo<'a>() {
|
||||
let v = 22;
|
||||
let x = A::<'a>::new(&v, 22);
|
||||
//~^ ERROR
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
error[E0597]: `v` does not live long enough
|
||||
--> $DIR/method-ufcs-inherent-1.rs:16:26
|
||||
|
|
||||
LL | let x = A::<'a>::new(&v, 22);
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | //~^ ERROR
|
||||
LL | }
|
||||
| - `v` dropped here while still borrowed
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 14:8...
|
||||
--> $DIR/method-ufcs-inherent-1.rs:14:8
|
||||
|
|
||||
LL | fn foo<'a>() {
|
||||
| ^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
||||
21
src/test/ui/nll/user-annotations/method-ufcs-inherent-2.rs
Normal file
21
src/test/ui/nll/user-annotations/method-ufcs-inherent-2.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#![feature(nll)]
|
||||
|
||||
// Check that substitutions given on the self type (here, `A`) can be
|
||||
// used in combination with annotations given for method arguments.
|
||||
|
||||
struct A<'a> { x: &'a u32 }
|
||||
|
||||
impl<'a> A<'a> {
|
||||
fn new<'b, T>(x: &'a u32, y: T) -> Self {
|
||||
Self { x }
|
||||
}
|
||||
}
|
||||
|
||||
fn foo<'a>() {
|
||||
let v = 22;
|
||||
let x = A::<'a>::new::<&'a u32>(&v, &v);
|
||||
//~^ ERROR
|
||||
//~| ERROR
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
error[E0597]: `v` does not live long enough
|
||||
--> $DIR/method-ufcs-inherent-2.rs:16:37
|
||||
|
|
||||
LL | let x = A::<'a>::new::<&'a u32>(&v, &v);
|
||||
| ^^ borrowed value does not live long enough
|
||||
...
|
||||
LL | }
|
||||
| - `v` dropped here while still borrowed
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 14:8...
|
||||
--> $DIR/method-ufcs-inherent-2.rs:14:8
|
||||
|
|
||||
LL | fn foo<'a>() {
|
||||
| ^^
|
||||
|
||||
error[E0597]: `v` does not live long enough
|
||||
--> $DIR/method-ufcs-inherent-2.rs:16:41
|
||||
|
|
||||
LL | let x = A::<'a>::new::<&'a u32>(&v, &v);
|
||||
| ^^ borrowed value does not live long enough
|
||||
...
|
||||
LL | }
|
||||
| - `v` dropped here while still borrowed
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 14:8...
|
||||
--> $DIR/method-ufcs-inherent-2.rs:14:8
|
||||
|
|
||||
LL | fn foo<'a>() {
|
||||
| ^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
||||
20
src/test/ui/nll/user-annotations/method-ufcs-inherent-3.rs
Normal file
20
src/test/ui/nll/user-annotations/method-ufcs-inherent-3.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#![feature(nll)]
|
||||
|
||||
// Check that inherent methods invoked with `<T>::new` style
|
||||
// carry their annotations through to NLL.
|
||||
|
||||
struct A<'a> { x: &'a u32 }
|
||||
|
||||
impl<'a> A<'a> {
|
||||
fn new<'b, T>(x: &'a u32, y: T) -> Self {
|
||||
Self { x }
|
||||
}
|
||||
}
|
||||
|
||||
fn foo<'a>() {
|
||||
let v = 22;
|
||||
let x = <A<'a>>::new(&v, 22);
|
||||
//~^ ERROR
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
error[E0597]: `v` does not live long enough
|
||||
--> $DIR/method-ufcs-inherent-3.rs:16:26
|
||||
|
|
||||
LL | let x = <A<'a>>::new(&v, 22);
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | //~^ ERROR
|
||||
LL | }
|
||||
| - `v` dropped here while still borrowed
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 14:8...
|
||||
--> $DIR/method-ufcs-inherent-3.rs:14:8
|
||||
|
|
||||
LL | fn foo<'a>() {
|
||||
| ^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
||||
22
src/test/ui/nll/user-annotations/method-ufcs-inherent-4.rs
Normal file
22
src/test/ui/nll/user-annotations/method-ufcs-inherent-4.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#![feature(nll)]
|
||||
|
||||
// Check that inherent methods invoked with `<T>::new` style
|
||||
// carry their annotations through to NLL in connection with
|
||||
// method type parameters.
|
||||
|
||||
struct A<'a> { x: &'a u32 }
|
||||
|
||||
impl<'a> A<'a> {
|
||||
fn new<'b, T>(x: &'a u32, y: T) -> Self {
|
||||
Self { x }
|
||||
}
|
||||
}
|
||||
|
||||
fn foo<'a>() {
|
||||
let v = 22;
|
||||
let x = <A<'a>>::new::<&'a u32>(&v, &v);
|
||||
//~^ ERROR
|
||||
//~| ERROR
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
error[E0597]: `v` does not live long enough
|
||||
--> $DIR/method-ufcs-inherent-4.rs:17:37
|
||||
|
|
||||
LL | let x = <A<'a>>::new::<&'a u32>(&v, &v);
|
||||
| ^^ borrowed value does not live long enough
|
||||
...
|
||||
LL | }
|
||||
| - `v` dropped here while still borrowed
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 15:8...
|
||||
--> $DIR/method-ufcs-inherent-4.rs:15:8
|
||||
|
|
||||
LL | fn foo<'a>() {
|
||||
| ^^
|
||||
|
||||
error[E0597]: `v` does not live long enough
|
||||
--> $DIR/method-ufcs-inherent-4.rs:17:41
|
||||
|
|
||||
LL | let x = <A<'a>>::new::<&'a u32>(&v, &v);
|
||||
| ^^ borrowed value does not live long enough
|
||||
...
|
||||
LL | }
|
||||
| - `v` dropped here while still borrowed
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 15:8...
|
||||
--> $DIR/method-ufcs-inherent-4.rs:15:8
|
||||
|
|
||||
LL | fn foo<'a>() {
|
||||
| ^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue