6
6
7
7
use rustc_index:: bit_set:: BitSet ;
8
8
use rustc_index:: vec:: IndexVec ;
9
- use rustc_data_structures:: fx:: FxHashSet ;
10
9
use rustc_target:: spec:: abi:: Abi ;
11
10
use rustc:: hir;
12
11
use rustc:: hir:: def_id:: DefId ;
@@ -20,7 +19,6 @@ use rustc::mir::traversal::ReversePostorder;
20
19
use rustc:: mir:: visit:: { PlaceContext , Visitor , MutatingUseContext , NonMutatingUseContext } ;
21
20
use rustc:: middle:: lang_items;
22
21
use rustc:: session:: config:: nightly_options;
23
- use syntax:: ast:: LitKind ;
24
22
use syntax:: feature_gate:: { emit_feature_err, GateIssue } ;
25
23
use syntax:: symbol:: sym;
26
24
use syntax_pos:: { Span , DUMMY_SP } ;
@@ -678,7 +676,6 @@ struct Checker<'a, 'tcx> {
678
676
rpo : ReversePostorder < ' a , ' tcx > ,
679
677
680
678
temp_promotion_state : IndexVec < Local , TempState > ,
681
- promotion_candidates : Vec < Candidate > ,
682
679
unchecked_promotion_candidates : Vec < Candidate > ,
683
680
684
681
/// If `true`, do not emit errors to the user, merely collect them in `errors`.
@@ -748,7 +745,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
748
745
def_id,
749
746
rpo,
750
747
temp_promotion_state : temps,
751
- promotion_candidates : vec ! [ ] ,
752
748
unchecked_promotion_candidates,
753
749
errors : vec ! [ ] ,
754
750
suppress_errors : false ,
@@ -794,7 +790,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
794
790
let mut qualifs = self . qualifs_in_value ( source) ;
795
791
796
792
match source {
797
- ValueSource :: Rvalue ( & Rvalue :: Ref ( _, kind, ref place ) ) => {
793
+ ValueSource :: Rvalue ( & Rvalue :: Ref ( _, kind, _ ) ) => {
798
794
// Getting `true` from `HasMutInterior::in_rvalue` means
799
795
// the borrowed place is disallowed from being borrowed,
800
796
// due to either a mutable borrow (with some exceptions),
@@ -833,57 +829,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
833
829
}
834
830
}
835
831
}
836
- } else if let BorrowKind :: Mut { .. } | BorrowKind :: Shared = kind {
837
- // Don't promote BorrowKind::Shallow borrows, as they don't
838
- // reach codegen.
839
- // FIXME(eddyb) the two other kinds of borrow (`Shallow` and `Unique`)
840
- // aren't promoted here but *could* be promoted as part of a larger
841
- // value because `IsNotPromotable` isn't being set for them,
842
- // need to figure out what is the intended behavior.
843
-
844
- // We might have a candidate for promotion.
845
- let candidate = Candidate :: Ref ( location) ;
846
- // Start by traversing to the "base", with non-deref projections removed.
847
- let deref_proj =
848
- place. projection . iter ( ) . rev ( ) . find ( |& elem| * elem == ProjectionElem :: Deref ) ;
849
-
850
- debug ! (
851
- "qualify_consts: promotion candidate: place={:?} {:?}" ,
852
- place. base, deref_proj
853
- ) ;
854
- // We can only promote interior borrows of promotable temps (non-temps
855
- // don't get promoted anyway).
856
- // (If we bailed out of the loop due to a `Deref` above, we will definitely
857
- // not enter the conditional here.)
858
- if let ( PlaceBase :: Local ( local) , None ) = ( & place. base , deref_proj) {
859
- if self . body . local_kind ( * local) == LocalKind :: Temp {
860
- debug ! ( "qualify_consts: promotion candidate: local={:?}" , local) ;
861
- // The borrowed place doesn't have `HasMutInterior`
862
- // (from `in_rvalue`), so we can safely ignore
863
- // `HasMutInterior` from the local's qualifications.
864
- // This allows borrowing fields which don't have
865
- // `HasMutInterior`, from a type that does, e.g.:
866
- // `let _: &'static _ = &(Cell::new(1), 2).1;`
867
- let mut local_qualifs = self . qualifs_in_local ( * local) ;
868
- // Any qualifications, except HasMutInterior (see above), disqualify
869
- // from promotion.
870
- // This is, in particular, the "implicit promotion" version of
871
- // the check making sure that we don't run drop glue during const-eval.
872
- local_qualifs[ HasMutInterior ] = false ;
873
- if !local_qualifs. 0 . iter ( ) . any ( |& qualif| qualif) {
874
- debug ! ( "qualify_consts: promotion candidate: {:?}" , candidate) ;
875
- self . promotion_candidates . push ( candidate) ;
876
- }
877
- }
878
- }
879
- }
880
- } ,
881
- ValueSource :: Rvalue ( & Rvalue :: Repeat ( ref operand, _) ) => {
882
- debug ! ( "assign: self.cx.mode={:?} self.def_id={:?} location={:?} operand={:?}" ,
883
- self . cx. mode, self . def_id, location, operand) ;
884
- if self . should_promote_repeat_expression ( operand) &&
885
- self . tcx . features ( ) . const_in_array_repeat_expressions {
886
- self . promotion_candidates . push ( Candidate :: Repeat ( location) ) ;
887
832
}
888
833
} ,
889
834
_ => { } ,
@@ -1047,22 +992,17 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
1047
992
// Collect all the temps we need to promote.
1048
993
let mut promoted_temps = BitSet :: new_empty ( self . temp_promotion_state . len ( ) ) ;
1049
994
1050
- // HACK(eddyb) don't try to validate promotion candidates if any
1051
- // parts of the control-flow graph were skipped due to an error.
1052
- let promotion_candidates = if has_controlflow_error {
1053
- let unleash_miri = self
1054
- . tcx
1055
- . sess
1056
- . opts
1057
- . debugging_opts
1058
- . unleash_the_miri_inside_of_you ;
1059
- if !unleash_miri {
1060
- self . tcx . sess . delay_span_bug (
1061
- body. span ,
1062
- "check_const: expected control-flow error(s)" ,
1063
- ) ;
1064
- }
1065
- self . promotion_candidates . clone ( )
995
+ // HACK: if parts of the control-flow graph were skipped due to an error, don't try to
996
+ // promote anything, since that can cause errors in a `const` if e.g. rvalue static
997
+ // promotion is attempted within a loop body.
998
+ let unleash_miri = self . tcx . sess . opts . debugging_opts . unleash_the_miri_inside_of_you ;
999
+ let promotion_candidates = if has_controlflow_error && !unleash_miri {
1000
+ self . tcx . sess . delay_span_bug (
1001
+ body. span ,
1002
+ "check_const: expected control-flow error(s)" ,
1003
+ ) ;
1004
+
1005
+ vec ! [ ]
1066
1006
} else {
1067
1007
promote_consts:: validate_candidates (
1068
1008
self . tcx ,
@@ -1111,15 +1051,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
1111
1051
1112
1052
( qualifs. encode_to_bits ( ) , self . tcx . arena . alloc ( promoted_temps) )
1113
1053
}
1114
-
1115
- /// Returns `true` if the operand of a repeat expression is promotable.
1116
- fn should_promote_repeat_expression ( & self , operand : & Operand < ' tcx > ) -> bool {
1117
- let not_promotable = IsNotImplicitlyPromotable :: in_operand ( self , operand) ||
1118
- IsNotPromotable :: in_operand ( self , operand) ;
1119
- debug ! ( "should_promote_repeat_expression: operand={:?} not_promotable={:?}" ,
1120
- operand, not_promotable) ;
1121
- !not_promotable
1122
- }
1123
1054
}
1124
1055
1125
1056
impl < ' a , ' tcx > Visitor < ' tcx > for Checker < ' a , ' tcx > {
@@ -1431,11 +1362,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
1431
1362
}
1432
1363
1433
1364
let fn_ty = func. ty ( self . body , self . tcx ) ;
1434
- let mut callee_def_id = None ;
1435
- let mut is_shuffle = false ;
1436
1365
match fn_ty. kind {
1437
1366
ty:: FnDef ( def_id, _) => {
1438
- callee_def_id = Some ( def_id) ;
1439
1367
match self . tcx . fn_sig ( def_id) . abi ( ) {
1440
1368
Abi :: RustIntrinsic |
1441
1369
Abi :: PlatformIntrinsic => {
@@ -1459,10 +1387,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
1459
1387
}
1460
1388
}
1461
1389
1462
- name if name. starts_with ( "simd_shuffle" ) => {
1463
- is_shuffle = true ;
1464
- }
1465
-
1466
1390
// no need to check feature gates, intrinsics are only callable
1467
1391
// from the libstd or with forever unstable feature gates
1468
1392
_ => { }
@@ -1550,36 +1474,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
1550
1474
}
1551
1475
}
1552
1476
1553
- // No need to do anything in constants and statics, as everything is "constant" anyway
1554
- // so promotion would be useless.
1555
- if self . mode != Mode :: Static && self . mode != Mode :: Const {
1556
- let constant_args = callee_def_id. and_then ( |id| {
1557
- args_required_const ( self . tcx , id)
1558
- } ) . unwrap_or_default ( ) ;
1559
- for ( i, arg) in args. iter ( ) . enumerate ( ) {
1560
- if !( is_shuffle && i == 2 || constant_args. contains ( & i) ) {
1561
- continue ;
1562
- }
1563
-
1564
- let candidate = Candidate :: Argument { bb : location. block , index : i } ;
1565
- // Since the argument is required to be constant,
1566
- // we care about constness, not promotability.
1567
- // If we checked for promotability, we'd miss out on
1568
- // the results of function calls (which are never promoted
1569
- // in runtime code).
1570
- // This is not a problem, because the argument explicitly
1571
- // requests constness, in contrast to regular promotion
1572
- // which happens even without the user requesting it.
1573
- //
1574
- // `promote_consts` is responsible for emitting the error if
1575
- // the argument is not promotable.
1576
- if !IsNotPromotable :: in_operand ( self , arg) {
1577
- debug ! ( "visit_terminator_kind: candidate={:?}" , candidate) ;
1578
- self . promotion_candidates . push ( candidate) ;
1579
- }
1580
- }
1581
- }
1582
-
1583
1477
// Check callee and argument operands.
1584
1478
self . visit_operand ( func, location) ;
1585
1479
for arg in args {
@@ -1887,19 +1781,6 @@ fn check_static_is_sync(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, hir_id: HirId)
1887
1781
} ) ;
1888
1782
}
1889
1783
1890
- fn args_required_const ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> Option < FxHashSet < usize > > {
1891
- let attrs = tcx. get_attrs ( def_id) ;
1892
- let attr = attrs. iter ( ) . find ( |a| a. check_name ( sym:: rustc_args_required_const) ) ?;
1893
- let mut ret = FxHashSet :: default ( ) ;
1894
- for meta in attr. meta_item_list ( ) ? {
1895
- match meta. literal ( ) ?. kind {
1896
- LitKind :: Int ( a, _) => { ret. insert ( a as usize ) ; }
1897
- _ => return None ,
1898
- }
1899
- }
1900
- Some ( ret)
1901
- }
1902
-
1903
1784
fn validator_mismatch (
1904
1785
tcx : TyCtxt < ' tcx > ,
1905
1786
body : & Body < ' tcx > ,
0 commit comments