@@ -10,6 +10,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1010use rustc_data_structures:: vec_map:: VecMap ;
1111use rustc_errors:: struct_span_err;
1212use rustc_hir as hir;
13+ use rustc_hir:: def:: DefKind ;
1314use rustc_hir:: def_id:: LocalDefId ;
1415use rustc_hir:: lang_items:: LangItem ;
1516use rustc_index:: vec:: { Idx , IndexVec } ;
@@ -1532,6 +1533,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
15321533 }
15331534 }
15341535 TerminatorKind :: SwitchInt { ref discr, switch_ty, .. } => {
1536+ self . check_operand ( discr, term_location) ;
1537+
15351538 let discr_ty = discr. ty ( body, tcx) ;
15361539 if let Err ( terr) = self . sub_types (
15371540 discr_ty,
@@ -1554,6 +1557,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
15541557 // FIXME: check the values
15551558 }
15561559 TerminatorKind :: Call { ref func, ref args, ref destination, from_hir_call, .. } => {
1560+ self . check_operand ( func, term_location) ;
1561+ for arg in args {
1562+ self . check_operand ( arg, term_location) ;
1563+ }
1564+
15571565 let func_ty = func. ty ( body, tcx) ;
15581566 debug ! ( "check_terminator: call, func_ty={:?}" , func_ty) ;
15591567 let sig = match func_ty. kind ( ) {
@@ -1598,6 +1606,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
15981606 self . check_call_inputs ( body, term, & sig, args, term_location, from_hir_call) ;
15991607 }
16001608 TerminatorKind :: Assert { ref cond, ref msg, .. } => {
1609+ self . check_operand ( cond, term_location) ;
1610+
16011611 let cond_ty = cond. ty ( body, tcx) ;
16021612 if cond_ty != tcx. types . bool {
16031613 span_mirbug ! ( self , term, "bad Assert ({:?}, not bool" , cond_ty) ;
@@ -1613,6 +1623,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
16131623 }
16141624 }
16151625 TerminatorKind :: Yield { ref value, .. } => {
1626+ self . check_operand ( value, term_location) ;
1627+
16161628 let value_ty = value. ty ( body, tcx) ;
16171629 match body. yield_ty ( ) {
16181630 None => span_mirbug ! ( self , term, "yield in non-generator" ) ,
@@ -1941,15 +1953,51 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19411953 }
19421954 }
19431955
1956+ fn check_operand ( & mut self , op : & Operand < ' tcx > , location : Location ) {
1957+ if let Operand :: Constant ( constant) = op {
1958+ let maybe_uneval = match constant. literal {
1959+ ConstantKind :: Ty ( ct) => match ct. val {
1960+ ty:: ConstKind :: Unevaluated ( uv) => Some ( uv) ,
1961+ _ => None ,
1962+ } ,
1963+ _ => None ,
1964+ } ;
1965+ if let Some ( uv) = maybe_uneval {
1966+ if uv. promoted . is_none ( ) {
1967+ let tcx = self . tcx ( ) ;
1968+ let def_id = uv. def . def_id_for_type_of ( ) ;
1969+ if tcx. def_kind ( def_id) == DefKind :: InlineConst {
1970+ let predicates = self . prove_closure_bounds (
1971+ tcx,
1972+ def_id. expect_local ( ) ,
1973+ uv. substs ( tcx) ,
1974+ location,
1975+ ) ;
1976+ self . normalize_and_prove_instantiated_predicates (
1977+ def_id,
1978+ predicates,
1979+ location. to_locations ( ) ,
1980+ ) ;
1981+ }
1982+ }
1983+ }
1984+ }
1985+ }
1986+
19441987 fn check_rvalue ( & mut self , body : & Body < ' tcx > , rvalue : & Rvalue < ' tcx > , location : Location ) {
19451988 let tcx = self . tcx ( ) ;
19461989
19471990 match rvalue {
19481991 Rvalue :: Aggregate ( ak, ops) => {
1992+ for op in ops {
1993+ self . check_operand ( op, location) ;
1994+ }
19491995 self . check_aggregate_rvalue ( & body, rvalue, ak, ops, location)
19501996 }
19511997
19521998 Rvalue :: Repeat ( operand, len) => {
1999+ self . check_operand ( operand, location) ;
2000+
19532001 // If the length cannot be evaluated we must assume that the length can be larger
19542002 // than 1.
19552003 // If the length is larger than 1, the repeat expression will need to copy the
@@ -2000,7 +2048,22 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20002048 }
20012049 }
20022050
2003- Rvalue :: NullaryOp ( _, ty) | Rvalue :: ShallowInitBox ( _, ty) => {
2051+ Rvalue :: NullaryOp ( _, ty) => {
2052+ let trait_ref = ty:: TraitRef {
2053+ def_id : tcx. require_lang_item ( LangItem :: Sized , Some ( self . last_span ) ) ,
2054+ substs : tcx. mk_substs_trait ( ty, & [ ] ) ,
2055+ } ;
2056+
2057+ self . prove_trait_ref (
2058+ trait_ref,
2059+ location. to_locations ( ) ,
2060+ ConstraintCategory :: SizedBound ,
2061+ ) ;
2062+ }
2063+
2064+ Rvalue :: ShallowInitBox ( operand, ty) => {
2065+ self . check_operand ( operand, location) ;
2066+
20042067 let trait_ref = ty:: TraitRef {
20052068 def_id : tcx. require_lang_item ( LangItem :: Sized , Some ( self . last_span ) ) ,
20062069 substs : tcx. mk_substs_trait ( ty, & [ ] ) ,
@@ -2014,6 +2077,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20142077 }
20152078
20162079 Rvalue :: Cast ( cast_kind, op, ty) => {
2080+ self . check_operand ( op, location) ;
2081+
20172082 match cast_kind {
20182083 CastKind :: Pointer ( PointerCast :: ReifyFnPointer ) => {
20192084 let fn_sig = op. ty ( body, tcx) . fn_sig ( tcx) ;
@@ -2260,6 +2325,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22602325 BinOp :: Eq | BinOp :: Ne | BinOp :: Lt | BinOp :: Le | BinOp :: Gt | BinOp :: Ge ,
22612326 box ( left, right) ,
22622327 ) => {
2328+ self . check_operand ( left, location) ;
2329+ self . check_operand ( right, location) ;
2330+
22632331 let ty_left = left. ty ( body, tcx) ;
22642332 match ty_left. kind ( ) {
22652333 // Types with regions are comparable if they have a common super-type.
@@ -2310,13 +2378,19 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
23102378 }
23112379 }
23122380
2381+ Rvalue :: Use ( operand) | Rvalue :: UnaryOp ( _, operand) => {
2382+ self . check_operand ( operand, location) ;
2383+ }
2384+
2385+ Rvalue :: BinaryOp ( _, box ( left, right) )
2386+ | Rvalue :: CheckedBinaryOp ( _, box ( left, right) ) => {
2387+ self . check_operand ( left, location) ;
2388+ self . check_operand ( right, location) ;
2389+ }
2390+
23132391 Rvalue :: AddressOf ( ..)
23142392 | Rvalue :: ThreadLocalRef ( ..)
2315- | Rvalue :: Use ( ..)
23162393 | Rvalue :: Len ( ..)
2317- | Rvalue :: BinaryOp ( ..)
2318- | Rvalue :: CheckedBinaryOp ( ..)
2319- | Rvalue :: UnaryOp ( ..)
23202394 | Rvalue :: Discriminant ( ..) => { }
23212395 }
23222396 }
0 commit comments