Skip to content

Commit 40af99d

Browse files
committed
treat type ascriptions as rvalues
1 parent ad7ba4d commit 40af99d

File tree

7 files changed

+93
-125
lines changed

7 files changed

+93
-125
lines changed

compiler/rustc_hir/src/hir.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,10 +1430,8 @@ impl Expr<'_> {
14301430
matches!(path.res, Res::Local(..) | Res::Def(DefKind::Static, _) | Res::Err)
14311431
}
14321432

1433-
// Type ascription inherits its place expression kind from its
1434-
// operand. See:
1435-
// https://github.com/rust-lang/rfcs/blob/master/text/0803-type-ascription.md#type-ascription-and-temporaries
1436-
ExprKind::Type(ref e, _) => e.is_place_expr(allow_projections_from),
1433+
// We always treat type ascriptions as rvalues
1434+
ExprKind::Type(_, _) => false,
14371435

14381436
ExprKind::Unary(UnOp::UnDeref, _) => true,
14391437

compiler/rustc_mir_build/src/build/expr/as_place.rs

Lines changed: 47 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use crate::build::{BlockAnd, BlockAndExtension, Builder};
66
use crate::thir::*;
77
use rustc_hir::def_id::DefId;
88
use rustc_hir::HirId;
9-
use rustc_middle::middle::region;
109
use rustc_middle::hir::place::ProjectionKind as HirProjectionKind;
10+
use rustc_middle::middle::region;
1111
use rustc_middle::mir::AssertKind::BoundsCheck;
1212
use rustc_middle::mir::*;
1313
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, Variance};
@@ -57,7 +57,8 @@ crate enum PlaceBase {
5757
/// DefId of the closure
5858
closure_def_id: DefId,
5959
/// The trait closure implements, `Fn`, `FnMut`, `FnOnce`
60-
closure_kind: ty::ClosureKind },
60+
closure_kind: ty::ClosureKind,
61+
},
6162
}
6263

6364
/// `PlaceBuilder` is used to create places during MIR construction. It allows you to "build up" a
@@ -81,8 +82,7 @@ crate struct PlaceBuilder<'tcx> {
8182
fn convert_to_hir_projections_and_truncate_for_capture<'tcx>(
8283
mir_projections: &[PlaceElem<'tcx>],
8384
) -> Vec<HirProjectionKind> {
84-
85-
let mut hir_projections = Vec::new();
85+
let mut hir_projections = Vec::new();
8686

8787
for mir_projection in mir_projections {
8888
let hir_projection = match mir_projection {
@@ -91,20 +91,20 @@ fn convert_to_hir_projections_and_truncate_for_capture<'tcx>(
9191
// We will never encouter this for multivariant enums,
9292
// read the comment for `Downcast`.
9393
HirProjectionKind::Field(field.index() as u32, VariantIdx::new(0))
94-
},
94+
}
9595
ProjectionElem::Downcast(..) => {
9696
// This projections exist only for enums that have
9797
// multiple variants. Since such enums that are captured
9898
// completely, we can stop here.
99-
break
100-
},
99+
break;
100+
}
101101
ProjectionElem::Index(..)
102102
| ProjectionElem::ConstantIndex { .. }
103103
| ProjectionElem::Subslice { .. } => {
104104
// We don't capture array-access projections.
105105
// We can stop here as arrays are captured completely.
106-
break
107-
},
106+
break;
107+
}
108108
};
109109

