Add the actual chain of projections to UserTypeProjection.

Update the existing NLL `patterns.rs` test accordingly.

includes changes addressing review feedback:

 * Added example to docs for `UserTypeProjections` illustrating how we
   build up multiple projections when descending into a pattern with
   type ascriptions.

 * Adapted niko's suggested docs for `UserTypeProjection`.

 * Factored out `projection_ty` from more general `projection_ty_core`
   (as a drive-by, made its callback an `FnMut`, as I discovered later
   that I need that).

 * Add note to docs that `PlaceTy.field_ty(..)` does not normalize its result.

 * Normalize as we project out `field_ty`.
This commit is contained in:
Felix S. Klock II 2018-10-22 22:50:10 +02:00
parent b569caf267
commit 740e8a3f37
13 changed files with 273 additions and 65 deletions

View file

@ -9,11 +9,11 @@ fn variable_no_initializer() {
}
fn tuple_no_initializer() {
// FIXME(#47187): We are not propagating ascribed type through tuples.
let x = 22;
let (y, z): (&'static u32, &'static u32);
y = &x;
y = &x; //~ ERROR
}
fn ref_with_ascribed_static_type() -> u32 {
@ -34,11 +34,11 @@ fn ref_with_ascribed_any_type() -> u32 {
struct Single<T> { value: T }
fn struct_no_initializer() {
// FIXME(#47187): We are not propagating ascribed type through patterns.
let x = 22;
let Single { value: y }: Single<&'static u32>;
y = &x;
y = &x; //~ ERROR
}
fn variable_with_initializer() {
@ -91,26 +91,26 @@ fn struct_double_field_underscore_with_initializer() {
}
fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 {
// The error in this test is inconsistency with
// `static_to_a_to_static_through_tuple`, but "feels right" to
// me. It occurs because we special case the single binding case
// and force the type of `y` to be `&'a u32`, even though the
// right-hand side has type `&'static u32`.
let y: &'a u32 = &22;
y //~ ERROR
}
fn static_to_a_to_static_through_tuple<'a>(x: &'a u32) -> &'static u32 {
// FIXME(#47187): The fact that this type-checks is perhaps surprising.
// What happens is that the right-hand side is constrained to have
// type `&'a u32`, which is possible, because it has type
// `&'static u32`. The variable `y` is then forced to have type
// `&'static u32`, but it is constrained only by the right-hand
// side, not the ascribed type, and hence it passes.
let (y, _z): (&'a u32, u32) = (&22, 44);
y
y //~ ERROR
}
fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 {

View file

@ -8,6 +8,16 @@ LL | y = &x; //~ ERROR
LL | }
| - `x` dropped here while still borrowed
error[E0597]: `x` does not live long enough
--> $DIR/patterns.rs:16:9
|
LL | let (y, z): (&'static u32, &'static u32);
| ---------------------------- type annotation requires that `x` is borrowed for `'static`
LL | y = &x; //~ ERROR
| ^^ borrowed value does not live long enough
LL | }
| - `x` dropped here while still borrowed
error[E0597]: `x` does not live long enough
--> $DIR/patterns.rs:22:13
|
@ -19,6 +29,16 @@ LL | **z
LL | }
| - `x` dropped here while still borrowed
error[E0597]: `x` does not live long enough
--> $DIR/patterns.rs:41:9
|
LL | let Single { value: y }: Single<&'static u32>;
| -------------------- type annotation requires that `x` is borrowed for `'static`
LL | y = &x; //~ ERROR
| ^^ borrowed value does not live long enough
LL | }
| - `x` dropped here while still borrowed
error[E0597]: `x` does not live long enough
--> $DIR/patterns.rs:46:27
|
@ -127,6 +147,15 @@ LL | fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 {
LL | y //~ ERROR
| ^ returning this value requires that `'a` must outlive `'static`
error: unsatisfied lifetime constraints
--> $DIR/patterns.rs:113:5
|
LL | fn static_to_a_to_static_through_tuple<'a>(x: &'a u32) -> &'static u32 {
| -- lifetime `'a` defined here
...
LL | y //~ ERROR
| ^ returning this value requires that `'a` must outlive `'static`
error: unsatisfied lifetime constraints
--> $DIR/patterns.rs:117:18
|
@ -135,7 +164,7 @@ LL | fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 {
LL | let (y, _z): (&'static u32, u32) = (x, 44); //~ ERROR
| ^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
error: aborting due to 14 previous errors
error: aborting due to 17 previous errors
Some errors occurred: E0597, E0716.
For more information about an error, try `rustc --explain E0597`.