@@ -10,6 +10,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
10
10
use rustc_data_structures:: vec_map:: VecMap ;
11
11
use rustc_errors:: struct_span_err;
12
12
use rustc_hir as hir;
13
+ use rustc_hir:: def:: DefKind ;
13
14
use rustc_hir:: def_id:: LocalDefId ;
14
15
use rustc_hir:: lang_items:: LangItem ;
15
16
use rustc_index:: vec:: { Idx , IndexVec } ;
@@ -1532,6 +1533,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1532
1533
}
1533
1534
}
1534
1535
TerminatorKind :: SwitchInt { ref discr, switch_ty, .. } => {
1536
+ self . check_operand ( discr, term_location) ;
1537
+
1535
1538
let discr_ty = discr. ty ( body, tcx) ;
1536
1539
if let Err ( terr) = self . sub_types (
1537
1540
discr_ty,
@@ -1554,6 +1557,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1554
1557
// FIXME: check the values
1555
1558
}
1556
1559
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
+
1557
1565
let func_ty = func. ty ( body, tcx) ;
1558
1566
debug ! ( "check_terminator: call, func_ty={:?}" , func_ty) ;
1559
1567
let sig = match func_ty. kind ( ) {
@@ -1598,6 +1606,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1598
1606
self . check_call_inputs ( body, term, & sig, args, term_location, from_hir_call) ;
1599
1607
}
1600
1608
TerminatorKind :: Assert { ref cond, ref msg, .. } => {
1609
+ self . check_operand ( cond, term_location) ;
1610
+
1601
1611
let cond_ty = cond. ty ( body, tcx) ;
1602
1612
if cond_ty != tcx. types . bool {
1603
1613
span_mirbug ! ( self , term, "bad Assert ({:?}, not bool" , cond_ty) ;
@@ -1613,6 +1623,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1613
1623
}
1614
1624
}
1615
1625
TerminatorKind :: Yield { ref value, .. } => {
1626
+ self . check_operand ( value, term_location) ;
1627
+
1616
1628
let value_ty = value. ty ( body, tcx) ;
1617
1629
match body. yield_ty ( ) {
1618
1630
None => span_mirbug ! ( self , term, "yield in non-generator" ) ,
@@ -1941,15 +1953,51 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1941
1953
}
1942
1954
}
1943
1955
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
+
1944
1987
fn check_rvalue ( & mut self , body : & Body < ' tcx > , rvalue : & Rvalue < ' tcx > , location : Location ) {
1945
1988
let tcx = self . tcx ( ) ;
1946
1989
1947
1990
match rvalue {
1948
1991
Rvalue :: Aggregate ( ak, ops) => {
1992
+ for op in ops {
1993
+ self . check_operand ( op, location) ;
1994
+ }
1949
1995
self . check_aggregate_rvalue ( & body, rvalue, ak, ops, location)
1950
1996
}
1951
1997
1952
1998
Rvalue :: Repeat ( operand, len) => {
1999
+ self . check_operand ( operand, location) ;
2000
+
1953
2001
// If the length cannot be evaluated we must assume that the length can be larger
1954
2002
// than 1.
1955
2003
// 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> {
2000
2048
}
2001
2049
}
2002
2050
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
+
2004
2067
let trait_ref = ty:: TraitRef {
2005
2068
def_id : tcx. require_lang_item ( LangItem :: Sized , Some ( self . last_span ) ) ,
2006
2069
substs : tcx. mk_substs_trait ( ty, & [ ] ) ,
@@ -2014,6 +2077,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2014
2077
}
2015
2078
2016
2079
Rvalue :: Cast ( cast_kind, op, ty) => {
2080
+ self . check_operand ( op, location) ;
2081
+
2017
2082
match cast_kind {
2018
2083
CastKind :: Pointer ( PointerCast :: ReifyFnPointer ) => {
2019
2084
let fn_sig = op. ty ( body, tcx) . fn_sig ( tcx) ;
@@ -2260,6 +2325,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2260
2325
BinOp :: Eq | BinOp :: Ne | BinOp :: Lt | BinOp :: Le | BinOp :: Gt | BinOp :: Ge ,
2261
2326
box ( left, right) ,
2262
2327
) => {
2328
+ self . check_operand ( left, location) ;
2329
+ self . check_operand ( right, location) ;
2330
+
2263
2331
let ty_left = left. ty ( body, tcx) ;
2264
2332
match ty_left. kind ( ) {
2265
2333
// Types with regions are comparable if they have a common super-type.
@@ -2310,13 +2378,19 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2310
2378
}
2311
2379
}
2312
2380
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
+
2313
2391
Rvalue :: AddressOf ( ..)
2314
2392
| Rvalue :: ThreadLocalRef ( ..)
2315
- | Rvalue :: Use ( ..)
2316
2393
| Rvalue :: Len ( ..)
2317
- | Rvalue :: BinaryOp ( ..)
2318
- | Rvalue :: CheckedBinaryOp ( ..)
2319
- | Rvalue :: UnaryOp ( ..)
2320
2394
| Rvalue :: Discriminant ( ..) => { }
2321
2395
}
2322
2396
}
0 commit comments