]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_borrowck/src/type_check/mod.rs
Rollup merge of #85766 - workingjubilee:file-options, r=yaahc
[rust.git] / compiler / rustc_borrowck / src / type_check / mod.rs
index 7e6a481ca69a1b76f62008c1282b3ea676662ac0..ddd077c22faf86662dfb93c482f2374dc249cd07 100644 (file)
@@ -10,6 +10,7 @@
 use rustc_data_structures::vec_map::VecMap;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::lang_items::LangItem;
 use rustc_index::vec::{Idx, IndexVec};
@@ -655,7 +656,7 @@ fn sanitize_promoted(&mut self, promoted_body: &'b Body<'tcx>, location: Locatio
             // If the region is live at at least one location in the promoted MIR,
             // then add a liveness constraint to the main MIR for this region
             // at the location provided as an argument to this method
-            if let Some(_) = liveness_constraints.get_elements(region).next() {
+            if liveness_constraints.get_elements(region).next().is_some() {
                 self.cx
                     .borrowck_context
                     .constraints
@@ -1343,13 +1344,9 @@ fn check_stmt(&mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Lo
                 // though.
                 let category = match place.as_local() {
                     Some(RETURN_PLACE) => {
-                        if let BorrowCheckContext {
-                            universal_regions:
-                                UniversalRegions { defining_ty: DefiningTy::Const(def_id, _), .. },
-                            ..
-                        } = self.borrowck_context
-                        {
-                            if tcx.is_static(*def_id) {
+                        let defining_ty = &self.borrowck_context.universal_regions.defining_ty;
+                        if defining_ty.is_const() {
+                            if tcx.is_static(defining_ty.def_id()) {
                                 ConstraintCategory::UseAsStatic
                             } else {
                                 ConstraintCategory::UseAsConst
@@ -1527,6 +1524,8 @@ fn check_terminator(
                 }
             }
             TerminatorKind::SwitchInt { ref discr, switch_ty, .. } => {
+                self.check_operand(discr, term_location);
+
                 let discr_ty = discr.ty(body, tcx);
                 if let Err(terr) = self.sub_types(
                     discr_ty,
@@ -1549,6 +1548,11 @@ fn check_terminator(
                 // FIXME: check the values
             }
             TerminatorKind::Call { ref func, ref args, ref destination, from_hir_call, .. } => {
+                self.check_operand(func, term_location);
+                for arg in args {
+                    self.check_operand(arg, term_location);
+                }
+
                 let func_ty = func.ty(body, tcx);
                 debug!("check_terminator: call, func_ty={:?}", func_ty);
                 let sig = match func_ty.kind() {
@@ -1593,6 +1597,8 @@ fn check_terminator(
                 self.check_call_inputs(body, term, &sig, args, term_location, from_hir_call);
             }
             TerminatorKind::Assert { ref cond, ref msg, .. } => {
+                self.check_operand(cond, term_location);
+
                 let cond_ty = cond.ty(body, tcx);
                 if cond_ty != tcx.types.bool {
                     span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
@@ -1608,6 +1614,8 @@ fn check_terminator(
                 }
             }
             TerminatorKind::Yield { ref value, .. } => {
+                self.check_operand(value, term_location);
+
                 let value_ty = value.ty(body, tcx);
                 match body.yield_ty() {
                     None => span_mirbug!(self, term, "yield in non-generator"),
@@ -1650,7 +1658,12 @@ fn check_call_dest(
                     Some(RETURN_PLACE) => {
                         if let BorrowCheckContext {
                             universal_regions:
-                                UniversalRegions { defining_ty: DefiningTy::Const(def_id, _), .. },
+                                UniversalRegions {
+                                    defining_ty:
+                                        DefiningTy::Const(def_id, _)
+                                        | DefiningTy::InlineConst(def_id, _),
+                                    ..
+                                },
                             ..
                         } = self.borrowck_context
                         {
@@ -1931,15 +1944,51 @@ fn aggregate_field_ty(
         }
     }
 
+    fn check_operand(&mut self, op: &Operand<'tcx>, location: Location) {
+        if let Operand::Constant(constant) = op {
+            let maybe_uneval = match constant.literal {
+                ConstantKind::Ty(ct) => match ct.val {
+                    ty::ConstKind::Unevaluated(uv) => Some(uv),
+                    _ => None,
+                },
+                _ => None,
+            };
+            if let Some(uv) = maybe_uneval {
+                if uv.promoted.is_none() {
+                    let tcx = self.tcx();
+                    let def_id = uv.def.def_id_for_type_of();
+                    if tcx.def_kind(def_id) == DefKind::InlineConst {
+                        let predicates = self.prove_closure_bounds(
+                            tcx,
+                            def_id.expect_local(),
+                            uv.substs(tcx),
+                            location,
+                        );
+                        self.normalize_and_prove_instantiated_predicates(
+                            def_id,
+                            predicates,
+                            location.to_locations(),
+                        );
+                    }
+                }
+            }
+        }
+    }
+
     fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
         let tcx = self.tcx();
 
         match rvalue {
             Rvalue::Aggregate(ak, ops) => {
+                for op in ops {
+                    self.check_operand(op, location);
+                }
                 self.check_aggregate_rvalue(&body, rvalue, ak, ops, location)
             }
 
             Rvalue::Repeat(operand, len) => {
+                self.check_operand(operand, location);
+
                 // If the length cannot be evaluated we must assume that the length can be larger
                 // than 1.
                 // If the length is larger than 1, the repeat expression will need to copy the
@@ -1990,7 +2039,22 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
                 }
             }
 
-            Rvalue::NullaryOp(_, ty) | Rvalue::ShallowInitBox(_, ty) => {
+            Rvalue::NullaryOp(_, ty) => {
+                let trait_ref = ty::TraitRef {
+                    def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
+                    substs: tcx.mk_substs_trait(ty, &[]),
+                };
+
+                self.prove_trait_ref(
+                    trait_ref,
+                    location.to_locations(),
+                    ConstraintCategory::SizedBound,
+                );
+            }
+
+            Rvalue::ShallowInitBox(operand, ty) => {
+                self.check_operand(operand, location);
+
                 let trait_ref = ty::TraitRef {
                     def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
                     substs: tcx.mk_substs_trait(ty, &[]),
@@ -2004,6 +2068,8 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
             }
 
             Rvalue::Cast(cast_kind, op, ty) => {
+                self.check_operand(op, location);
+
                 match cast_kind {
                     CastKind::Pointer(PointerCast::ReifyFnPointer) => {
                         let fn_sig = op.ty(body, tcx).fn_sig(tcx);
@@ -2250,6 +2316,9 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
                 BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge,
                 box (left, right),
             ) => {
+                self.check_operand(left, location);
+                self.check_operand(right, location);
+
                 let ty_left = left.ty(body, tcx);
                 match ty_left.kind() {
                     // Types with regions are comparable if they have a common super-type.
@@ -2300,13 +2369,19 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
                 }
             }
 
+            Rvalue::Use(operand) | Rvalue::UnaryOp(_, operand) => {
+                self.check_operand(operand, location);
+            }
+
+            Rvalue::BinaryOp(_, box (left, right))
+            | Rvalue::CheckedBinaryOp(_, box (left, right)) => {
+                self.check_operand(left, location);
+                self.check_operand(right, location);
+            }
+
             Rvalue::AddressOf(..)
             | Rvalue::ThreadLocalRef(..)
-            | Rvalue::Use(..)
             | Rvalue::Len(..)
-            | Rvalue::BinaryOp(..)
-            | Rvalue::CheckedBinaryOp(..)
-            | Rvalue::UnaryOp(..)
             | Rvalue::Discriminant(..) => {}
         }
     }