@@ -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 } ;
@@ -1343,13 +1344,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
13431344 // though.
13441345 let category = match place. as_local ( ) {
13451346 Some ( RETURN_PLACE ) => {
1346- if let BorrowCheckContext {
1347- universal_regions :
1348- UniversalRegions { defining_ty : DefiningTy :: Const ( def_id, _) , .. } ,
1349- ..
1350- } = self . borrowck_context
1351- {
1352- if tcx. is_static ( * def_id) {
1347+ let defining_ty = & self . borrowck_context . universal_regions . defining_ty ;
1348+ if defining_ty. is_const ( ) {
1349+ if tcx. is_static ( defining_ty. def_id ( ) ) {
13531350 ConstraintCategory :: UseAsStatic
13541351 } else {
13551352 ConstraintCategory :: UseAsConst
@@ -1527,6 +1524,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
15271524 }
15281525 }
15291526 TerminatorKind :: SwitchInt { ref discr, switch_ty, .. } => {
1527+ self . check_operand ( discr, term_location) ;
1528+
15301529 let discr_ty = discr. ty ( body, tcx) ;
15311530 if let Err ( terr) = self . sub_types (
15321531 discr_ty,
@@ -1549,6 +1548,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
15491548 // FIXME: check the values
15501549 }
15511550 TerminatorKind :: Call { ref func, ref args, ref destination, from_hir_call, .. } => {
1551+ self . check_operand ( func, term_location) ;
1552+ for arg in args {
1553+ self . check_operand ( arg, term_location) ;
1554+ }
1555+
15521556 let func_ty = func. ty ( body, tcx) ;
15531557 debug ! ( "check_terminator: call, func_ty={:?}" , func_ty) ;
15541558 let sig = match func_ty. kind ( ) {
@@ -1593,6 +1597,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
15931597 self . check_call_inputs ( body, term, & sig, args, term_location, from_hir_call) ;
15941598 }
15951599 TerminatorKind :: Assert { ref cond, ref msg, .. } => {
1600+ self . check_operand ( cond, term_location) ;
1601+
15961602 let cond_ty = cond. ty ( body, tcx) ;
15971603 if cond_ty != tcx. types . bool {
15981604 span_mirbug ! ( self , term, "bad Assert ({:?}, not bool" , cond_ty) ;
@@ -1608,6 +1614,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
16081614 }
16091615 }
16101616 TerminatorKind :: Yield { ref value, .. } => {
1617+ self . check_operand ( value, term_location) ;
1618+
16111619 let value_ty = value. ty ( body, tcx) ;
16121620 match body. yield_ty ( ) {
16131621 None => span_mirbug ! ( self , term, "yield in non-generator" ) ,
@@ -1650,7 +1658,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
16501658 Some ( RETURN_PLACE ) => {
16511659 if let BorrowCheckContext {
16521660 universal_regions :
1653- UniversalRegions { defining_ty : DefiningTy :: Const ( def_id, _) , .. } ,
1661+ UniversalRegions {
1662+ defining_ty :
1663+ DefiningTy :: Const ( def_id, _)
1664+ | DefiningTy :: InlineConst ( def_id, _) ,
1665+ ..
1666+ } ,
16541667 ..
16551668 } = self . borrowck_context
16561669 {
@@ -1931,15 +1944,51 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19311944 }
19321945 }
19331946
1947+ fn check_operand ( & mut self , op : & Operand < ' tcx > , location : Location ) {
1948+ if let Operand :: Constant ( constant) = op {
1949+ let maybe_uneval = match constant. literal {
1950+ ConstantKind :: Ty ( ct) => match ct. val {
1951+ ty:: ConstKind :: Unevaluated ( uv) => Some ( uv) ,
1952+ _ => None ,
1953+ } ,
1954+ _ => None ,
1955+ } ;
1956+ if let Some ( uv) = maybe_uneval {
1957+ if uv. promoted . is_none ( ) {
1958+ let tcx = self . tcx ( ) ;
1959+ let def_id = uv. def . def_id_for_type_of ( ) ;
1960+ if tcx. def_kind ( def_id) == DefKind :: InlineConst {
1961+ let predicates = self . prove_closure_bounds (
1962+ tcx,
1963+ def_id. expect_local ( ) ,
1964+ uv. substs ( tcx) ,
1965+ location,
1966+ ) ;
1967+ self . normalize_and_prove_instantiated_predicates (
1968+ def_id,
1969+ predicates,
1970+ location. to_locations ( ) ,
1971+ ) ;
1972+ }
1973+ }
1974+ }
1975+ }
1976+ }
1977+
19341978 fn check_rvalue ( & mut self , body : & Body < ' tcx > , rvalue : & Rvalue < ' tcx > , location : Location ) {
19351979 let tcx = self . tcx ( ) ;
19361980
19371981 match rvalue {
19381982 Rvalue :: Aggregate ( ak, ops) => {
1983+ for op in ops {
1984+ self . check_operand ( op, location) ;
1985+ }
19391986 self . check_aggregate_rvalue ( & body, rvalue, ak, ops, location)
19401987 }
19411988
19421989 Rvalue :: Repeat ( operand, len) => {
1990+ self . check_operand ( operand, location) ;
1991+
19431992 // If the length cannot be evaluated we must assume that the length can be larger
19441993 // than 1.
19451994 // If the length is larger than 1, the repeat expression will need to copy the
@@ -1990,7 +2039,22 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19902039 }
19912040 }
19922041
1993- Rvalue :: NullaryOp ( _, ty) | Rvalue :: ShallowInitBox ( _, ty) => {
2042+ Rvalue :: NullaryOp ( _, ty) => {
2043+ let trait_ref = ty:: TraitRef {
2044+ def_id : tcx. require_lang_item ( LangItem :: Sized , Some ( self . last_span ) ) ,
2045+ substs : tcx. mk_substs_trait ( ty, & [ ] ) ,
2046+ } ;
2047+
2048+ self . prove_trait_ref (
2049+ trait_ref,
2050+ location. to_locations ( ) ,
2051+ ConstraintCategory :: SizedBound ,
2052+ ) ;
2053+ }
2054+
2055+ Rvalue :: ShallowInitBox ( operand, ty) => {
2056+ self . check_operand ( operand, location) ;
2057+
19942058 let trait_ref = ty:: TraitRef {
19952059 def_id : tcx. require_lang_item ( LangItem :: Sized , Some ( self . last_span ) ) ,
19962060 substs : tcx. mk_substs_trait ( ty, & [ ] ) ,
@@ -2004,6 +2068,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20042068 }
20052069
20062070 Rvalue :: Cast ( cast_kind, op, ty) => {
2071+ self . check_operand ( op, location) ;
2072+
20072073 match cast_kind {
20082074 CastKind :: Pointer ( PointerCast :: ReifyFnPointer ) => {
20092075 let fn_sig = op. ty ( body, tcx) . fn_sig ( tcx) ;
@@ -2250,6 +2316,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22502316 BinOp :: Eq | BinOp :: Ne | BinOp :: Lt | BinOp :: Le | BinOp :: Gt | BinOp :: Ge ,
22512317 box ( left, right) ,
22522318 ) => {
2319+ self . check_operand ( left, location) ;
2320+ self . check_operand ( right, location) ;
2321+
22532322 let ty_left = left. ty ( body, tcx) ;
22542323 match ty_left. kind ( ) {
22552324 // Types with regions are comparable if they have a common super-type.
@@ -2300,13 +2369,19 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
23002369 }
23012370 }
23022371
2372+ Rvalue :: Use ( operand) | Rvalue :: UnaryOp ( _, operand) => {
2373+ self . check_operand ( operand, location) ;
2374+ }
2375+
2376+ Rvalue :: BinaryOp ( _, box ( left, right) )
2377+ | Rvalue :: CheckedBinaryOp ( _, box ( left, right) ) => {
2378+ self . check_operand ( left, location) ;
2379+ self . check_operand ( right, location) ;
2380+ }
2381+
23032382 Rvalue :: AddressOf ( ..)
23042383 | Rvalue :: ThreadLocalRef ( ..)
2305- | Rvalue :: Use ( ..)
23062384 | Rvalue :: Len ( ..)
2307- | Rvalue :: BinaryOp ( ..)
2308- | Rvalue :: CheckedBinaryOp ( ..)
2309- | Rvalue :: UnaryOp ( ..)
23102385 | Rvalue :: Discriminant ( ..) => { }
23112386 }
23122387 }
0 commit comments