Skip to content

Commit

Permalink
Use the span of the user type for AscribeUserType
Browse files Browse the repository at this point in the history
Also change the order of the fake read for let and the AscribeUserType,
so that we use the better span and message from the fake read in errors.
  • Loading branch information
matthewjasper committed Oct 10, 2018
1 parent 0e07c42 commit 55ec104
Show file tree
Hide file tree
Showing 23 changed files with 94 additions and 57 deletions.
2 changes: 1 addition & 1 deletion src/librustc/mir/mod.rs
Expand Up @@ -710,7 +710,7 @@ pub struct LocalDecl<'tcx> {
/// e.g. via `let x: T`, then we carry that type here. The MIR
/// borrow checker needs this information since it can affect
/// region inference.
pub user_ty: Option<CanonicalTy<'tcx>>,
pub user_ty: Option<(CanonicalTy<'tcx>, Span)>,

/// Name of the local, used in debuginfo and pretty-printing.
///
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/mir/visit.rs
Expand Up @@ -735,7 +735,7 @@ macro_rules! make_mir_visitor {
local,
source_info: *source_info,
});
if let Some(user_ty) = user_ty {
if let Some((user_ty, _)) = user_ty {
self.visit_user_ty(user_ty);
}
self.visit_source_info(source_info);
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/borrow_check/nll/type_check/mod.rs
Expand Up @@ -310,12 +310,12 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
self.super_local_decl(local, local_decl);
self.sanitize_type(local_decl, local_decl.ty);

if let Some(user_ty) = local_decl.user_ty {
if let Some((user_ty, span)) = local_decl.user_ty {
if let Err(terr) = self.cx.relate_type_and_user_type(
local_decl.ty,
ty::Variance::Invariant,
user_ty,
Locations::All(local_decl.source_info.span),
Locations::All(span),
ConstraintCategory::TypeAnnotation,
) {
span_mirbug!(
Expand Down
37 changes: 19 additions & 18 deletions src/librustc_mir/build/matches/mod.rs
Expand Up @@ -292,30 +292,32 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
..
},
user_ty: ascription_user_ty,
user_ty_span,
} => {
let place =
self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard);
unpack!(block = self.into(&place, block, initializer));

let source_info = self.source_info(irrefutable_pat.span);
// Inject a fake read, see comments on `FakeReadCause::ForLet`.
let pattern_source_info = self.source_info(irrefutable_pat.span);
self.cfg.push(
block,
Statement {
source_info,
kind: StatementKind::AscribeUserType(
place.clone(),
ty::Variance::Invariant,
ascription_user_ty,
),
source_info: pattern_source_info,
kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()),
},
);

// Inject a fake read, see comments on `FakeReadCause::ForLet`.
let ty_source_info = self.source_info(user_ty_span);
self.cfg.push(
block,
Statement {
source_info,
kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()),
source_info: ty_source_info,
kind: StatementKind::AscribeUserType(
place.clone(),
ty::Variance::Invariant,
ascription_user_ty,
),
},
);

Expand Down Expand Up @@ -489,7 +491,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
pub fn visit_bindings(
&mut self,
pattern: &Pattern<'tcx>,
mut pattern_user_ty: Option<CanonicalTy<'tcx>>,
mut pattern_user_ty: Option<(CanonicalTy<'tcx>, Span)>,
f: &mut impl FnMut(
&mut Self,
Mutability,
Expand All @@ -498,7 +500,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
NodeId,
Span,
Ty<'tcx>,
Option<CanonicalTy<'tcx>>,
Option<(CanonicalTy<'tcx>, Span)>,
),
) {
match *pattern.kind {
Expand Down Expand Up @@ -549,16 +551,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
// FIXME(#47184): extract or handle `pattern_user_ty` somehow
self.visit_bindings(subpattern, None, f);
}
PatternKind::AscribeUserType { ref subpattern, user_ty } => {
PatternKind::AscribeUserType { ref subpattern, user_ty, user_ty_span } => {
// This corresponds to something like
//
// ```
// let (p1: T1): T2 = ...;
// let A::<'a>(_): A<'static> = ...;
// ```
//
// Not presently possible, though maybe someday.
assert!(pattern_user_ty.is_none());
self.visit_bindings(subpattern, Some(user_ty), f)
// FIXME(#47184): handle `pattern_user_ty` somehow
self.visit_bindings(subpattern, Some((user_ty, user_ty_span)), f)
}
PatternKind::Leaf { ref subpatterns }
| PatternKind::Variant {
Expand Down Expand Up @@ -1469,7 +1470,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
num_patterns: usize,
var_id: NodeId,
var_ty: Ty<'tcx>,
user_var_ty: Option<CanonicalTy<'tcx>>,
user_var_ty: Option<(CanonicalTy<'tcx>, Span)>,
has_guard: ArmHasGuard,
opt_match_place: Option<(Option<Place<'tcx>>, Span)>,
pat_span: Span,
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/build/matches/simplify.rs
Expand Up @@ -63,9 +63,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
candidate: &mut Candidate<'pat, 'tcx>)
-> Result<(), MatchPair<'pat, 'tcx>> {
match *match_pair.pattern.kind {
PatternKind::AscribeUserType { ref subpattern, user_ty } => {
PatternKind::AscribeUserType { ref subpattern, user_ty, user_ty_span } => {
candidate.ascriptions.push(Ascription {
span: match_pair.pattern.span,
span: user_ty_span,
user_ty,
source: match_pair.place.clone(),
});
Expand Down
1 change: 1 addition & 0 deletions src/librustc_mir/hair/cx/block.rs
Expand Up @@ -92,6 +92,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
span: pattern.span,
kind: Box::new(PatternKind::AscribeUserType {
user_ty: *user_ty,
user_ty_span: ty.span,
subpattern: pattern
})
};
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_mir/hair/pattern/mod.rs
Expand Up @@ -71,6 +71,7 @@ pub enum PatternKind<'tcx> {
AscribeUserType {
user_ty: CanonicalTy<'tcx>,
subpattern: Pattern<'tcx>,
user_ty_span: Span,
},

/// x, ref x, x @ P, etc
Expand Down Expand Up @@ -692,6 +693,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
kind = PatternKind::AscribeUserType {
subpattern,
user_ty,
user_ty_span: span,
};
}

Expand Down Expand Up @@ -1015,9 +1017,11 @@ impl<'tcx> PatternFoldable<'tcx> for PatternKind<'tcx> {
PatternKind::AscribeUserType {
ref subpattern,
user_ty,
user_ty_span,
} => PatternKind::AscribeUserType {
subpattern: subpattern.fold_with(folder),
user_ty: user_ty.fold_with(folder),
user_ty_span,
},
PatternKind::Binding {
mutability,
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/basic_assignment.rs
Expand Up @@ -55,8 +55,8 @@ fn main() {
// StorageDead(_3);
// StorageLive(_4);
// _4 = std::option::Option<std::boxed::Box<u32>>::None;
// AscribeUserType(_4, o, Canonical { variables: [], value: std::option::Option<std::boxed::Box<u32>> });
// FakeRead(ForLet, _4);
// AscribeUserType(_4, o, Canonical { variables: [], value: std::option::Option<std::boxed::Box<u32>> });
// StorageLive(_5);
// StorageLive(_6);
// _6 = move _4;
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr
Expand Up @@ -5,10 +5,10 @@ LL | let a: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
| ^^^^^^^^^

error: higher-ranked subtype error
--> $DIR/hr-fn-aaa-as-aba.rs:32:9
--> $DIR/hr-fn-aaa-as-aba.rs:32:12
|
LL | let _: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
| ^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

4 changes: 2 additions & 2 deletions src/test/ui/nll/user-annotations/patterns.stderr
Expand Up @@ -131,12 +131,12 @@ LL | y //~ ERROR
| ^ returning this value requires that `'a` must outlive `'static`

error: unsatisfied lifetime constraints
--> $DIR/patterns.rs:117:9
--> $DIR/patterns.rs:117:18
|
LL | fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 {
| -- lifetime `'a` defined here
LL | let (y, _z): (&'static u32, u32) = (x, 44); //~ ERROR
| ^^^^^^^ type annotation requires that `'a` must outlive `'static`
| ^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`

error: aborting due to 14 previous errors

Expand Down
@@ -1,10 +1,10 @@
error[E0621]: explicit lifetime required in the type of `v`
--> $DIR/region-object-lifetime-in-coercion.rs:18:9
--> $DIR/region-object-lifetime-in-coercion.rs:18:12
|
LL | fn a(v: &[u8]) -> Box<Foo + 'static> {
| ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
LL | let x: Box<Foo + 'static> = Box::new(v);
| ^ lifetime `'static` required
| ^^^^^^^^^^^^^^^^^^ lifetime `'static` required

error[E0621]: explicit lifetime required in the type of `v`
--> $DIR/region-object-lifetime-in-coercion.rs:24:5
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/regions/regions-addr-of-self.nll.stderr
@@ -1,10 +1,10 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-addr-of-self.rs:17:13
--> $DIR/regions-addr-of-self.rs:17:16
|
LL | pub fn chase_cat(&mut self) {
| - let's call the lifetime of this reference `'1`
LL | let p: &'static mut usize = &mut self.cats_chased; //~ ERROR cannot infer
| ^ type annotation requires that `'1` must outlive `'static`
| ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`

error: aborting due to previous error

12 changes: 6 additions & 6 deletions src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr
@@ -1,33 +1,33 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-addr-of-upvar-self.rs:20:17
--> $DIR/regions-addr-of-upvar-self.rs:20:20
|
LL | let _f = || {
| -- lifetime `'1` represents this closure's body
LL | let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
| ^ type annotation requires that `'1` must outlive `'static`
| ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
|
= note: closure implements `FnMut`, so references to captured variables can't escape the closure

error: unsatisfied lifetime constraints
--> $DIR/regions-addr-of-upvar-self.rs:20:17
--> $DIR/regions-addr-of-upvar-self.rs:20:20
|
LL | pub fn chase_cat(&mut self) {
| --------- lifetime `'2` appears in the type of `self`
LL | let _f = || {
| -- lifetime `'1` represents this closure's body
LL | let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
| ^ type annotation requires that `'1` must outlive `'2`
| ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'2`
|
= note: closure implements `FnMut`, so references to captured variables can't escape the closure

error: unsatisfied lifetime constraints
--> $DIR/regions-addr-of-upvar-self.rs:20:17
--> $DIR/regions-addr-of-upvar-self.rs:20:20
|
LL | pub fn chase_cat(&mut self) {
| - let's call the lifetime of this reference `'1`
LL | let _f = || {
LL | let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
| ^ type annotation requires that `'1` must outlive `'static`
| ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`

error[E0597]: `self` does not live long enough
--> $DIR/regions-addr-of-upvar-self.rs:20:46
Expand Down
@@ -1,13 +1,13 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-infer-contravariance-due-to-decl.rs:35:9
--> $DIR/regions-infer-contravariance-due-to-decl.rs:35:12
|
LL | fn use_<'short,'long>(c: Contravariant<'short>,
| ------ ----- lifetime `'long` defined here
| |
| lifetime `'short` defined here
...
LL | let _: Contravariant<'long> = c; //~ ERROR E0623
| ^ type annotation requires that `'short` must outlive `'long`
| ^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`

error: aborting due to previous error

@@ -1,13 +1,13 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-infer-covariance-due-to-decl.rs:32:9
--> $DIR/regions-infer-covariance-due-to-decl.rs:32:12
|
LL | fn use_<'short,'long>(c: Covariant<'long>,
| ------ ----- lifetime `'long` defined here
| |
| lifetime `'short` defined here
...
LL | let _: Covariant<'short> = c; //~ ERROR E0623
| ^ type annotation requires that `'short` must outlive `'long`
| ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`

error: aborting due to previous error

@@ -1,13 +1,13 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-variance-contravariant-use-covariant-in-second-position.rs:35:9
--> $DIR/regions-variance-contravariant-use-covariant-in-second-position.rs:35:12
|
LL | fn use_<'short,'long>(c: S<'long, 'short>,
| ------ ----- lifetime `'long` defined here
| |
| lifetime `'short` defined here
...
LL | let _: S<'long, 'long> = c; //~ ERROR E0623
| ^ type annotation requires that `'short` must outlive `'long`
| ^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`

error: aborting due to previous error

@@ -1,13 +1,13 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-variance-contravariant-use-covariant.rs:33:9
--> $DIR/regions-variance-contravariant-use-covariant.rs:33:12
|
LL | fn use_<'short,'long>(c: Contravariant<'short>,
| ------ ----- lifetime `'long` defined here
| |
| lifetime `'short` defined here
...
LL | let _: Contravariant<'long> = c; //~ ERROR E0623
| ^ type annotation requires that `'short` must outlive `'long`
| ^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`

error: aborting due to previous error

@@ -1,13 +1,13 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-variance-covariant-use-contravariant.rs:33:9
--> $DIR/regions-variance-covariant-use-contravariant.rs:33:12
|
LL | fn use_<'short,'long>(c: Covariant<'long>,
| ------ ----- lifetime `'long` defined here
| |
| lifetime `'short` defined here
...
LL | let _: Covariant<'short> = c; //~ ERROR E0623
| ^ type annotation requires that `'short` must outlive `'long`
| ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`

error: aborting due to previous error

@@ -1,13 +1,13 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-variance-invariant-use-contravariant.rs:30:9
--> $DIR/regions-variance-invariant-use-contravariant.rs:30:12
|
LL | fn use_<'short,'long>(c: Invariant<'long>,
| ------ ----- lifetime `'long` defined here
| |
| lifetime `'short` defined here
...
LL | let _: Invariant<'short> = c; //~ ERROR E0623
| ^ type annotation requires that `'short` must outlive `'long`
| ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`

error: aborting due to previous error

@@ -1,11 +1,11 @@
error: unsatisfied lifetime constraints
--> $DIR/regions-variance-invariant-use-covariant.rs:27:9
--> $DIR/regions-variance-invariant-use-covariant.rs:27:12
|
LL | fn use_<'b>(c: Invariant<'b>) {
| -- lifetime `'b` defined here
...
LL | let _: Invariant<'static> = c; //~ ERROR mismatched types
| ^ type annotation requires that `'b` must outlive `'static`
| ^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'static`

error: aborting due to previous error

2 changes: 1 addition & 1 deletion src/test/ui/try-block/try-block-bad-lifetime.stderr
Expand Up @@ -2,7 +2,7 @@ error[E0597]: `my_string` does not live long enough
--> $DIR/try-block-bad-lifetime.rs:25:33
|
LL | let result: Result<(), &str> = try {
| ------ borrow later used here
| ------ borrow later stored here
LL | let my_string = String::from("");
LL | let my_str: & str = & my_string;
| ^^^^^^^^^^^ borrowed value does not live long enough
Expand Down

0 comments on commit 55ec104

Please sign in to comment.