@@ -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 } ;
@@ -1343,13 +1344,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1343
1344
// though.
1344
1345
let category = match place. as_local ( ) {
1345
1346
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 ( ) ) {
1353
1350
ConstraintCategory :: UseAsStatic
1354
1351
} else {
1355
1352
ConstraintCategory :: UseAsConst
@@ -1527,6 +1524,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1527
1524
}
1528
1525
}
1529
1526
TerminatorKind :: SwitchInt { ref discr, switch_ty, .. } => {
1527
+ self . check_operand ( discr, term_location) ;
1528
+
1530
1529
let discr_ty = discr. ty ( body, tcx) ;
1531
1530
if let Err ( terr) = self . sub_types (
1532
1531
discr_ty,
@@ -1549,6 +1548,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1549
1548
// FIXME: check the values
1550
1549
}
1551
1550
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
+
1552
1556
let func_ty = func. ty ( body, tcx) ;
1553
1557
debug ! ( "check_terminator: call, func_ty={:?}" , func_ty) ;
1554
1558
let sig = match func_ty. kind ( ) {
@@ -1593,6 +1597,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1593
1597
self . check_call_inputs ( body, term, & sig, args, term_location, from_hir_call) ;
1594
1598
}
1595
1599
TerminatorKind :: Assert { ref cond, ref msg, .. } => {
1600
+ self . check_operand ( cond, term_location) ;
1601
+
1596
1602
let cond_ty = cond. ty ( body, tcx) ;
1597
1603
if cond_ty != tcx. types . bool {
1598
1604
span_mirbug ! ( self , term, "bad Assert ({:?}, not bool" , cond_ty) ;
@@ -1608,6 +1614,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1608
1614
}
1609
1615
}
1610
1616
TerminatorKind :: Yield { ref value, .. } => {
1617
+ self . check_operand ( value, term_location) ;
1618
+
1611
1619
let value_ty = value. ty ( body, tcx) ;
1612
1620
match body. yield_ty ( ) {
1613
1621
None => span_mirbug ! ( self , term, "yield in non-generator" ) ,
@@ -1650,7 +1658,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1650
1658
Some ( RETURN_PLACE ) => {
1651
1659
if let BorrowCheckContext {
1652
1660
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
+ } ,
1654
1667
..
1655
1668
} = self . borrowck_context
1656
1669
{
@@ -1931,15 +1944,51 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1931
1944
}
1932
1945
}
1933
1946
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
+
1934
1978
fn check_rvalue ( & mut self , body : & Body < ' tcx > , rvalue : & Rvalue < ' tcx > , location : Location ) {
1935
1979
let tcx = self . tcx ( ) ;
1936
1980
1937
1981
match rvalue {
1938
1982
Rvalue :: Aggregate ( ak, ops) => {
1983
+ for op in ops {
1984
+ self . check_operand ( op, location) ;
1985
+ }
1939
1986
self . check_aggregate_rvalue ( & body, rvalue, ak, ops, location)
1940
1987
}
1941
1988
1942
1989
Rvalue :: Repeat ( operand, len) => {
1990
+ self . check_operand ( operand, location) ;
1991
+
1943
1992
// If the length cannot be evaluated we must assume that the length can be larger
1944
1993
// than 1.
1945
1994
// 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> {
1990
2039
}
1991
2040
}
1992
2041
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
+
1994
2058
let trait_ref = ty:: TraitRef {
1995
2059
def_id : tcx. require_lang_item ( LangItem :: Sized , Some ( self . last_span ) ) ,
1996
2060
substs : tcx. mk_substs_trait ( ty, & [ ] ) ,
@@ -2004,6 +2068,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2004
2068
}
2005
2069
2006
2070
Rvalue :: Cast ( cast_kind, op, ty) => {
2071
+ self . check_operand ( op, location) ;
2072
+
2007
2073
match cast_kind {
2008
2074
CastKind :: Pointer ( PointerCast :: ReifyFnPointer ) => {
2009
2075
let fn_sig = op. ty ( body, tcx) . fn_sig ( tcx) ;
@@ -2250,6 +2316,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2250
2316
BinOp :: Eq | BinOp :: Ne | BinOp :: Lt | BinOp :: Le | BinOp :: Gt | BinOp :: Ge ,
2251
2317
box ( left, right) ,
2252
2318
) => {
2319
+ self . check_operand ( left, location) ;
2320
+ self . check_operand ( right, location) ;
2321
+
2253
2322
let ty_left = left. ty ( body, tcx) ;
2254
2323
match ty_left. kind ( ) {
2255
2324
// Types with regions are comparable if they have a common super-type.
@@ -2300,13 +2369,19 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2300
2369
}
2301
2370
}
2302
2371
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
+
2303
2382
Rvalue :: AddressOf ( ..)
2304
2383
| Rvalue :: ThreadLocalRef ( ..)
2305
- | Rvalue :: Use ( ..)
2306
2384
| Rvalue :: Len ( ..)
2307
- | Rvalue :: BinaryOp ( ..)
2308
- | Rvalue :: CheckedBinaryOp ( ..)
2309
- | Rvalue :: UnaryOp ( ..)
2310
2385
| Rvalue :: Discriminant ( ..) => { }
2311
2386
}
2312
2387
}
0 commit comments