mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-04 19:12:50 +00:00
Pull thir::Cx
out of the MIR Builder
This commit is contained in:
parent
60def4de5e
commit
2a2b4d7257
@ -110,8 +110,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
let_scope_stack.push(remainder_scope);
|
||||
|
||||
// Declare the bindings, which may create a source scope.
|
||||
let remainder_span =
|
||||
remainder_scope.span(this.hir.tcx(), &this.hir.region_scope_tree);
|
||||
let remainder_span = remainder_scope.span(this.tcx, &this.region_scope_tree);
|
||||
|
||||
let visibility_scope =
|
||||
Some(this.new_source_scope(remainder_span, LintLevel::Inherited, None));
|
||||
@ -175,7 +174,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
// Then, the block may have an optional trailing expression which is a “return” value
|
||||
// of the block, which is stored into `destination`.
|
||||
let tcx = this.hir.tcx();
|
||||
let tcx = this.tcx;
|
||||
let destination_ty = destination.ty(&this.local_decls, tcx).ty;
|
||||
if let Some(expr) = expr {
|
||||
let tail_result_is_ignored =
|
||||
@ -195,7 +194,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
if destination_ty.is_unit() {
|
||||
// We only want to assign an implicit `()` as the return value of the block if the
|
||||
// block does not diverge. (Otherwise, we may try to assign a unit to a `!`-type.)
|
||||
this.cfg.push_assign_unit(block, source_info, destination, this.hir.tcx());
|
||||
this.cfg.push_assign_unit(block, source_info, destination, this.tcx);
|
||||
}
|
||||
}
|
||||
// Finally, we pop all the let scopes before exiting out from the scope of block
|
||||
@ -221,7 +220,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
Safety::Safe => {}
|
||||
// no longer treat `unsafe fn`s as `unsafe` contexts (see RFC #2585)
|
||||
Safety::FnUnsafe
|
||||
if self.hir.tcx().lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, hir_id).0
|
||||
if self.tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, hir_id).0
|
||||
!= Level::Allow => {}
|
||||
_ => return,
|
||||
}
|
||||
|
@ -136,12 +136,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
});
|
||||
}
|
||||
|
||||
let tcx = this.hir.tcx();
|
||||
let tcx = this.tcx;
|
||||
|
||||
if tcx.features().unsized_fn_params {
|
||||
let ty = expr.ty;
|
||||
let span = expr.span;
|
||||
let param_env = this.hir.param_env;
|
||||
let param_env = this.param_env;
|
||||
|
||||
if !ty.is_sized(tcx.at(span), param_env) {
|
||||
// !sized means !copy, so this is an unsized move
|
||||
|
@ -353,7 +353,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
expr: &Expr<'tcx>,
|
||||
) -> BlockAnd<Place<'tcx>> {
|
||||
let place_builder = unpack!(block = self.as_place_builder(block, expr));
|
||||
block.and(place_builder.into_place(self.hir.tcx(), self.hir.typeck_results()))
|
||||
block.and(place_builder.into_place(self.tcx, self.typeck_results))
|
||||
}
|
||||
|
||||
/// This is used when constructing a compound `Place`, so that we can avoid creating
|
||||
@ -377,7 +377,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
expr: &Expr<'tcx>,
|
||||
) -> BlockAnd<Place<'tcx>> {
|
||||
let place_builder = unpack!(block = self.as_read_only_place_builder(block, expr));
|
||||
block.and(place_builder.into_place(self.hir.tcx(), self.hir.typeck_results()))
|
||||
block.and(place_builder.into_place(self.tcx, self.typeck_results))
|
||||
}
|
||||
|
||||
/// This is used when constructing a compound `Place`, so that we can avoid creating
|
||||
@ -462,8 +462,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
inferred_ty: expr.ty,
|
||||
});
|
||||
|
||||
let place =
|
||||
place_builder.clone().into_place(this.hir.tcx(), this.hir.typeck_results());
|
||||
let place = place_builder.clone().into_place(this.tcx, this.typeck_results);
|
||||
this.cfg.push(
|
||||
block,
|
||||
Statement {
|
||||
@ -557,12 +556,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
upvar_id: ty::UpvarId,
|
||||
) -> BlockAnd<PlaceBuilder<'tcx>> {
|
||||
let closure_ty = self
|
||||
.hir
|
||||
.typeck_results()
|
||||
.node_type(self.hir.tcx().hir().local_def_id_to_hir_id(upvar_id.closure_expr_id));
|
||||
.typeck_results
|
||||
.node_type(self.tcx.hir().local_def_id_to_hir_id(upvar_id.closure_expr_id));
|
||||
|
||||
let closure_kind = if let ty::Closure(_, closure_substs) = closure_ty.kind() {
|
||||
self.hir.infcx().closure_kind(closure_substs).unwrap()
|
||||
self.infcx.closure_kind(closure_substs).unwrap()
|
||||
} else {
|
||||
// Generators are considered FnOnce.
|
||||
ty::ClosureKind::FnOnce
|
||||
@ -608,7 +606,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
block = self.bounds_check(
|
||||
block,
|
||||
base_place.clone().into_place(self.hir.tcx(), self.hir.typeck_results()),
|
||||
base_place.clone().into_place(self.tcx, self.typeck_results),
|
||||
idx,
|
||||
expr_span,
|
||||
source_info,
|
||||
@ -617,8 +615,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
if is_outermost_index {
|
||||
self.read_fake_borrows(block, fake_borrow_temps, source_info)
|
||||
} else {
|
||||
base_place =
|
||||
base_place.expect_upvars_resolved(self.hir.tcx(), self.hir.typeck_results());
|
||||
base_place = base_place.expect_upvars_resolved(self.tcx, self.typeck_results);
|
||||
self.add_fake_borrows_of_base(
|
||||
&base_place,
|
||||
block,
|
||||
@ -639,8 +636,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
expr_span: Span,
|
||||
source_info: SourceInfo,
|
||||
) -> BasicBlock {
|
||||
let usize_ty = self.hir.usize_ty();
|
||||
let bool_ty = self.hir.bool_ty();
|
||||
let usize_ty = self.tcx.types.usize;
|
||||
let bool_ty = self.tcx.types.bool;
|
||||
// bounds check:
|
||||
let len = self.temp(usize_ty, expr_span);
|
||||
let lt = self.temp(bool_ty, expr_span);
|
||||
@ -670,7 +667,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
expr_span: Span,
|
||||
source_info: SourceInfo,
|
||||
) {
|
||||
let tcx = self.hir.tcx();
|
||||
let tcx = self.tcx;
|
||||
let local = match base_place.base {
|
||||
PlaceBase::Local(local) => local,
|
||||
PlaceBase::Upvar { .. } => bug!("Expected PlacseBase::Local found Upvar"),
|
||||
|
@ -61,8 +61,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
ExprKind::Unary { op, arg } => {
|
||||
let arg = unpack!(block = this.as_operand(block, scope, &arg));
|
||||
// Check for -MIN on signed integers
|
||||
if this.hir.check_overflow() && *op == UnOp::Neg && expr.ty.is_signed() {
|
||||
let bool_ty = this.hir.bool_ty();
|
||||
if this.check_overflow && *op == UnOp::Neg && expr.ty.is_signed() {
|
||||
let bool_ty = this.tcx.types.bool;
|
||||
|
||||
let minval = this.minval_literal(expr_span, expr.ty);
|
||||
let is_min = this.temp(bool_ty, expr_span);
|
||||
@ -105,7 +105,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// initialize the box contents:
|
||||
unpack!(
|
||||
block = this.expr_into_dest(
|
||||
this.hir.tcx().mk_place_deref(Place::from(result)),
|
||||
this.tcx.mk_place_deref(Place::from(result)),
|
||||
block,
|
||||
&value
|
||||
)
|
||||
@ -148,7 +148,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// to the same MIR as `let x = ();`.
|
||||
|
||||
// first process the set of fields
|
||||
let el_ty = expr.ty.sequence_element_type(this.hir.tcx());
|
||||
let el_ty = expr.ty.sequence_element_type(this.tcx);
|
||||
let fields: Vec<_> = fields
|
||||
.into_iter()
|
||||
.map(|f| unpack!(block = this.as_operand(block, scope, &f)))
|
||||
@ -221,7 +221,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
block.and(Rvalue::Use(Operand::Constant(box Constant {
|
||||
span: expr_span,
|
||||
user_ty: None,
|
||||
literal: ty::Const::zero_sized(this.hir.tcx(), this.hir.tcx().types.unit),
|
||||
literal: ty::Const::zero_sized(this.tcx, this.tcx.types.unit),
|
||||
})))
|
||||
}
|
||||
ExprKind::Yield { .. }
|
||||
@ -273,9 +273,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
rhs: Operand<'tcx>,
|
||||
) -> BlockAnd<Rvalue<'tcx>> {
|
||||
let source_info = self.source_info(span);
|
||||
let bool_ty = self.hir.bool_ty();
|
||||
if self.hir.check_overflow() && op.is_checkable() && ty.is_integral() {
|
||||
let result_tup = self.hir.tcx().intern_tup(&[ty, bool_ty]);
|
||||
let bool_ty = self.tcx.types.bool;
|
||||
if self.check_overflow && op.is_checkable() && ty.is_integral() {
|
||||
let result_tup = self.tcx.intern_tup(&[ty, bool_ty]);
|
||||
let result_value = self.temp(result_tup, span);
|
||||
|
||||
self.cfg.push_assign(
|
||||
@ -287,7 +287,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
let val_fld = Field::new(0);
|
||||
let of_fld = Field::new(1);
|
||||
|
||||
let tcx = self.hir.tcx();
|
||||
let tcx = self.tcx;
|
||||
let val = tcx.mk_place_field(result_value, val_fld, ty);
|
||||
let of = tcx.mk_place_field(result_value, of_fld, bool_ty);
|
||||
|
||||
@ -389,7 +389,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// is same as that of the capture in the parent closure.
|
||||
PlaceBase::Upvar { .. } => {
|
||||
let enclosing_upvars_resolved =
|
||||
arg_place_builder.clone().into_place(this.hir.tcx(), this.hir.typeck_results());
|
||||
arg_place_builder.clone().into_place(this.tcx, this.typeck_results);
|
||||
|
||||
match enclosing_upvars_resolved.as_ref() {
|
||||
PlaceRef {
|
||||
@ -426,13 +426,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
Mutability::Mut => BorrowKind::Mut { allow_two_phase_borrow: false },
|
||||
};
|
||||
|
||||
let arg_place = arg_place_builder.into_place(this.hir.tcx(), this.hir.typeck_results());
|
||||
let arg_place = arg_place_builder.into_place(this.tcx, this.typeck_results);
|
||||
|
||||
this.cfg.push_assign(
|
||||
block,
|
||||
source_info,
|
||||
Place::from(temp),
|
||||
Rvalue::Ref(this.hir.tcx().lifetimes.re_erased, borrow_kind, arg_place),
|
||||
Rvalue::Ref(this.tcx.lifetimes.re_erased, borrow_kind, arg_place),
|
||||
);
|
||||
|
||||
// See the comment in `expr_as_temp` and on the `rvalue_scopes` field for why
|
||||
@ -447,9 +447,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// Helper to get a `-1` value of the appropriate type
|
||||
fn neg_1_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
|
||||
let param_ty = ty::ParamEnv::empty().and(ty);
|
||||
let bits = self.hir.tcx().layout_of(param_ty).unwrap().size.bits();
|
||||
let bits = self.tcx.layout_of(param_ty).unwrap().size.bits();
|
||||
let n = (!0u128) >> (128 - bits);
|
||||
let literal = ty::Const::from_bits(self.hir.tcx(), n, param_ty);
|
||||
let literal = ty::Const::from_bits(self.tcx, n, param_ty);
|
||||
|
||||
self.literal_operand(span, literal)
|
||||
}
|
||||
@ -458,9 +458,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
fn minval_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
|
||||
assert!(ty.is_signed());
|
||||
let param_ty = ty::ParamEnv::empty().and(ty);
|
||||
let bits = self.hir.tcx().layout_of(param_ty).unwrap().size.bits();
|
||||
let bits = self.tcx.layout_of(param_ty).unwrap().size.bits();
|
||||
let n = 1 << (bits - 1);
|
||||
let literal = ty::Const::from_bits(self.hir.tcx(), n, param_ty);
|
||||
let literal = ty::Const::from_bits(self.tcx, n, param_ty);
|
||||
|
||||
self.literal_operand(span, literal)
|
||||
}
|
||||
|
@ -59,13 +59,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
}
|
||||
match expr.kind {
|
||||
ExprKind::StaticRef { def_id, .. } => {
|
||||
assert!(!this.hir.tcx().is_thread_local_static(def_id));
|
||||
assert!(!this.tcx.is_thread_local_static(def_id));
|
||||
local_decl.internal = true;
|
||||
local_decl.local_info =
|
||||
Some(box LocalInfo::StaticRef { def_id, is_thread_local: false });
|
||||
}
|
||||
ExprKind::ThreadLocalRef(def_id) => {
|
||||
assert!(this.hir.tcx().is_thread_local_static(def_id));
|
||||
assert!(this.tcx.is_thread_local_static(def_id));
|
||||
local_decl.internal = true;
|
||||
local_decl.local_info =
|
||||
Some(box LocalInfo::StaticRef { def_id, is_thread_local: true });
|
||||
|
@ -7,8 +7,9 @@ use rustc_ast::InlineAsmOptions;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_hir as hir;
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::CanonicalUserTypeAnnotation;
|
||||
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation};
|
||||
|
||||
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
/// Compile `expr`, storing the result into `destination`, which
|
||||
@ -58,7 +59,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
let mut then_block = this.cfg.start_new_block();
|
||||
let mut else_block = this.cfg.start_new_block();
|
||||
let term = TerminatorKind::if_(this.hir.tcx(), operand, then_block, else_block);
|
||||
let term = TerminatorKind::if_(this.tcx, operand, then_block, else_block);
|
||||
this.cfg.terminate(block, source_info, term);
|
||||
|
||||
unpack!(then_block = this.expr_into_dest(destination, then_block, &then));
|
||||
@ -68,7 +69,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// Body of the `if` expression without an `else` clause must return `()`, thus
|
||||
// we implicitly generate a `else {}` if it is not specified.
|
||||
let correct_si = this.source_info(expr_span.shrink_to_hi());
|
||||
this.cfg.push_assign_unit(else_block, correct_si, destination, this.hir.tcx());
|
||||
this.cfg.push_assign_unit(else_block, correct_si, destination, this.tcx);
|
||||
else_block
|
||||
};
|
||||
|
||||
@ -132,25 +133,33 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
LogicalOp::And => (else_block, false_block),
|
||||
LogicalOp::Or => (true_block, else_block),
|
||||
};
|
||||
let term = TerminatorKind::if_(this.hir.tcx(), lhs, blocks.0, blocks.1);
|
||||
let term = TerminatorKind::if_(this.tcx, lhs, blocks.0, blocks.1);
|
||||
this.cfg.terminate(block, source_info, term);
|
||||
|
||||
let rhs = unpack!(else_block = this.as_local_operand(else_block, &rhs));
|
||||
let term = TerminatorKind::if_(this.hir.tcx(), rhs, true_block, false_block);
|
||||
let term = TerminatorKind::if_(this.tcx, rhs, true_block, false_block);
|
||||
this.cfg.terminate(else_block, source_info, term);
|
||||
|
||||
this.cfg.push_assign_constant(
|
||||
true_block,
|
||||
source_info,
|
||||
destination,
|
||||
Constant { span: expr_span, user_ty: None, literal: this.hir.true_literal() },
|
||||
Constant {
|
||||
span: expr_span,
|
||||
user_ty: None,
|
||||
literal: ty::Const::from_bool(this.tcx, true),
|
||||
},
|
||||
);
|
||||
|
||||
this.cfg.push_assign_constant(
|
||||
false_block,
|
||||
source_info,
|
||||
destination,
|
||||
Constant { span: expr_span, user_ty: None, literal: this.hir.false_literal() },
|
||||
Constant {
|
||||
span: expr_span,
|
||||
user_ty: None,
|
||||
literal: ty::Const::from_bool(this.tcx, false),
|
||||
},
|
||||
);
|
||||
|
||||
// Link up both branches:
|
||||
@ -241,8 +250,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
BorrowKind::Shared => unpack!(block = this.as_read_only_place(block, &arg)),
|
||||
_ => unpack!(block = this.as_place(block, &arg)),
|
||||
};
|
||||
let borrow =
|
||||
Rvalue::Ref(this.hir.tcx().lifetimes.re_erased, *borrow_kind, arg_place);
|
||||
let borrow = Rvalue::Ref(this.tcx.lifetimes.re_erased, *borrow_kind, arg_place);
|
||||
this.cfg.push_assign(block, source_info, destination, borrow);
|
||||
block.unit()
|
||||
}
|
||||
@ -272,7 +280,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let field_names = this.hir.all_fields(adt_def, *variant_index);
|
||||
let field_names: Vec<_> =
|
||||
(0..adt_def.variants[*variant_index].fields.len()).map(Field::new).collect();
|
||||
|
||||
let fields: Vec<_> = if let Some(FruInfo { base, field_types }) = base {
|
||||
let place_builder = unpack!(block = this.as_place_builder(block, &base));
|
||||
@ -290,7 +299,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
this.consume_by_copy_or_move(
|
||||
place_builder
|
||||
.field(n, ty)
|
||||
.into_place(this.hir.tcx(), this.hir.typeck_results()),
|
||||
.into_place(this.tcx, this.typeck_results),
|
||||
)
|
||||
}
|
||||
})
|
||||
@ -398,7 +407,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
| ExprKind::AssignOp { .. }
|
||||
| ExprKind::LlvmInlineAsm { .. } => {
|
||||
unpack!(block = this.stmt_expr(block, expr, None));
|
||||
this.cfg.push_assign_unit(block, source_info, destination, this.hir.tcx());
|
||||
this.cfg.push_assign_unit(block, source_info, destination, this.tcx);
|
||||
block.unit()
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
// Generate better code for things that don't need to be
|
||||
// dropped.
|
||||
if this.hir.needs_drop(lhs.ty) {
|
||||
if lhs.ty.needs_drop(this.tcx, this.param_env) {
|
||||
let rhs = unpack!(block = this.as_local_operand(block, &rhs));
|
||||
let lhs = unpack!(block = this.as_place(block, &lhs));
|
||||
unpack!(block = this.build_drop_and_replace(block, lhs_span, lhs, rhs));
|
||||
|
@ -413,7 +413,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
let ty_source_info = self.source_info(user_ty_span);
|
||||
let user_ty = pat_ascription_ty.user_ty(
|
||||
&mut self.canonical_user_type_annotations,
|
||||
place.ty(&self.local_decls, self.hir.tcx()).ty,
|
||||
place.ty(&self.local_decls, self.tcx).ty,
|
||||
ty_source_info.span,
|
||||
);
|
||||
self.cfg.push(
|
||||
@ -555,7 +555,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
let local_id = self.var_local_id(var, for_guard);
|
||||
let source_info = self.source_info(span);
|
||||
self.cfg.push(block, Statement { source_info, kind: StatementKind::StorageLive(local_id) });
|
||||
let region_scope = self.hir.region_scope_tree.var_scope(var.local_id);
|
||||
let region_scope = self.region_scope_tree.var_scope(var.local_id);
|
||||
if schedule_drop {
|
||||
self.schedule_drop(span, region_scope, local_id, DropKind::Storage);
|
||||
}
|
||||
@ -564,7 +564,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
crate fn schedule_drop_for_binding(&mut self, var: HirId, span: Span, for_guard: ForGuard) {
|
||||
let local_id = self.var_local_id(var, for_guard);
|
||||
let region_scope = self.hir.region_scope_tree.var_scope(var.local_id);
|
||||
let region_scope = self.region_scope_tree.var_scope(var.local_id);
|
||||
self.schedule_drop(span, region_scope, local_id, DropKind::Value);
|
||||
}
|
||||
|
||||
@ -1070,7 +1070,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
fake_borrows.insert(Place {
|
||||
local: source.local,
|
||||
projection: self.hir.tcx().intern_place_elems(proj_base),
|
||||
projection: self.tcx.intern_place_elems(proj_base),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1549,7 +1549,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
fake_borrows: &'b FxHashSet<Place<'tcx>>,
|
||||
temp_span: Span,
|
||||
) -> Vec<(Place<'tcx>, Local)> {
|
||||
let tcx = self.hir.tcx();
|
||||
let tcx = self.tcx;
|
||||
|
||||
debug!("add_fake_borrows fake_borrows = {:?}", fake_borrows);
|
||||
|
||||
@ -1726,7 +1726,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// * So we eagerly create the reference for the arm and then take a
|
||||
// reference to that.
|
||||
if let Some(guard) = guard {
|
||||
let tcx = self.hir.tcx();
|
||||
let tcx = self.tcx;
|
||||
let bindings = parent_bindings
|
||||
.iter()
|
||||
.flat_map(|(bindings, _)| bindings)
|
||||
@ -1885,7 +1885,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
let user_ty = ascription.user_ty.clone().user_ty(
|
||||
&mut self.canonical_user_type_annotations,
|
||||
ascription.source.ty(&self.local_decls, self.hir.tcx()).ty,
|
||||
ascription.source.ty(&self.local_decls, self.tcx).ty,
|
||||
source_info.span,
|
||||
);
|
||||
self.cfg.push(
|
||||
@ -1914,7 +1914,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// Assign each of the bindings. Since we are binding for a
|
||||
// guard expression, this will never trigger moves out of the
|
||||
// candidate.
|
||||
let re_erased = self.hir.tcx().lifetimes.re_erased;
|
||||
let re_erased = self.tcx.lifetimes.re_erased;
|
||||
for binding in bindings {
|
||||
debug!("bind_matched_candidate_for_guard(binding={:?})", binding);
|
||||
let source_info = self.source_info(binding.span);
|
||||
@ -1963,7 +1963,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
{
|
||||
debug!("bind_matched_candidate_for_arm_body(block={:?})", block);
|
||||
|
||||
let re_erased = self.hir.tcx().lifetimes.re_erased;
|
||||
let re_erased = self.tcx.lifetimes.re_erased;
|
||||
// Assign each of the bindings. This may trigger moves out of the candidate.
|
||||
for binding in bindings {
|
||||
let source_info = self.source_info(binding.span);
|
||||
@ -2012,7 +2012,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
var_id, name, mode, var_ty, visibility_scope, source_info
|
||||
);
|
||||
|
||||
let tcx = self.hir.tcx();
|
||||
let tcx = self.tcx;
|
||||
let debug_source_info = SourceInfo { span: source_info.span, scope: visibility_scope };
|
||||
let binding_mode = match mode {
|
||||
BindingMode::ByValue => ty::BindingMode::BindByValue(mutability),
|
||||
|
@ -147,7 +147,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
match_pair: MatchPair<'pat, 'tcx>,
|
||||
candidate: &mut Candidate<'pat, 'tcx>,
|
||||
) -> Result<(), MatchPair<'pat, 'tcx>> {
|
||||
let tcx = self.hir.tcx();
|
||||
let tcx = self.tcx;
|
||||
match *match_pair.pattern.kind {
|
||||
PatKind::AscribeUserType {
|
||||
ref subpattern,
|
||||
@ -251,13 +251,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
PatKind::Variant { adt_def, substs, variant_index, ref subpatterns } => {
|
||||
let irrefutable = adt_def.variants.iter_enumerated().all(|(i, v)| {
|
||||
i == variant_index || {
|
||||
self.hir.tcx().features().exhaustive_patterns
|
||||
self.tcx.features().exhaustive_patterns
|
||||
&& !v
|
||||
.uninhabited_from(
|
||||
self.hir.tcx(),
|
||||
self.tcx,
|
||||
substs,
|
||||
adt_def.adt_kind(),
|
||||
self.hir.param_env,
|
||||
self.param_env,
|
||||
)
|
||||
.is_empty()
|
||||
}
|
||||
|
@ -13,9 +13,11 @@ use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_hir::{LangItem, RangeEnd};
|
||||
use rustc_index::bit_set::BitSet;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::subst::{GenericArg, Subst};
|
||||
use rustc_middle::ty::util::IntTypeExt;
|
||||
use rustc_middle::ty::{self, adjustment::PointerCast, Ty};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
|
||||
use std::cmp::Ordering;
|
||||
@ -93,9 +95,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
match *match_pair.pattern.kind {
|
||||
PatKind::Constant { value } => {
|
||||
options.entry(value).or_insert_with(|| {
|
||||
value.eval_bits(self.hir.tcx(), self.hir.param_env, switch_ty)
|
||||
});
|
||||
options
|
||||
.entry(value)
|
||||
.or_insert_with(|| value.eval_bits(self.tcx, self.param_env, switch_ty));
|
||||
true
|
||||
}
|
||||
PatKind::Variant { .. } => {
|
||||
@ -157,7 +159,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
"perform_test({:?}, {:?}: {:?}, {:?})",
|
||||
block,
|
||||
place,
|
||||
place.ty(&self.local_decls, self.hir.tcx()),
|
||||
place.ty(&self.local_decls, self.tcx),
|
||||
test
|
||||
);
|
||||
|
||||
@ -169,7 +171,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
let num_enum_variants = adt_def.variants.len();
|
||||
debug_assert_eq!(target_blocks.len(), num_enum_variants + 1);
|
||||
let otherwise_block = *target_blocks.last().unwrap();
|
||||
let tcx = self.hir.tcx();
|
||||
let tcx = self.tcx;
|
||||
let switch_targets = SwitchTargets::new(
|
||||
adt_def.discriminants(tcx).filter_map(|(idx, discr)| {
|
||||
if variants.contains(idx) {
|
||||
@ -217,7 +219,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
0 => (second_bb, first_bb),
|
||||
v => span_bug!(test.span, "expected boolean value but got {:?}", v),
|
||||
};
|
||||
TerminatorKind::if_(self.hir.tcx(), Operand::Copy(place), true_bb, false_bb)
|
||||
TerminatorKind::if_(self.tcx, Operand::Copy(place), true_bb, false_bb)
|
||||
} else {
|
||||
bug!("`TestKind::SwitchInt` on `bool` should have two targets")
|
||||
}
|
||||
@ -292,7 +294,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
TestKind::Len { len, op } => {
|
||||
let target_blocks = make_target_blocks(self);
|
||||
|
||||
let usize_ty = self.hir.usize_ty();
|
||||
let usize_ty = self.tcx.types.usize;
|
||||
let actual = self.temp(usize_ty, test.span);
|
||||
|
||||
// actual = len(place)
|
||||
@ -331,7 +333,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
left: Operand<'tcx>,
|
||||
right: Operand<'tcx>,
|
||||
) {
|
||||
let bool_ty = self.hir.bool_ty();
|
||||
let bool_ty = self.tcx.types.bool;
|
||||
let result = self.temp(bool_ty, source_info.span);
|
||||
|
||||
// result = op(left, right)
|
||||
@ -341,7 +343,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
self.cfg.terminate(
|
||||
block,
|
||||
source_info,
|
||||
TerminatorKind::if_(self.hir.tcx(), Operand::Move(result), success_block, fail_block),
|
||||
TerminatorKind::if_(self.tcx, Operand::Move(result), success_block, fail_block),
|
||||
);
|
||||
}
|
||||
|
||||
@ -377,7 +379,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// nothing to do, neither is an array
|
||||
(None, None) => {}
|
||||
(Some((region, elem_ty, _)), _) | (None, Some((region, elem_ty, _))) => {
|
||||
let tcx = self.hir.tcx();
|
||||
let tcx = self.tcx;
|
||||
// make both a slice
|
||||
ty = tcx.mk_imm_ref(region, tcx.mk_slice(elem_ty));
|
||||
if opt_ref_ty.is_some() {
|
||||
@ -408,10 +410,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
_ => bug!("non_scalar_compare called on non-reference type: {}", ty),
|
||||
};
|
||||
|
||||
let eq_def_id = self.hir.tcx().require_lang_item(LangItem::PartialEq, None);
|
||||
let method = self.hir.trait_method(eq_def_id, sym::eq, deref_ty, &[deref_ty.into()]);
|
||||
let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, None);
|
||||
let method = trait_method(self.tcx, eq_def_id, sym::eq, deref_ty, &[deref_ty.into()]);
|
||||
|
||||
let bool_ty = self.hir.bool_ty();
|
||||
let bool_ty = self.tcx.types.bool;
|
||||
let eq_result = self.temp(bool_ty, source_info.span);
|
||||
let eq_block = self.cfg.start_new_block();
|
||||
self.cfg.terminate(
|
||||
@ -443,12 +445,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
self.cfg.terminate(
|
||||
eq_block,
|
||||
source_info,
|
||||
TerminatorKind::if_(
|
||||
self.hir.tcx(),
|
||||
Operand::Move(eq_result),
|
||||
success_block,
|
||||
fail_block,
|
||||
),
|
||||
TerminatorKind::if_(self.tcx, Operand::Move(eq_result), success_block, fail_block),
|
||||
);
|
||||
} else {
|
||||
bug!("`TestKind::Eq` should have two target blocks")
|
||||
@ -632,11 +629,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
use rustc_hir::RangeEnd::*;
|
||||
use std::cmp::Ordering::*;
|
||||
|
||||
let tcx = self.hir.tcx();
|
||||
let tcx = self.tcx;
|
||||
|
||||
let test_ty = test.lo.ty;
|
||||
let lo = compare_const_vals(tcx, test.lo, pat.hi, self.hir.param_env, test_ty)?;
|
||||
let hi = compare_const_vals(tcx, test.hi, pat.lo, self.hir.param_env, test_ty)?;
|
||||
let lo = compare_const_vals(tcx, test.lo, pat.hi, self.param_env, test_ty)?;
|
||||
let hi = compare_const_vals(tcx, test.hi, pat.lo, self.param_env, test_ty)?;
|
||||
|
||||
match (test.end, pat.end, lo, hi) {
|
||||
// pat < test
|
||||
@ -731,7 +728,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
candidate: &mut Candidate<'pat, 'tcx>,
|
||||
) {
|
||||
let match_pair = candidate.match_pairs.remove(match_pair_index);
|
||||
let tcx = self.hir.tcx();
|
||||
let tcx = self.tcx;
|
||||
|
||||
// So, if we have a match-pattern like `x @ Enum::Variant(P1, P2)`,
|
||||
// we want to create a set of derived match-patterns like
|
||||
@ -762,10 +759,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
) -> Option<bool> {
|
||||
use std::cmp::Ordering::*;
|
||||
|
||||
let tcx = self.hir.tcx();
|
||||
let tcx = self.tcx;
|
||||
|
||||
let a = compare_const_vals(tcx, range.lo, value, self.hir.param_env, range.lo.ty)?;
|
||||
let b = compare_const_vals(tcx, value, range.hi, self.hir.param_env, range.lo.ty)?;
|
||||
let a = compare_const_vals(tcx, range.lo, value, self.param_env, range.lo.ty)?;
|
||||
let b = compare_const_vals(tcx, value, range.hi, self.param_env, range.lo.ty)?;
|
||||
|
||||
match (b, range.end) {
|
||||
(Less, _) | (Equal, RangeEnd::Included) if a != Greater => Some(true),
|
||||
@ -815,3 +812,25 @@ impl Test<'_> {
|
||||
fn is_switch_ty(ty: Ty<'_>) -> bool {
|
||||
ty.is_integral() || ty.is_char() || ty.is_bool()
|
||||
}
|
||||
|
||||
fn trait_method<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
method_name: Symbol,
|
||||
self_ty: Ty<'tcx>,
|
||||
params: &[GenericArg<'tcx>],
|
||||
) -> &'tcx ty::Const<'tcx> {
|
||||
let substs = tcx.mk_substs_trait(self_ty, params);
|
||||
|
||||
// The unhygienic comparison here is acceptable because this is only
|
||||
// used on known traits.
|
||||
let item = tcx
|
||||
.associated_items(trait_def_id)
|
||||
.filter_by_name_unhygienic(method_name)
|
||||
.find(|item| item.kind == ty::AssocKind::Fn)
|
||||
.expect("trait method not found");
|
||||
|
||||
let method_ty = tcx.type_of(item.def_id);
|
||||
let method_ty = method_ty.subst(tcx, substs);
|
||||
ty::Const::zero_sized(tcx, method_ty)
|
||||
}
|
||||
|
@ -15,8 +15,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
subpatterns
|
||||
.iter()
|
||||
.map(|fieldpat| {
|
||||
let place =
|
||||
self.hir.tcx().mk_place_field(place, fieldpat.field, fieldpat.pattern.ty);
|
||||
let place = self.tcx.mk_place_field(place, fieldpat.field, fieldpat.pattern.ty);
|
||||
MatchPair::new(place, &fieldpat.pattern)
|
||||
})
|
||||
.collect()
|
||||
@ -30,9 +29,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
opt_slice: Option<&'pat Pat<'tcx>>,
|
||||
suffix: &'pat [Pat<'tcx>],
|
||||
) {
|
||||
let tcx = self.hir.tcx();
|
||||
let tcx = self.tcx;
|
||||
let (min_length, exact_size) = match place.ty(&self.local_decls, tcx).ty.kind() {
|
||||
ty::Array(_, length) => (length.eval_usize(tcx, self.hir.param_env), true),
|
||||
ty::Array(_, length) => (length.eval_usize(tcx, self.param_env), true),
|
||||
_ => ((prefix.len() + suffix.len()).try_into().unwrap(), false),
|
||||
};
|
||||
|
||||
|
@ -3,10 +3,10 @@
|
||||
|
||||
use crate::build::Builder;
|
||||
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
|
||||
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
/// Adds a new temporary value of type `ty` storing the result of
|
||||
@ -37,7 +37,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// Returns a zero literal operand for the appropriate type, works for
|
||||
// bool, char and integers.
|
||||
crate fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
|
||||
let literal = ty::Const::from_bits(self.hir.tcx(), 0, ty::ParamEnv::empty().and(ty));
|
||||
let literal = ty::Const::from_bits(self.tcx, 0, ty::ParamEnv::empty().and(ty));
|
||||
|
||||
self.literal_operand(span, literal)
|
||||
}
|
||||
@ -48,7 +48,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
source_info: SourceInfo,
|
||||
value: u64,
|
||||
) -> Place<'tcx> {
|
||||
let usize_ty = self.hir.usize_ty();
|
||||
let usize_ty = self.tcx.types.usize;
|
||||
let temp = self.temp(usize_ty, source_info.span);
|
||||
self.cfg.push_assign_constant(
|
||||
block,
|
||||
@ -57,16 +57,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
Constant {
|
||||
span: source_info.span,
|
||||
user_ty: None,
|
||||
literal: self.hir.usize_literal(value),
|
||||
literal: ty::Const::from_usize(self.tcx, value),
|
||||
},
|
||||
);
|
||||
temp
|
||||
}
|
||||
|
||||
crate fn consume_by_copy_or_move(&self, place: Place<'tcx>) -> Operand<'tcx> {
|
||||
let tcx = self.hir.tcx();
|
||||
let tcx = self.tcx;
|
||||
let ty = place.ty(&self.local_decls, tcx).ty;
|
||||
if !self.hir.type_is_copy_modulo_regions(ty, DUMMY_SP) {
|
||||
if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, DUMMY_SP) {
|
||||
Operand::Move(place)
|
||||
} else {
|
||||
Operand::Copy(place)
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::build;
|
||||
use crate::build::scope::DropKind;
|
||||
use crate::thir::cx::Cx;
|
||||
use crate::thir::{BindingMode, LintLevel, PatKind};
|
||||
use crate::thir::{BindingMode, Expr, LintLevel, Pat, PatKind};
|
||||
use rustc_attr::{self as attr, UnwindAttr};
|
||||
use rustc_errors::ErrorReported;
|
||||
use rustc_hir as hir;
|
||||
@ -9,13 +9,13 @@ use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{GeneratorKind, HirIdMap, Node};
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||
use rustc_middle::hir::place::PlaceBase as HirPlaceBase;
|
||||
use rustc_middle::middle::region;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::subst::Subst;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_span::symbol::kw;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeckResults};
|
||||
use rustc_span::symbol::{kw, sym};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use rustc_target::spec::PanicStrategy;
|
||||
@ -42,6 +42,7 @@ crate fn mir_built<'tcx>(
|
||||
/// Construct the MIR for a given `DefId`.
|
||||
fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_> {
|
||||
let id = tcx.hir().local_def_id_to_hir_id(def.did);
|
||||
let body_owner_kind = tcx.hir().body_owner_kind(id);
|
||||
|
||||
// Figure out what primary body this item has.
|
||||
let (body_id, return_ty_span, span_with_body) = match tcx.hir().get(id) {
|
||||
@ -88,13 +89,13 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
|
||||
let span_with_body = span_with_body.unwrap_or_else(|| tcx.hir().span(id));
|
||||
|
||||
tcx.infer_ctxt().enter(|infcx| {
|
||||
let cx = Cx::new(&infcx, def, id);
|
||||
let body = if let Some(ErrorReported) = cx.typeck_results().tainted_by_errors {
|
||||
build::construct_error(cx, body_id)
|
||||
} else if cx.body_owner_kind.is_fn_or_closure() {
|
||||
let mut cx = Cx::new(tcx, def);
|
||||
let body = if let Some(ErrorReported) = cx.typeck_results.tainted_by_errors {
|
||||
build::construct_error(&infcx, def, id, body_id, body_owner_kind)
|
||||
} else if body_owner_kind.is_fn_or_closure() {
|
||||
// fetch the fully liberated fn signature (that is, all bound
|
||||
// types/lifetimes replaced)
|
||||
let fn_sig = cx.typeck_results().liberated_fn_sigs()[id];
|
||||
let fn_sig = cx.typeck_results.liberated_fn_sigs()[id];
|
||||
let fn_def_id = tcx.hir().local_def_id(id);
|
||||
|
||||
let safety = match fn_sig.unsafety {
|
||||
@ -103,6 +104,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
|
||||
};
|
||||
|
||||
let body = tcx.hir().body(body_id);
|
||||
let expr = cx.mirror_expr(&body.value);
|
||||
let ty = tcx.type_of(fn_def_id);
|
||||
let mut abi = fn_sig.abi;
|
||||
let implicit_argument = match ty.kind() {
|
||||
@ -178,7 +180,8 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
|
||||
};
|
||||
|
||||
let mut mir = build::construct_fn(
|
||||
cx,
|
||||
&infcx,
|
||||
def,
|
||||
id,
|
||||
arguments,
|
||||
safety,
|
||||
@ -186,6 +189,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
|
||||
return_ty,
|
||||
return_ty_span,
|
||||
body,
|
||||
expr,
|
||||
span_with_body,
|
||||
);
|
||||
if yield_ty.is_some() {
|
||||
@ -205,9 +209,12 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
|
||||
// place to be the type of the constant because NLL typeck will
|
||||
// equate them.
|
||||
|
||||
let return_ty = cx.typeck_results().node_type(id);
|
||||
let return_ty = cx.typeck_results.node_type(id);
|
||||
|
||||
build::construct_const(cx, body_id, return_ty, return_ty_span)
|
||||
let ast_expr = &tcx.hir().body(body_id).value;
|
||||
let expr = cx.mirror_expr(ast_expr);
|
||||
|
||||
build::construct_const(&infcx, expr, def, id, return_ty, return_ty_span)
|
||||
};
|
||||
|
||||
lints::check(tcx, &body);
|
||||
@ -304,10 +311,17 @@ impl BlockFrame {
|
||||
struct BlockContext(Vec<BlockFrame>);
|
||||
|
||||
struct Builder<'a, 'tcx> {
|
||||
hir: Cx<'a, 'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||
typeck_results: &'tcx TypeckResults<'tcx>,
|
||||
region_scope_tree: &'tcx region::ScopeTree,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
|
||||
cfg: CFG<'tcx>,
|
||||
|
||||
def_id: DefId,
|
||||
hir_id: hir::HirId,
|
||||
check_overflow: bool,
|
||||
fn_span: Span,
|
||||
arg_count: usize,
|
||||
generator_kind: Option<GeneratorKind>,
|
||||
@ -577,8 +591,9 @@ struct ArgInfo<'tcx>(
|
||||
Option<ImplicitSelfKind>,
|
||||
);
|
||||
|
||||
fn construct_fn<'a, 'tcx, A>(
|
||||
hir: Cx<'a, 'tcx>,
|
||||
fn construct_fn<'tcx, A>(
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
fn_def: ty::WithOptConstParam<LocalDefId>,
|
||||
fn_id: hir::HirId,
|
||||
arguments: A,
|
||||
safety: Safety,
|
||||
@ -586,6 +601,7 @@ fn construct_fn<'a, 'tcx, A>(
|
||||
return_ty: Ty<'tcx>,
|
||||
return_ty_span: Span,
|
||||
body: &'tcx hir::Body<'tcx>,
|
||||
expr: Expr<'tcx>,
|
||||
span_with_body: Span,
|
||||
) -> Body<'tcx>
|
||||
where
|
||||
@ -593,15 +609,13 @@ where
|
||||
{
|
||||
let arguments: Vec<_> = arguments.collect();
|
||||
|
||||
let tcx = hir.tcx();
|
||||
let tcx_hir = tcx.hir();
|
||||
let span = tcx_hir.span(fn_id);
|
||||
|
||||
let fn_def_id = tcx_hir.local_def_id(fn_id);
|
||||
let tcx = infcx.tcx;
|
||||
let span = tcx.hir().span(fn_id);
|
||||
|
||||
let mut builder = Builder::new(
|
||||
hir,
|
||||
fn_def_id.to_def_id(),
|
||||
infcx,
|
||||
fn_def,
|
||||
fn_id,
|
||||
span_with_body,
|
||||
arguments.len(),
|
||||
safety,
|
||||
@ -625,16 +639,16 @@ where
|
||||
Some(builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
|
||||
builder.args_and_body(
|
||||
START_BLOCK,
|
||||
fn_def_id.to_def_id(),
|
||||
fn_def.did.to_def_id(),
|
||||
&arguments,
|
||||
arg_scope,
|
||||
&body.value,
|
||||
&expr,
|
||||
)
|
||||
}))
|
||||
}));
|
||||
let source_info = builder.source_info(fn_end);
|
||||
builder.cfg.terminate(return_block, source_info, TerminatorKind::Return);
|
||||
let should_abort = should_abort_on_panic(tcx, fn_def_id, abi);
|
||||
let should_abort = should_abort_on_panic(tcx, fn_def.did, abi);
|
||||
builder.build_drop_trees(should_abort);
|
||||
return_block.unit()
|
||||
}));
|
||||
@ -645,7 +659,7 @@ where
|
||||
} else {
|
||||
None
|
||||
};
|
||||
debug!("fn_id {:?} has attrs {:?}", fn_def_id, tcx.get_attrs(fn_def_id.to_def_id()));
|
||||
debug!("fn_id {:?} has attrs {:?}", fn_def, tcx.get_attrs(fn_def.did.to_def_id()));
|
||||
|
||||
let mut body = builder.finish();
|
||||
body.spread_arg = spread_arg;
|
||||
@ -653,21 +667,19 @@ where
|
||||
}
|
||||
|
||||
fn construct_const<'a, 'tcx>(
|
||||
hir: Cx<'a, 'tcx>,
|
||||
body_id: hir::BodyId,
|
||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||
expr: Expr<'tcx>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
hir_id: hir::HirId,
|
||||
const_ty: Ty<'tcx>,
|
||||
const_ty_span: Span,
|
||||
) -> Body<'tcx> {
|
||||
let tcx = hir.tcx();
|
||||
let owner_id = tcx.hir().body_owner(body_id);
|
||||
let def_id = tcx.hir().local_def_id(owner_id);
|
||||
let span = tcx.hir().span(owner_id);
|
||||
let tcx = infcx.tcx;
|
||||
let span = tcx.hir().span(hir_id);
|
||||
let mut builder =
|
||||
Builder::new(hir, def_id.to_def_id(), span, 0, Safety::Safe, const_ty, const_ty_span, None);
|
||||
Builder::new(infcx, def, hir_id, span, 0, Safety::Safe, const_ty, const_ty_span, None);
|
||||
|
||||
let mut block = START_BLOCK;
|
||||
let ast_expr = &tcx.hir().body(body_id).value;
|
||||
let expr = builder.hir.mirror_expr(ast_expr);
|
||||
unpack!(block = builder.expr_into_dest(Place::return_place(), block, &expr));
|
||||
|
||||
let source_info = builder.source_info(span);
|
||||
@ -682,15 +694,19 @@ fn construct_const<'a, 'tcx>(
|
||||
///
|
||||
/// This is required because we may still want to run MIR passes on an item
|
||||
/// with type errors, but normal MIR construction can't handle that in general.
|
||||
fn construct_error<'a, 'tcx>(hir: Cx<'a, 'tcx>, body_id: hir::BodyId) -> Body<'tcx> {
|
||||
let tcx = hir.tcx();
|
||||
let owner_id = tcx.hir().body_owner(body_id);
|
||||
let def_id = tcx.hir().local_def_id(owner_id);
|
||||
let span = tcx.hir().span(owner_id);
|
||||
fn construct_error<'a, 'tcx>(
|
||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
hir_id: hir::HirId,
|
||||
body_id: hir::BodyId,
|
||||
body_owner_kind: hir::BodyOwnerKind,
|
||||
) -> Body<'tcx> {
|
||||
let tcx = infcx.tcx;
|
||||
let span = tcx.hir().span(hir_id);
|
||||
let ty = tcx.ty_error();
|
||||
let generator_kind = tcx.hir().body(body_id).generator_kind;
|
||||
let num_params = match hir.body_owner_kind {
|
||||
hir::BodyOwnerKind::Fn => tcx.hir().fn_decl_by_hir_id(owner_id).unwrap().inputs.len(),
|
||||
let num_params = match body_owner_kind {
|
||||
hir::BodyOwnerKind::Fn => tcx.hir().fn_decl_by_hir_id(hir_id).unwrap().inputs.len(),
|
||||
hir::BodyOwnerKind::Closure => {
|
||||
if generator_kind.is_some() {
|
||||
// Generators have an implicit `self` parameter *and* a possibly
|
||||
@ -698,22 +714,14 @@ fn construct_error<'a, 'tcx>(hir: Cx<'a, 'tcx>, body_id: hir::BodyId) -> Body<'t
|
||||
2
|
||||
} else {
|
||||
// The implicit self parameter adds another local in MIR.
|
||||
1 + tcx.hir().fn_decl_by_hir_id(owner_id).unwrap().inputs.len()
|
||||
1 + tcx.hir().fn_decl_by_hir_id(hir_id).unwrap().inputs.len()
|
||||
}
|
||||
}
|
||||
hir::BodyOwnerKind::Const => 0,
|
||||
hir::BodyOwnerKind::Static(_) => 0,
|
||||
};
|
||||
let mut builder = Builder::new(
|
||||
hir,
|
||||
def_id.to_def_id(),
|
||||
span,
|
||||
num_params,
|
||||
Safety::Safe,
|
||||
ty,
|
||||
span,
|
||||
generator_kind,
|
||||
);
|
||||
let mut builder =
|
||||
Builder::new(infcx, def, hir_id, span, num_params, Safety::Safe, ty, span, generator_kind);
|
||||
let source_info = builder.source_info(span);
|
||||
// Some MIR passes will expect the number of parameters to match the
|
||||
// function declaration.
|
||||
@ -728,8 +736,9 @@ fn construct_error<'a, 'tcx>(hir: Cx<'a, 'tcx>, body_id: hir::BodyId) -> Body<'t
|
||||
|
||||
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
fn new(
|
||||
hir: Cx<'a, 'tcx>,
|
||||
def_id: DefId,
|
||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
hir_id: hir::HirId,
|
||||
span: Span,
|
||||
arg_count: usize,
|
||||
safety: Safety,
|
||||
@ -737,10 +746,30 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
return_span: Span,
|
||||
generator_kind: Option<GeneratorKind>,
|
||||
) -> Builder<'a, 'tcx> {
|
||||
let lint_level = LintLevel::Explicit(hir.root_lint_level);
|
||||
let tcx = infcx.tcx;
|
||||
let attrs = tcx.hir().attrs(hir_id);
|
||||
// Some functions always have overflow checks enabled,
|
||||
// however, they may not get codegen'd, depending on
|
||||
// the settings for the crate they are codegened in.
|
||||
let mut check_overflow = tcx.sess.contains_name(attrs, sym::rustc_inherit_overflow_checks);
|
||||
// Respect -C overflow-checks.
|
||||
check_overflow |= tcx.sess.overflow_checks();
|
||||
// Constants always need overflow checks.
|
||||
check_overflow |= matches!(
|
||||
tcx.hir().body_owner_kind(hir_id),
|
||||
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_)
|
||||
);
|
||||
|
||||
let lint_level = LintLevel::Explicit(hir_id);
|
||||
let mut builder = Builder {
|
||||
hir,
|
||||
def_id,
|
||||
tcx,
|
||||
infcx,
|
||||
typeck_results: tcx.typeck_opt_const_arg(def),
|
||||
region_scope_tree: tcx.region_scope_tree(def.did),
|
||||
param_env: tcx.param_env(def.did),
|
||||
def_id: def.did.to_def_id(),
|
||||
hir_id,
|
||||
check_overflow,
|
||||
cfg: CFG { basic_blocks: IndexVec::new() },
|
||||
fn_span: span,
|
||||
arg_count,
|
||||
@ -796,7 +825,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
fn_def_id: DefId,
|
||||
arguments: &[ArgInfo<'tcx>],
|
||||
argument_scope: region::Scope,
|
||||
ast_body: &'tcx hir::Expr<'tcx>,
|
||||
expr: &Expr<'tcx>,
|
||||
) -> BlockAnd<()> {
|
||||
// Allocate locals for the function arguments
|
||||
for &ArgInfo(ty, _, arg_opt, _) in arguments.iter() {
|
||||
@ -816,9 +845,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
let tcx = self.hir.tcx();
|
||||
let tcx = self.tcx;
|
||||
let tcx_hir = tcx.hir();
|
||||
let hir_typeck_results = self.hir.typeck_results();
|
||||
let hir_typeck_results = self.typeck_results;
|
||||
|
||||
// In analyze_closure() in upvar.rs we gathered a list of upvars used by a
|
||||
// indexed closure and we stored in a map called closure_captures in TypeckResults
|
||||
@ -894,14 +923,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
// Make sure we drop (parts of) the argument even when not matched on.
|
||||
self.schedule_drop(
|
||||
arg_opt.as_ref().map_or(ast_body.span, |arg| arg.pat.span),
|
||||
arg_opt.as_ref().map_or(expr.span, |arg| arg.pat.span),
|
||||
argument_scope,
|
||||
local,
|
||||
DropKind::Value,
|
||||
);
|
||||
|
||||
if let Some(arg) = arg_opt {
|
||||
let pattern = self.hir.pattern_from_hir(&arg.pat);
|
||||
let pat = match tcx.hir().get(arg.pat.hir_id) {
|
||||
Node::Pat(pat) | Node::Binding(pat) => pat,
|
||||
node => bug!("pattern became {:?}", node),
|
||||
};
|
||||
let pattern = Pat::from_hir(tcx, self.param_env, self.typeck_results, pat);
|
||||
let original_source_scope = self.source_scope;
|
||||
let span = pattern.span;
|
||||
self.set_correct_source_scope_for_arg(arg.hir_id, original_source_scope, span);
|
||||
@ -936,7 +969,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
_ => {
|
||||
scope = self.declare_bindings(
|
||||
scope,
|
||||
ast_body.span,
|
||||
expr.span,
|
||||
&pattern,
|
||||
matches::ArmHasGuard(false),
|
||||
Some((Some(&place), span)),
|
||||
@ -953,8 +986,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
self.source_scope = source_scope;
|
||||
}
|
||||
|
||||
let body = self.hir.mirror_expr(ast_body);
|
||||
self.expr_into_dest(Place::return_place(), block, &body)
|
||||
self.expr_into_dest(Place::return_place(), block, &expr)
|
||||
}
|
||||
|
||||
fn set_correct_source_scope_for_arg(
|
||||
@ -963,15 +995,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
original_source_scope: SourceScope,
|
||||
pattern_span: Span,
|
||||
) {
|
||||
let tcx = self.hir.tcx();
|
||||
let current_root = tcx.maybe_lint_level_root_bounded(arg_hir_id, self.hir.root_lint_level);
|
||||
let tcx = self.tcx;
|
||||
let current_root = tcx.maybe_lint_level_root_bounded(arg_hir_id, self.hir_id);
|
||||
let parent_root = tcx.maybe_lint_level_root_bounded(
|
||||
self.source_scopes[original_source_scope]
|
||||
.local_data
|
||||
.as_ref()
|
||||
.assert_crate_local()
|
||||
.lint_root,
|
||||
self.hir.root_lint_level,
|
||||
self.hir_id,
|
||||
);
|
||||
if current_root != parent_root {
|
||||
self.source_scope =
|
||||
@ -983,7 +1015,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
match self.unit_temp {
|
||||
Some(tmp) => tmp,
|
||||
None => {
|
||||
let ty = self.hir.unit_ty();
|
||||
let ty = self.tcx.mk_unit();
|
||||
let fn_span = self.fn_span;
|
||||
let tmp = self.temp(ty, fn_span);
|
||||
self.unit_temp = Some(tmp);
|
||||
|
@ -516,7 +516,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
{
|
||||
debug!("in_scope(region_scope={:?})", region_scope);
|
||||
let source_scope = self.source_scope;
|
||||
let tcx = self.hir.tcx();
|
||||
let tcx = self.tcx;
|
||||
if let LintLevel::Explicit(current_hir_id) = lint_level {
|
||||
// Use `maybe_lint_level_root_bounded` with `root_lint_level` as a bound
|
||||
// to avoid adding Hir dependences on our parents.
|
||||
@ -524,10 +524,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
let parent_root = tcx.maybe_lint_level_root_bounded(
|
||||
self.source_scopes[source_scope].local_data.as_ref().assert_crate_local().lint_root,
|
||||
self.hir.root_lint_level,
|
||||
self.hir_id,
|
||||
);
|
||||
let current_root =
|
||||
tcx.maybe_lint_level_root_bounded(current_hir_id, self.hir.root_lint_level);
|
||||
let current_root = tcx.maybe_lint_level_root_bounded(current_hir_id, self.hir_id);
|
||||
|
||||
if parent_root != current_root {
|
||||
self.source_scope = self.new_source_scope(
|
||||
@ -615,7 +614,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
unpack!(block = self.expr_into_dest(destination, block, value));
|
||||
self.block_context.pop();
|
||||
} else {
|
||||
self.cfg.push_assign_unit(block, source_info, destination, self.hir.tcx())
|
||||
self.cfg.push_assign_unit(block, source_info, destination, self.tcx)
|
||||
}
|
||||
} else {
|
||||
assert!(value.is_none(), "`return` and `break` should have a destination");
|
||||
@ -763,7 +762,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
) {
|
||||
let needs_drop = match drop_kind {
|
||||
DropKind::Value => {
|
||||
if !self.hir.needs_drop(self.local_decls[local].ty) {
|
||||
if !self.local_decls[local].ty.needs_drop(self.tcx, self.param_env) {
|
||||
return;
|
||||
}
|
||||
true
|
||||
@ -834,10 +833,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
}
|
||||
|
||||
if scope.region_scope == region_scope {
|
||||
let region_scope_span =
|
||||
region_scope.span(self.hir.tcx(), &self.hir.region_scope_tree);
|
||||
let region_scope_span = region_scope.span(self.tcx, &self.region_scope_tree);
|
||||
// Attribute scope exit drops to scope's closing brace.
|
||||
let scope_end = self.hir.tcx().sess.source_map().end_point(region_scope_span);
|
||||
let scope_end = self.tcx.sess.source_map().end_point(region_scope_span);
|
||||
|
||||
scope.drops.push(DropData {
|
||||
source_info: SourceInfo { span: scope_end, scope: scope.source_scope },
|
||||
@ -926,7 +924,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
let cond = unpack!(block = self.as_local_operand(block, condition));
|
||||
let true_block = self.cfg.start_new_block();
|
||||
let false_block = self.cfg.start_new_block();
|
||||
let term = TerminatorKind::if_(self.hir.tcx(), cond.clone(), true_block, false_block);
|
||||
let term = TerminatorKind::if_(self.tcx, cond.clone(), true_block, false_block);
|
||||
self.cfg.terminate(block, source_info, term);
|
||||
|
||||
match cond {
|
||||
|
@ -7,7 +7,7 @@ use rustc_middle::ty;
|
||||
|
||||
use rustc_index::vec::Idx;
|
||||
|
||||
impl<'a, 'tcx> Cx<'a, 'tcx> {
|
||||
impl<'tcx> Cx<'tcx> {
|
||||
crate fn mirror_block(&mut self, block: &'tcx hir::Block<'tcx>) -> Block<'tcx> {
|
||||
// We have to eagerly lower the "spine" of the statements
|
||||
// in order to get the lexical scoping correctly.
|
||||
|
@ -15,7 +15,7 @@ use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
|
||||
use rustc_middle::ty::{self, AdtKind, Ty};
|
||||
use rustc_span::Span;
|
||||
|
||||
impl<'a, 'tcx> Cx<'a, 'tcx> {
|
||||
impl<'tcx> Cx<'tcx> {
|
||||
crate fn mirror_expr(&mut self, hir_expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> {
|
||||
let temp_lifetime = self.region_scope_tree.temporary_scope(hir_expr.hir_id.local_id);
|
||||
let expr_scope =
|
||||
@ -26,7 +26,7 @@ impl<'a, 'tcx> Cx<'a, 'tcx> {
|
||||
let mut expr = self.make_mirror_unadjusted(hir_expr);
|
||||
|
||||
// Now apply adjustments, if any.
|
||||
for adjustment in self.typeck_results().expr_adjustments(hir_expr) {
|
||||
for adjustment in self.typeck_results.expr_adjustments(hir_expr) {
|
||||
debug!("make_mirror: expr={:?} applying adjustment={:?}", expr, adjustment);
|
||||
expr = self.apply_adjustment(hir_expr, expr, adjustment);
|
||||
}
|
||||
@ -287,13 +287,13 @@ impl<'a, 'tcx> Cx<'a, 'tcx> {
|
||||
self.overloaded_operator(expr, vec![lhs, rhs])
|
||||
} else {
|
||||
// FIXME overflow
|
||||
match (op.node, self.constness) {
|
||||
(hir::BinOpKind::And, _) => ExprKind::LogicalOp {
|
||||
match op.node {
|
||||
hir::BinOpKind::And => ExprKind::LogicalOp {
|
||||
op: LogicalOp::And,
|
||||
lhs: self.mirror_expr_boxed(lhs),
|
||||
rhs: self.mirror_expr_boxed(rhs),
|
||||
},
|
||||
(hir::BinOpKind::Or, _) => ExprKind::LogicalOp {
|
||||
hir::BinOpKind::Or => ExprKind::LogicalOp {
|
||||
op: LogicalOp::Or,
|
||||
lhs: self.mirror_expr_boxed(lhs),
|
||||
rhs: self.mirror_expr_boxed(rhs),
|
||||
@ -420,7 +420,7 @@ impl<'a, 'tcx> Cx<'a, 'tcx> {
|
||||
};
|
||||
|
||||
let upvars = self
|
||||
.typeck_results()
|
||||
.typeck_results
|
||||
.closure_min_captures_flattened(def_id)
|
||||
.zip(substs.upvar_tys())
|
||||
.map(|(captured_place, ty)| self.capture_upvar(expr, captured_place, ty))
|
||||
@ -981,7 +981,7 @@ impl<'a, 'tcx> Cx<'a, 'tcx> {
|
||||
fn capture_upvar(
|
||||
&mut self,
|
||||
closure_expr: &'tcx hir::Expr<'tcx>,
|
||||
captured_place: &'a ty::CapturedPlace<'tcx>,
|
||||
captured_place: &'tcx ty::CapturedPlace<'tcx>,
|
||||
upvar_ty: Ty<'tcx>,
|
||||
) -> Expr<'tcx> {
|
||||
let upvar_capture = captured_place.info.capture_kind;
|
||||
|
@ -9,114 +9,37 @@ use rustc_ast as ast;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::Node;
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_middle::middle::region;
|
||||
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
|
||||
use rustc_middle::ty::subst::Subst;
|
||||
use rustc_middle::ty::subst::{GenericArg, InternalSubsts};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
|
||||
#[derive(Clone)]
|
||||
crate struct Cx<'a, 'tcx> {
|
||||
crate struct Cx<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||
|
||||
crate root_lint_level: hir::HirId,
|
||||
crate param_env: ty::ParamEnv<'tcx>,
|
||||
|
||||
/// Identity `InternalSubsts` for use with const-evaluation.
|
||||
crate identity_substs: &'tcx InternalSubsts<'tcx>,
|
||||
|
||||
crate region_scope_tree: &'tcx region::ScopeTree,
|
||||
crate typeck_results: &'a ty::TypeckResults<'tcx>,
|
||||
|
||||
/// This is `Constness::Const` if we are compiling a `static`,
|
||||
/// `const`, or the body of a `const fn`.
|
||||
constness: hir::Constness,
|
||||
crate typeck_results: &'tcx ty::TypeckResults<'tcx>,
|
||||
|
||||
/// The `DefId` of the owner of this body.
|
||||
body_owner: DefId,
|
||||
|
||||
/// What kind of body is being compiled.
|
||||
crate body_owner_kind: hir::BodyOwnerKind,
|
||||
|
||||
/// Whether this constant/function needs overflow checks.
|
||||
check_overflow: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Cx<'a, 'tcx> {
|
||||
crate fn new(
|
||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
src_id: hir::HirId,
|
||||
) -> Cx<'a, 'tcx> {
|
||||
let tcx = infcx.tcx;
|
||||
impl<'tcx> Cx<'tcx> {
|
||||
crate fn new(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalDefId>) -> Cx<'tcx> {
|
||||
let typeck_results = tcx.typeck_opt_const_arg(def);
|
||||
let body_owner_kind = tcx.hir().body_owner_kind(src_id);
|
||||
|
||||
let constness = match body_owner_kind {
|
||||
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => hir::Constness::Const,
|
||||
hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::Fn => hir::Constness::NotConst,
|
||||
};
|
||||
|
||||
let attrs = tcx.hir().attrs(src_id);
|
||||
|
||||
// Some functions always have overflow checks enabled,
|
||||
// however, they may not get codegen'd, depending on
|
||||
// the settings for the crate they are codegened in.
|
||||
let mut check_overflow = tcx.sess.contains_name(attrs, sym::rustc_inherit_overflow_checks);
|
||||
|
||||
// Respect -C overflow-checks.
|
||||
check_overflow |= tcx.sess.overflow_checks();
|
||||
|
||||
// Constants always need overflow checks.
|
||||
check_overflow |= constness == hir::Constness::Const;
|
||||
|
||||
Cx {
|
||||
tcx,
|
||||
infcx,
|
||||
root_lint_level: src_id,
|
||||
param_env: tcx.param_env(def.did),
|
||||
identity_substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
|
||||
region_scope_tree: tcx.region_scope_tree(def.did),
|
||||
typeck_results,
|
||||
constness,
|
||||
body_owner: def.did.to_def_id(),
|
||||
body_owner_kind,
|
||||
check_overflow,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Cx<'a, 'tcx> {
|
||||
crate fn usize_ty(&mut self) -> Ty<'tcx> {
|
||||
self.tcx.types.usize
|
||||
}
|
||||
|
||||
crate fn usize_literal(&mut self, value: u64) -> &'tcx ty::Const<'tcx> {
|
||||
ty::Const::from_usize(self.tcx, value)
|
||||
}
|
||||
|
||||
crate fn bool_ty(&mut self) -> Ty<'tcx> {
|
||||
self.tcx.types.bool
|
||||
}
|
||||
|
||||
crate fn unit_ty(&mut self) -> Ty<'tcx> {
|
||||
self.tcx.mk_unit()
|
||||
}
|
||||
|
||||
crate fn true_literal(&mut self) -> &'tcx ty::Const<'tcx> {
|
||||
ty::Const::from_bool(self.tcx, true)
|
||||
}
|
||||
|
||||
crate fn false_literal(&mut self) -> &'tcx ty::Const<'tcx> {
|
||||
ty::Const::from_bool(self.tcx, false)
|
||||
}
|
||||
|
||||
impl<'tcx> Cx<'tcx> {
|
||||
crate fn const_eval_literal(
|
||||
&mut self,
|
||||
lit: &'tcx ast::LitKind,
|
||||
@ -149,66 +72,15 @@ impl<'a, 'tcx> Cx<'a, 'tcx> {
|
||||
};
|
||||
Pat::from_hir(self.tcx, self.param_env, self.typeck_results(), p)
|
||||
}
|
||||
}
|
||||
|
||||
crate fn trait_method(
|
||||
&mut self,
|
||||
trait_def_id: DefId,
|
||||
method_name: Symbol,
|
||||
self_ty: Ty<'tcx>,
|
||||
params: &[GenericArg<'tcx>],
|
||||
) -> &'tcx ty::Const<'tcx> {
|
||||
let substs = self.tcx.mk_substs_trait(self_ty, params);
|
||||
|
||||
// The unhygienic comparison here is acceptable because this is only
|
||||
// used on known traits.
|
||||
let item = self
|
||||
.tcx
|
||||
.associated_items(trait_def_id)
|
||||
.filter_by_name_unhygienic(method_name)
|
||||
.find(|item| item.kind == ty::AssocKind::Fn)
|
||||
.expect("trait method not found");
|
||||
|
||||
let method_ty = self.tcx.type_of(item.def_id);
|
||||
let method_ty = method_ty.subst(self.tcx, substs);
|
||||
ty::Const::zero_sized(self.tcx, method_ty)
|
||||
}
|
||||
|
||||
crate fn all_fields(&mut self, adt_def: &ty::AdtDef, variant_index: VariantIdx) -> Vec<Field> {
|
||||
(0..adt_def.variants[variant_index].fields.len()).map(Field::new).collect()
|
||||
}
|
||||
|
||||
crate fn needs_drop(&mut self, ty: Ty<'tcx>) -> bool {
|
||||
ty.needs_drop(self.tcx, self.param_env)
|
||||
}
|
||||
|
||||
crate fn infcx(&self) -> &'a InferCtxt<'a, 'tcx> {
|
||||
self.infcx
|
||||
}
|
||||
|
||||
crate fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
impl<'tcx> UserAnnotatedTyHelpers<'tcx> for Cx<'tcx> {
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
crate fn typeck_results(&self) -> &'a ty::TypeckResults<'tcx> {
|
||||
self.typeck_results
|
||||
}
|
||||
|
||||
crate fn check_overflow(&self) -> bool {
|
||||
self.check_overflow
|
||||
}
|
||||
|
||||
crate fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>, span: Span) -> bool {
|
||||
self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> UserAnnotatedTyHelpers<'tcx> for Cx<'_, 'tcx> {
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx()
|
||||
}
|
||||
|
||||
fn typeck_results(&self) -> &ty::TypeckResults<'tcx> {
|
||||
self.typeck_results()
|
||||
self.typeck_results
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user