Skip to content

Commit 17b285d

Browse files
committed
Added UserAssertTy statement.
1 parent c0fdb29 commit 17b285d

File tree

19 files changed

+79
-6
lines changed

19 files changed

+79
-6
lines changed

src/librustc/ich/impls_mir.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,10 @@ for mir::StatementKind<'gcx> {
277277
op.hash_stable(hcx, hasher);
278278
places.hash_stable(hcx, hasher);
279279
}
280+
mir::StatementKind::UserAssertTy(ref ty, ref local) => {
281+
ty.hash_stable(hcx, hasher);
282+
local.hash_stable(hcx, hasher);
283+
}
280284
mir::StatementKind::Nop => {}
281285
mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
282286
asm.hash_stable(hcx, hasher);

src/librustc/mir/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,6 +1253,15 @@ pub enum StatementKind<'tcx> {
12531253
/// (The starting point(s) arise implicitly from borrows.)
12541254
EndRegion(region::Scope),
12551255

1256+
/// Encodes a user's type assertion. These need to be preserved intact so that NLL can respect
1257+
/// them. For example:
1258+
///
1259+
/// let (a, b): (T, U) = y;
1260+
///
1261+
/// Here we would insert a `UserAssertTy<(T, U)>(y)` instruction to check that the type of `y`
1262+
/// is the right thing.
1263+
UserAssertTy(Ty<'tcx>, Local),
1264+
12561265
/// No-op. Useful for deleting instructions without affecting statement indices.
12571266
Nop,
12581267
}
@@ -1324,6 +1333,7 @@ impl<'tcx> Debug for Statement<'tcx> {
13241333
InlineAsm { ref asm, ref outputs, ref inputs } => {
13251334
write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs)
13261335
},
1336+
UserAssertTy(ref ty, ref local) => write!(fmt, "UserAssertTy({:?}, {:?})", ty, local),
13271337
Nop => write!(fmt, "nop"),
13281338
}
13291339
}
@@ -2184,6 +2194,7 @@ EnumTypeFoldableImpl! {
21842194
(StatementKind::InlineAsm) { asm, outputs, inputs },
21852195
(StatementKind::Validate)(a, b),
21862196
(StatementKind::EndRegion)(a),
2197+
(StatementKind::UserAssertTy)(a, b),
21872198
(StatementKind::Nop),
21882199
}
21892200
}

src/librustc/mir/visit.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,13 @@ macro_rules! make_mir_visitor {
144144
self.super_operand(operand, location);
145145
}
146146

147+
fn visit_user_assert_ty(&mut self,
148+
ty: & $($mutability)* Ty<'tcx>,
149+
local: & $($mutability)* Local,
150+
location: Location) {
151+
self.super_user_assert_ty(ty, local, location);
152+
}
153+
147154
fn visit_place(&mut self,
148155
place: & $($mutability)* Place<'tcx>,
149156
context: PlaceContext<'tcx>,
@@ -376,6 +383,10 @@ macro_rules! make_mir_visitor {
376383
self.visit_operand(input, location);
377384
}
378385
}
386+
StatementKind::UserAssertTy(ref $($mutability)* ty,
387+
ref $($mutability)* local) => {
388+
self.visit_user_assert_ty(ty, local, location);
389+
}
379390
StatementKind::Nop => {}
380391
}
381392
}
@@ -619,6 +630,14 @@ macro_rules! make_mir_visitor {
619630
}
620631
}
621632