110110
hir_projections.push(hir_projection);
@@ -181,9 +181,9 @@ fn find_capture_matching_projections<'a, 'tcx>(
181181
// If an ancestor is found, `idx` is the index within the list of captured places
182182
// for root variable `var_hir_id` and `capture` is the `ty::CapturedPlace` itself.
183183
let (idx, capture) = root_variable_min_captures.iter().enumerate().find(|(_, capture)| {
184-
let possible_ancestor_proj_kinds =
185-
capture.place.projections.iter().map(|proj| proj.kind).collect();
186-
is_ancestor_or_same_capture(&possible_ancestor_proj_kinds, &hir_projections)
184+
let possible_ancestor_proj_kinds =
185+
capture.place.projections.iter().map(|proj| proj.kind).collect();
186+
is_ancestor_or_same_capture(&possible_ancestor_proj_kinds, &hir_projections)
187187
})?;
188188

189189
// Convert index to be from the presepective of the entire closure_min_captures map
@@ -213,35 +213,34 @@ fn to_upvars_resolved_place_builder<'a, 'tcx>(
213213
ty::ClosureKind::FnOnce => {}
214214
}
215215

216-
let (capture_index, capture) =
217-
if let Some(capture_details) = find_capture_matching_projections(
216+
let (capture_index, capture) = if let Some(capture_details) =
217+
find_capture_matching_projections(
218218
typeck_results,
219219
var_hir_id,
220220
closure_def_id,
221221
&from_builder.projection,
222222
) {
223-
capture_details
224-
} else {
225-
if !tcx.features().capture_disjoint_fields {
226-
bug!(
227-
"No associated capture found for {:?}[{:#?}] even though \
223+
capture_details
224+
} else {
225+
if !tcx.features().capture_disjoint_fields {
226+
bug!(
227+
"No associated capture found for {:?}[{:#?}] even though \
228228
capture_disjoint_fields isn't enabled",
229-
var_hir_id,
230-
from_builder.projection
231-
)
232-
} else {
233-
// FIXME(project-rfc-2229#24): Handle this case properly
234-
debug!(
235-
"No associated capture found for {:?}[{:#?}]",
236-
var_hir_id,
237-
from_builder.projection,
238-
);
239-
}
240-
return Err(var_hir_id);
241-
};
229+
var_hir_id,
230+
from_builder.projection
231+
)
232+
} else {
233+
// FIXME(project-rfc-2229#24): Handle this case properly
234+
debug!(
235+
"No associated capture found for {:?}[{:#?}]",
236+
var_hir_id, from_builder.projection,
237+
);
238+
}
239+
return Err(var_hir_id);
240+
};
242241

243-
let closure_ty =
244-
typeck_results.node_type(tcx.hir().local_def_id_to_hir_id(closure_def_id.expect_local()));
242+
let closure_ty = typeck_results
243+
.node_type(tcx.hir().local_def_id_to_hir_id(closure_def_id.expect_local()));
245244

246245
let substs = match closure_ty.kind() {
247246
ty::Closure(_, substs) => ty::UpvarSubsts::Closure(substs),
@@ -256,7 +255,8 @@ fn to_upvars_resolved_place_builder<'a, 'tcx>(
256255
// we know that the capture exists and is the `capture_index`-th capture.
257256
let var_ty = substs.tupled_upvars_ty().tuple_element_ty(capture_index).unwrap();
258257

259-
upvar_resolved_place_builder = upvar_resolved_place_builder.field(Field::new(capture_index), var_ty);
258+
upvar_resolved_place_builder =
259+
upvar_resolved_place_builder.field(Field::new(capture_index), var_ty);
260260

261261
// If the variable is captured via ByRef(Immutable/Mutable) Borrow,
262262
// we need to deref it
@@ -270,8 +270,9 @@ fn to_upvars_resolved_place_builder<'a, 'tcx>(
270270

271271
// We used some of the projections to build the capture itself,
272272
// now we apply the remaining to the upvar resolved place.
273-
upvar_resolved_place_builder.projection.extend(
274-
curr_projections.drain(next_projection..));
273+
upvar_resolved_place_builder
274+
.projection
275+
.extend(curr_projections.drain(next_projection..));
275276

276277
Ok(upvar_resolved_place_builder)
277278
}
@@ -356,7 +357,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
356357

357358
/// This is used when constructing a compound `Place`, so that we can avoid creating
358359
/// intermediate `Place` values until we know the full set of projections.
359-
crate fn as_place_builder<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<PlaceBuilder<'tcx>>
360+
crate fn as_place_builder<M>(
361+
&mut self,
362+
block: BasicBlock,
363+
expr: M,
364+
) -> BlockAnd<PlaceBuilder<'tcx>>
360365
where
361366
M: Mirror<'tcx, Output = Expr<'tcx>>,
362367
{
@@ -456,38 +461,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
456461
block.and(place_builder)
457462
}
458463

459-
ExprKind::PlaceTypeAscription { source, user_ty } => {
460-
let source = this.hir.mirror(source);
461-
let place_builder = unpack!(
462-
block = this.expr_as_place(block, source, mutability, fake_borrow_temps,)
463-
);
464-
if let Some(user_ty) = user_ty {
465-
let annotation_index =
466-
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
467-
span: source_info.span,
468-
user_ty,
469-
inferred_ty: expr.ty,
470-
});
471-
472-
let place =
473-
place_builder.clone().into_place(this.hir.tcx(), this.hir.typeck_results());
474-
this.cfg.push(
475-
block,
476-
Statement {
477-
source_info,
478-
kind: StatementKind::AscribeUserType(
479-
box (
480-
place,
481-
UserTypeProjection { base: annotation_index, projs: vec![] },
482-
),
483-
Variance::Invariant,
484-
),
485-
},
486-
);
487-
}
488-
block.and(place_builder)
489-
}
490-
ExprKind::ValueTypeAscription { source, user_ty } => {
464+
ExprKind::TypeAscription { source, user_ty } => {
491465
let source = this.hir.mirror(source);
492466
let temp =
493467
unpack!(block = this.as_temp(block, source.temp_lifetime, source, mutability));
@@ -626,7 +600,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
626600
if is_outermost_index {
627601
self.read_fake_borrows(block, fake_borrow_temps, source_info)
628602
} else {
629-
base_place = base_place.expect_upvars_resolved(self.hir.tcx(), self.hir.typeck_results());
603+
base_place =
604+
base_place.expect_upvars_resolved(self.hir.tcx(), self.hir.typeck_results());
630605
self.add_fake_borrows_of_base(
631606
&base_place,
632607
block,
@@ -678,7 +653,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
678653
let tcx = self.hir.tcx();
679654
let local = match base_place.base {
680655
PlaceBase::Local(local) => local,
681-
PlaceBase::Upvar { .. } => bug!("Expected PlacseBase::Local found Upvar")
656+
PlaceBase::Upvar { .. } => bug!("Expected PlacseBase::Local found Upvar"),
682657
};
683658

684659
let place_ty = Place::ty_from(local, &base_place.projection, &self.local_decls, tcx);

compiler/rustc_mir_build/src/build/expr/as_rvalue.rs

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
33
use rustc_index::vec::Idx;
44

5+
use crate::build::expr::as_place::PlaceBase;
56
use crate::build::expr::category::{Category, RvalueFunc};
67
use crate::build::{BlockAnd, BlockAndExtension, Builder};
7-
use crate::build::expr::as_place::PlaceBase;
88
use crate::thir::*;
99
use rustc_middle::middle::region;
1010
use rustc_middle::mir::AssertKind;
@@ -269,11 +269,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
269269
| ExprKind::Return { .. }
270270
| ExprKind::InlineAsm { .. }
271271
| ExprKind::LlvmInlineAsm { .. }
272-
| ExprKind::PlaceTypeAscription { .. }
273-
| ExprKind::ValueTypeAscription { .. } => {
272+
| ExprKind::TypeAscription { .. } => {
274273
// these do not have corresponding `Rvalue` variants,
275274
// so make an operand and then return that
276-
debug_assert!(!matches!(Category::of(&expr.kind), Some(Category::Rvalue(RvalueFunc::AsRvalue))));
275+
debug_assert!(!matches!(
276+
Category::of(&expr.kind),
277+
Some(Category::Rvalue(RvalueFunc::AsRvalue))
278+
));
277279
let operand = unpack!(block = this.as_operand(block, scope, expr));
278280
block.and(Rvalue::Use(operand))
279281
}
@@ -400,34 +402,39 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
400402
// We are capturing a path that starts off a local variable in the parent.
401403
// The mutability of the current capture is same as the mutability
402404
// of the local declaration in the parent.
403-
PlaceBase::Local(local) => this.local_decls[local].mutability,
405+
PlaceBase::Local(local) => this.local_decls[local].mutability,
404406
// Parent is a closure and we are capturing a path that is captured
405407
// by the parent itself. The mutability of the current capture
406408
// is same as that of the capture in the parent closure.
407409
PlaceBase::Upvar { .. } => {
408-
let enclosing_upvars_resolved = arg_place_builder.clone().into_place(
409-
this.hir.tcx(),
410-
this.hir.typeck_results());
410+
let enclosing_upvars_resolved =
411+
arg_place_builder.clone().into_place(this.hir.tcx(), this.hir.typeck_results());
411412

412413
match enclosing_upvars_resolved.as_ref() {
413-
PlaceRef { local, projection: &[ProjectionElem::Field(upvar_index, _), ..] }
414+
PlaceRef {
415+
local,
416+
projection: &[ProjectionElem::Field(upvar_index, _), ..],
417+
}
414418
| PlaceRef {
415419
local,
416-
projection: &[ProjectionElem::Deref, ProjectionElem::Field(upvar_index, _), ..] } => {
417-
// Not in a closure
418-
debug_assert!(
419-
local == Local::new(1),
420-
"Expected local to be Local(1), found {:?}",
421-
local
422-
);
423-
// Not in a closure
424-
debug_assert!(
425-
this.upvar_mutbls.len() > upvar_index.index(),
426-
"Unexpected capture place, upvar_mutbls={:#?}, upvar_index={:?}",
427-
this.upvar_mutbls, upvar_index
428-
);
429-
this.upvar_mutbls[upvar_index.index()]
430-
}
420+
projection:
421+
&[ProjectionElem::Deref, ProjectionElem::Field(upvar_index, _), ..],
422+
} => {
423+
// Not in a closure
424+
debug_assert!(
425+
local == Local::new(1),
426+
"Expected local to be Local(1), found {:?}",
427+
local
428+
);
429+
// Not in a closure
430+
debug_assert!(
431+
this.upvar_mutbls.len() > upvar_index.index(),
432+
"Unexpected capture place, upvar_mutbls={:#?}, upvar_index={:?}",
433+
this.upvar_mutbls,
434+
upvar_index
435+
);
436+
this.upvar_mutbls[upvar_index.index()]
437+
}
431438
_ => bug!("Unexpected capture place"),
432439
}
433440
}
@@ -438,9 +445,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
438445
Mutability::Mut => BorrowKind::Mut { allow_two_phase_borrow: false },
439446
};
440447

441-
let arg_place = arg_place_builder.into_place(
442-
this.hir.tcx(),
443-
this.hir.typeck_results());
448+
let arg_place = arg_place_builder.into_place(this.hir.tcx(), this.hir.typeck_results());
444449

445450
this.cfg.push_assign(
446451
block,

compiler/rustc_mir_build/src/build/expr/category.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ impl Category {
4040
| ExprKind::Index { .. }
4141
| ExprKind::UpvarRef { .. }
4242
| ExprKind::VarRef { .. }
43-
| ExprKind::PlaceTypeAscription { .. }
44-
| ExprKind::ValueTypeAscription { .. } => Some(Category::Place),
43+
| ExprKind::TypeAscription { .. } => Some(Category::Place),
4544

4645
ExprKind::LogicalOp { .. }
4746
| ExprKind::Match { .. }

compiler/rustc_mir_build/src/build/expr/into.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
4040
let expr_span = expr.span;
4141
let source_info = this.source_info(expr_span);
4242

43-
let expr_is_block_or_scope = matches!(expr.kind, ExprKind::Block { .. } | ExprKind::Scope { .. });
43+
let expr_is_block_or_scope =
44+
matches!(expr.kind, ExprKind::Block { .. } | ExprKind::Scope { .. });
4445

4546
let schedule_drop = move |this: &mut Self| {
4647
if let Some(drop_scope) = scope {
@@ -71,11 +72,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
7172
}
7273
ExprKind::NeverToAny { source } => {
7374
let source = this.hir.mirror(source);
74-
let is_call = matches!(source.kind, ExprKind::Call { .. } | ExprKind::InlineAsm { .. });
75+
let is_call =
76+
matches!(source.kind, ExprKind::Call { .. } | ExprKind::InlineAsm { .. });
7577

7678
// (#66975) Source could be a const of type `!`, so has to
7779
// exist in the generated MIR.
78-
unpack!(block = this.as_temp(block, Some(this.local_scope()), source, Mutability::Mut,));
80+
unpack!(
81+
block = this.as_temp(block, Some(this.local_scope()), source, Mutability::Mut,)
82+
);
7983

8084
// This is an optimization. If the expression was a call then we already have an
8185
// unreachable block. Don't bother to terminate it and create a new one.
@@ -433,8 +437,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
433437
// Avoid creating a temporary
434438
ExprKind::VarRef { .. }
435439
| ExprKind::UpvarRef { .. }
436-
| ExprKind::PlaceTypeAscription { .. }
437-
| ExprKind::ValueTypeAscription { .. } => {
440+
| ExprKind::TypeAscription { .. } => {
438441
debug_assert!(Category::of(&expr.kind) == Some(Category::Place));
439442

440443
let place = unpack!(block = this.as_place(block, expr));

0 commit comments

Comments
 (0)