]> git.lizzy.rs Git - rust.git/commitdiff
Pull `thir::Cx` out of the MIR `Builder`
authorLeSeulArtichaut <leseulartichaut@gmail.com>
Wed, 3 Mar 2021 15:35:54 +0000 (16:35 +0100)
committerLeSeulArtichaut <leseulartichaut@gmail.com>
Tue, 9 Mar 2021 19:13:58 +0000 (20:13 +0100)
17 files changed:
compiler/rustc_mir_build/src/build/block.rs
compiler/rustc_mir_build/src/build/expr/as_operand.rs
compiler/rustc_mir_build/src/build/expr/as_place.rs
compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
compiler/rustc_mir_build/src/build/expr/as_temp.rs
compiler/rustc_mir_build/src/build/expr/into.rs
compiler/rustc_mir_build/src/build/expr/stmt.rs
compiler/rustc_mir_build/src/build/matches/mod.rs
compiler/rustc_mir_build/src/build/matches/simplify.rs
compiler/rustc_mir_build/src/build/matches/test.rs
compiler/rustc_mir_build/src/build/matches/util.rs
compiler/rustc_mir_build/src/build/misc.rs
compiler/rustc_mir_build/src/build/mod.rs
compiler/rustc_mir_build/src/build/scope.rs
compiler/rustc_mir_build/src/thir/cx/block.rs
compiler/rustc_mir_build/src/thir/cx/expr.rs
compiler/rustc_mir_build/src/thir/cx/mod.rs