633+
fn super_user_assert_ty(&mut self,
634+
ty: & $($mutability)* Ty<'tcx>,
635+
local: & $($mutability)* Local,
636+
location: Location) {
637+
self.visit_ty(ty, TyContext::Location(location));
638+
self.visit_local(local, PlaceContext::Validate, location);
639+
}
640+
622641
fn super_place(&mut self,
623642
place: & $($mutability)* Place<'tcx>,
624643
context: PlaceContext<'tcx>,

src/librustc_mir/borrow_check/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -392,11 +392,13 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
392392
// ignored when consuming results (update to
393393
// flow_state already handled).
394394
}
395-
StatementKind::Nop | StatementKind::Validate(..) | StatementKind::StorageLive(..) => {
396-
// `Nop`, `Validate`, and `StorageLive` are irrelevant
395+
StatementKind::Nop |
396+
StatementKind::UserAssertTy(..) |
397+
StatementKind::Validate(..) |
398+
StatementKind::StorageLive(..) => {
399+
// `Nop`, `UserAssertTy`, `Validate`, and `StorageLive` are irrelevant
397400
// to borrow check.
398401
}
399-
400402
StatementKind::StorageDead(local) => {
401403
self.access_place(
402404
ContextKind::StorageDead.new(location),

src/librustc_mir/borrow_check/nll/type_check/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
766766
| StatementKind::InlineAsm { .. }
767767
| StatementKind::EndRegion(_)
768768
| StatementKind::Validate(..)
769+
| StatementKind::UserAssertTy(..)
769770
| StatementKind::Nop => {}
770771
}
771772
}

src/librustc_mir/build/block.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
102102
remainder_scope,
103103
init_scope,
104104
pattern,
105+
ty,
105106
initializer,
106107
lint_level
107108
} => {
@@ -120,12 +121,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
120121
opt_destruction_scope.map(|de|(de, source_info)), block, |this| {
121122
let scope = (init_scope, source_info);
122123
this.in_scope(scope, lint_level, block, |this| {
123-
this.expr_into_pattern(block, pattern, init)
124+
this.expr_into_pattern(block, ty, pattern, init)
124125
})
125126
}));
126127
} else {
127128
this.visit_bindings(&pattern, &mut |this, _, _, node, span, _| {
128129
this.storage_live_binding(block, node, span);
130+
if let Some(ty) = ty {
131+
this.user_assert_ty(block, ty, node, span);
132+
}
129133
this.schedule_drop_for_binding(node, span);
130134
})
131135
}

src/librustc_mir/build/matches/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,18 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
145145
end_block.unit()
146146
}
147147

148+
pub fn user_assert_ty(&mut self, block: BasicBlock, ty: Ty<'tcx>, var: NodeId, span: Span) {
149+
let local_id = self.var_indices[&var];
150+
let source_info = self.source_info(span);
151+
self.cfg.push(block, Statement {
152+
source_info,
153+
kind: StatementKind::UserAssertTy(ty, local_id),
154+
});
155+
}
156+
148157
pub fn expr_into_pattern(&mut self,
149158
mut block: BasicBlock,
159+
ty: Option<Ty<'tcx>>,
150160
irrefutable_pat: Pattern<'tcx>,
151161
initializer: ExprRef<'tcx>)
152162
-> BlockAnd<()> {
@@ -156,6 +166,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
156166
var,
157167
subpattern: None, .. } => {
158168
let place = self.storage_live_binding(block, var, irrefutable_pat.span);
169+
170+
if let Some(ty) = ty {
171+
self.user_assert_ty(block, ty, var, irrefutable_pat.span);
172+
}
173+
159174
unpack!(block = self.into(&place, block, initializer));
160175
self.schedule_drop_for_binding(var, irrefutable_pat.span);
161176
block.unit()

src/librustc_mir/dataflow/impls/borrows.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
678678
mir::StatementKind::SetDiscriminant { .. } |
679679
mir::StatementKind::StorageLive(..) |
680680
mir::StatementKind::Validate(..) |
681+
mir::StatementKind::UserAssertTy(..) |
681682
mir::StatementKind::Nop => {}
682683

683684
}

src/librustc_mir/dataflow/move_paths/builder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
298298
}
299299
StatementKind::EndRegion(_) |
300300
StatementKind::Validate(..) |
301+
StatementKind::UserAssertTy(..) |
301302
StatementKind::Nop => {}
302303
}
303304
}

src/librustc_mir/hair/cx/block.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,14 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
7676
first_statement_index: region::FirstStatementIndex::new(index),
7777
});
7878

79+
let ty = local.ty.clone().map(|ty| cx.tables().node_id_to_type(ty.hir_id));
7980
let pattern = cx.pattern_from_hir(&local.pat);
8081
result.push(StmtRef::Mirror(Box::new(Stmt {
8182
kind: StmtKind::Let {
8283
remainder_scope: remainder_scope,
8384
init_scope: region::Scope::Node(hir_id.local_id),
8485
pattern,
86+
ty,
8587
initializer: local.init.to_ref(),
8688
lint_level: cx.lint_level_of(local.id),
8789
},

0 commit comments

Comments
 (0)