index 2d1fd4d09d1a447badca352e22ca50da067a8e4b..7bb141058d22e906614adbf045ecc14dcad7112d 100644 (file)
@@ -110,8 +110,7 @@ fn ast_block_stmts(
                     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 @@ fn ast_block_stmts(
 
         // 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 @@ fn ast_block_stmts(
             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 @@ fn update_source_scope_for_safety_mode(&mut self, span: Span, safety_mode: Block
                     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,
                 }
index faa8ea759d70970b39695d2c4b412b8412a59ba1..81428e098699d6fad49072ad3c7896b1c655127c 100644 (file)
@@ -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
index 156f8d2e7045c754e45c950b2b82e2b3266f4dce..3581ca1ee5bd5e42fab01d1f00d6a55ad2a623db 100644 (file)
@@ -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 @@ fn expr_as_place(
                             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 @@ fn lower_captured_upvar(
         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 @@ fn lower_index_expression(
 
         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 @@ fn lower_index_expression(
         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 @@ fn bounds_check(
         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 @@ fn add_fake_borrows_of_base(
         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"),
index 8082315408c6fc7c8825f970b9e7846bf6c16f27..89a179bd4510d0268c31838ed110e1b590df4755 100644 (file)
@@ -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 @@ fn limit_capture_mutability(
             // 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 @@ fn limit_capture_mutability(
             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 @@ fn limit_capture_mutability(
     // 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 @@ fn neg_1_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'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)
     }
index 0f4d05fc03ab96974739380a5b1a81ecde52579c..8b032032bfc43dfda51d576f86cae5923d606db2 100644 (file)
@@ -59,13 +59,13 @@ fn as_temp_inner(
             }
             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 });
index 9c719e36551c41973f2c3b1324672fef415d8eaf..83a09a005084a7da1dfb796385a8ca57a47b7437 100644 (file)
@@ -7,8 +7,9 @@
 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()
             }
 
index 0d2d99a8b5e87915013b39ecf6e70e16f7185468..8e907a40f43fa53972d72bc8b12c505aae18f551 100644 (file)
@@ -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));
index 6a828c1864fc9aad7a770681518b97a64dbe13ac..d93fc6149c213d64ff8c411ebe27e49f0635a829 100644 (file)
@@ -413,7 +413,7 @@ pub(super) fn expr_into_pattern(
                 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 @@ pub(super) fn expr_into_pattern(
         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 @@ pub(super) fn expr_into_pattern(
 
     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 @@ fn select_matched_candidates(
 
                     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 @@ fn calculate_fake_borrows<'b>(
         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 @@ fn bind_and_guard_matched_candidate<'pat>(
         //    * 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 @@ fn ascribe_types<'b>(
 
             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 @@ fn bind_matched_candidate_for_guard<'b>(
         // 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 @@ fn bind_matched_candidate_for_arm_body<'b>(
     {
         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 @@ fn declare_binding(
             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),
index ddfaeafc07cf18e7bce59d08d3328cce934a2a3c..9931cdf3b9e9113049ddbcb3633efeb638a16968 100644 (file)
@@ -147,7 +147,7 @@ fn simplify_match_pair<'pat>(
         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 @@ fn simplify_match_pair<'pat>(
             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()
                     }
index c428ed817b1f8eb3055e4a2dc54c2c63910833ff..48abaa8d35f82b5cd9d62a6a9e56d99b5b302ff7 100644 (file)
 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 @@ pub(super) fn add_cases_to_switch<'pat>(
 
         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 @@ pub(super) fn perform_test(
             "perform_test({:?}, {:?}: {:?}, {:?})",
             block,
             place,
-            place.ty(&self.local_decls, self.hir.tcx()),
+            place.ty(&self.local_decls, self.tcx),
             test
         );
 
@@ -169,7 +171,7 @@ pub(super) fn perform_test(
                 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 @@ pub(super) fn perform_test(
                             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 @@ pub(super) fn perform_test(
             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 @@ fn compare(
         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 @@ fn compare(
         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 @@ fn non_scalar_compare(
             // 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 @@ fn non_scalar_compare(
             _ => 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 @@ fn non_scalar_compare(
             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 @@ pub(super) fn sort_candidate<'pat>(
                     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 @@ fn candidate_after_variant_switch<'pat>(
         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 @@ fn const_range_contains(
     ) -> 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 @@ pub(super) fn targets(&self) -> usize {
 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)
+}
index db1f678a5c68d46a535f9acf8d907ffceb5e043b..15aca0203aa0117e8efc69a465c17a36788b8275 100644 (file)
@@ -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),
         };
 
index 29651d9bc663a8380f436e8483a9555a8c6ac2bf..62c217a12aaad1c6cad879f23298aaa09b2f16c1 100644 (file)
@@ -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)
index f9bed4454f2ede28c59417a2cb5168fcf8b04d02..ecc5f2f260e7dd4ac44744971c73b40e3875b449 100644 (file)
@@ -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::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 @@
 /// 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 @@ fn is_statement(&self) -> bool {
 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 @@ fn construct_fn<'a, 'tcx, A>(
 {
     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 @@ fn construct_fn<'a, 'tcx, A>(
                 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 @@ fn construct_fn<'a, 'tcx, A>(
     } 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 @@ fn construct_fn<'a, 'tcx, A>(
 }
 
 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 @@ fn new(
         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 @@ fn args_and_body(
         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 @@ fn args_and_body(
             }
         }
 
-        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 @@ fn args_and_body(
 
             // 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 @@ fn args_and_body(
                     _ => {
                         scope = self.declare_bindings(
                             scope,
-                            ast_body.span,
+                            expr.span,
                             &pattern,
                             matches::ArmHasGuard(false),
                             Some((Some(&place), span)),
@@ -953,8 +986,7 @@ fn args_and_body(
             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 @@ fn set_correct_source_scope_for_arg(
         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 @@ fn get_unit_temp(&mut self) -> Place<'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);
index fccff023d0872a6e0d11443f69cc4865bdf9b709..6c58528a3c5c6e85073d6929690a66efbed745d5 100644 (file)
@@ -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 @@ fn leave_top_scope(&mut self, block: BasicBlock) -> BasicBlock {
     ) {
         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 @@ fn leave_top_scope(&mut self, block: BasicBlock) -> BasicBlock {
             }
 
             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 @@ fn leave_top_scope(&mut self, block: BasicBlock) -> BasicBlock {
         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 {
index 9c1440aba4204487a448a92a7bd0ffbc06f8693b..25af65d1c6538d931f95a64dceb97b47bd9c7684 100644 (file)
@@ -7,7 +7,7 @@
 
 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.
index cd5e73a45cd59bb2d2390b0e739e82c5b14fa7cf..2d1170ca3a89d5bd6aa5091fcb641365731377fa 100644 (file)
@@ -15,7 +15,7 @@
 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 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'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 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'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 @@ fn overloaded_place(
     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;
index 6b3b3be514c039d1558ae306f8b87af96c0c8c99..c00e9ff8dd98e01864b7094fd13f6e59e97ff71e 100644 (file)
 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> {
-        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> {
+impl<'tcx> UserAnnotatedTyHelpers<'tcx> for Cx<'tcx> {
     fn tcx(&self) -> TyCtxt<'tcx> {
-        self.tcx()
+        self.tcx
     }
 
     fn typeck_results(&self) -> &ty::TypeckResults<'tcx> {
-        self.typeck_results()
+        self.typeck_results
     }
 }