@@ -56,19 +56,13 @@ bitflags! {
56
56
// Function argument.
57
57
const FN_ARGUMENT = 1 << 2 ;
58
58
59
- // Static place or move from a static.
60
- const STATIC = 1 << 3 ;
61
-
62
- // Reference to a static.
63
- const STATIC_REF = 1 << 4 ;
64
-
65
59
// Not constant at all - non-`const fn` calls, asm!,
66
60
// pointer comparisons, ptr-to-int casts, etc.
67
- const NOT_CONST = 1 << 5 ;
61
+ const NOT_CONST = 1 << 3 ;
68
62
69
63
// Refers to temporaries which cannot be promoted as
70
64
// promote_consts decided they weren't simple enough.
71
- const NOT_PROMOTABLE = 1 << 6 ;
65
+ const NOT_PROMOTABLE = 1 << 4 ;
72
66
73
67
// Const items can only have MUTABLE_INTERIOR
74
68
// and NOT_PROMOTABLE without producing an error.
@@ -226,42 +220,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
226
220
self . add ( original) ;
227
221
}
228
222
229
- /// Check if a Local with the current qualifications is promotable.
230
- fn can_promote ( & self , qualif : Qualif ) -> bool {
231
- // References to statics are allowed, but only in other statics.
232
- if self . mode == Mode :: Static || self . mode == Mode :: StaticMut {
233
- ( qualif - Qualif :: STATIC_REF ) . is_empty ( )
234
- } else {
235
- qualif. is_empty ( )
236
- }
237
- }
238
-
239
- /// Check if a Place with the current qualifications could
240
- /// be consumed, by either an operand or a Deref projection.
241
- fn try_consume ( & mut self ) -> bool {
242
- if self . qualif . intersects ( Qualif :: STATIC ) && self . mode != Mode :: Fn {
243
- let msg = if self . mode == Mode :: Static ||
244
- self . mode == Mode :: StaticMut {
245
- "cannot refer to other statics by value, use the \
246
- address-of operator or a constant instead"
247
- } else {
248
- "cannot refer to statics by value, use a constant instead"
249
- } ;
250
- struct_span_err ! ( self . tcx. sess, self . span, E0394 , "{}" , msg)
251
- . span_label ( self . span , "referring to another static by value" )
252
- . note ( "use the address-of operator or a constant instead" )
253
- . emit ( ) ;
254
-
255
- // Replace STATIC with NOT_CONST to avoid further errors.
256
- self . qualif = self . qualif - Qualif :: STATIC ;
257
- self . add ( Qualif :: NOT_CONST ) ;
258
-
259
- false
260
- } else {
261
- true
262
- }
263
- }
264
-
265
223
/// Assign the current qualification to the given destination.
266
224
fn assign ( & mut self , dest : & Place < ' tcx > , location : Location ) {
267
225
trace ! ( "assign: {:?}" , dest) ;
@@ -305,7 +263,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
305
263
} ) if self . mir . local_kind ( index) == LocalKind :: Temp
306
264
&& self . mir . local_decls [ index] . ty . is_box ( )
307
265
&& self . local_qualif [ index] . map_or ( false , |qualif| {
308
- qualif. intersects ( Qualif :: NOT_CONST )
266
+ qualif. contains ( Qualif :: NOT_CONST )
309
267
} ) => {
310
268
// Part of `box expr`, we should've errored
311
269
// already for the Box allocation Rvalue.
@@ -492,17 +450,21 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
492
450
match * place {
493
451
Place :: Local ( ref local) => self . visit_local ( local, context, location) ,
494
452
Place :: Static ( ref global) => {
495
- self . add ( Qualif :: STATIC ) ;
453
+ // Only allow statics (not consts) to refer to other statics.
454
+ if !( self . mode == Mode :: Static || self . mode == Mode :: StaticMut ) {
455
+ self . add ( Qualif :: NOT_CONST ) ;
456
+ }
496
457
497
458
if self . mode != Mode :: Fn {
498
- for attr in & self . tcx . get_attrs ( global. def_id ) [ ..] {
499
- if attr. check_name ( "thread_local" ) {
500
- span_err ! ( self . tcx. sess, self . span, E0625 ,
501
- "thread-local statics cannot be \
502
- accessed at compile-time") ;
503
- self . add ( Qualif :: NOT_CONST ) ;
504
- return ;
505
- }
459
+ if self . tcx
460
+ . get_attrs ( global. def_id )
461
+ . iter ( )
462
+ . any ( |attr| attr. check_name ( "thread_local" ) ) {
463
+ span_err ! ( self . tcx. sess, self . span, E0625 ,
464
+ "thread-local statics cannot be \
465
+ accessed at compile-time") ;
466
+ self . add ( Qualif :: NOT_CONST ) ;
467
+ return ;
506
468
}
507
469
}
508
470
@@ -527,15 +489,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
527
489
this. super_place ( place, context, location) ;
528
490
match proj. elem {
529
491
ProjectionElem :: Deref => {
530
- if !this. try_consume ( ) {
531
- return ;
532
- }
533
-
534
- if this. qualif . intersects ( Qualif :: STATIC_REF ) {
535
- this. qualif = this. qualif - Qualif :: STATIC_REF ;
536
- this. add ( Qualif :: STATIC ) ;
537
- }
538
-
539
492
this. add ( Qualif :: NOT_CONST ) ;
540
493
541
494
let base_ty = proj. base . ty ( this. mir , this. tcx ) . to_ty ( this. tcx ) ;
@@ -573,11 +526,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
573
526
this. not_const ( ) ;
574
527
}
575
528
}
576
- } else if this. qualif . intersects ( Qualif :: STATIC ) {
577
- span_err ! ( this. tcx. sess, this. span, E0494 ,
578
- "cannot refer to the interior of another \
579
- static, use a constant instead") ;
580
529
}
530
+
581
531
let ty = place. ty ( this. mir , this. tcx ) . to_ty ( this. tcx ) ;
582
532
this. qualif . restrict ( ty, this. tcx , this. param_env ) ;
583
533
}
@@ -599,7 +549,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
599
549
Operand :: Move ( _) => {
600
550
self . nest ( |this| {
601
551
this. super_operand ( operand, location) ;
602
- this. try_consume ( ) ;
603
552
} ) ;
604
553
605
554
// Mark the consumed locals to indicate later drops are noops.
@@ -651,14 +600,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
651
600
region,
652
601
kind
653
602
} , location) ;
654
- if !this. try_consume ( ) {
655
- return ;
656
- }
657
-
658
- if this. qualif . intersects ( Qualif :: STATIC_REF ) {
659
- this. qualif = this. qualif - Qualif :: STATIC_REF ;
660
- this. add ( Qualif :: STATIC ) ;
661
- }
662
603
} ) ;
663
604
} else {
664
605
self . super_rvalue ( rvalue, location) ;
@@ -678,22 +619,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
678
619
Rvalue :: Cast ( CastKind :: UnsafeFnPointer , ..) |
679
620
Rvalue :: Cast ( CastKind :: ClosureFnPointer , ..) |
680
621
Rvalue :: Cast ( CastKind :: Unsize , ..) |
681
- Rvalue :: Discriminant ( ..) => { }
682
-
683
- Rvalue :: Len ( _) => {
684
- // Static places in consts would have errored already,
685
- // don't treat length checks as reads from statics.
686
- self . qualif = self . qualif - Qualif :: STATIC ;
687
- }
622
+ Rvalue :: Discriminant ( ..) |
623
+ Rvalue :: Len ( _) => { }
688
624
689
625
Rvalue :: Ref ( _, kind, ref place) => {
690
- // Static places in consts would have errored already,
691
- // only keep track of references to them here.
692
- if self . qualif . intersects ( Qualif :: STATIC ) {
693
- self . qualif = self . qualif - Qualif :: STATIC ;
694
- self . add ( Qualif :: STATIC_REF ) ;
695
- }
696
-
697
626
let ty = place. ty ( self . mir , self . tcx ) . to_ty ( self . tcx ) ;
698
627
699
628
// Default to forbidding the borrow and/or its promotion,
@@ -744,7 +673,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
744
673
// Constants cannot be borrowed if they contain interior mutability as
745
674
// it means that our "silent insertion of statics" could change
746
675
// initializer values (very bad).
747
- if self . qualif . intersects ( Qualif :: MUTABLE_INTERIOR ) {
676
+ if self . qualif . contains ( Qualif :: MUTABLE_INTERIOR ) {
748
677
// A reference of a MUTABLE_INTERIOR place is instead
749
678
// NOT_CONST (see `if forbidden_mut` below), to avoid
750
679
// duplicate errors (from reborrowing, for example).
@@ -781,7 +710,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
781
710
// This allows borrowing fields which don't have
782
711
// `MUTABLE_INTERIOR`, from a type that does, e.g.:
783
712
// `let _: &'static _ = &(Cell::new(1), 2).1;`
784
- if self . can_promote ( qualif - Qualif :: MUTABLE_INTERIOR ) {
713
+ if ( qualif - Qualif :: MUTABLE_INTERIOR ) . is_empty ( ) {
785
714
self . promotion_candidates . push ( candidate) ;
786
715
}
787
716
}
@@ -889,7 +818,7 @@ This does not pose a problem by itself because they can't be accessed directly."
889
818
if Some ( def. did ) == self . tcx . lang_items ( ) . unsafe_cell_type ( ) {
890
819
let ty = rvalue. ty ( self . mir , self . tcx ) ;
891
820
self . add_type ( ty) ;
892
- assert ! ( self . qualif. intersects ( Qualif :: MUTABLE_INTERIOR ) ) ;
821
+ assert ! ( self . qualif. contains ( Qualif :: MUTABLE_INTERIOR ) ) ;
893
822
}
894
823
}
895
824
}
@@ -949,7 +878,7 @@ This does not pose a problem by itself because they can't be accessed directly."
949
878
}
950
879
let candidate = Candidate :: Argument { bb, index : i } ;
951
880
if is_shuffle && i == 2 {
952
- if this. can_promote ( this . qualif ) {
881
+ if this. qualif . is_empty ( ) {
953
882
this. promotion_candidates . push ( candidate) ;
954
883
} else {
955
884
span_err ! ( this. tcx. sess, this. span, E0526 ,
@@ -965,7 +894,7 @@ This does not pose a problem by itself because they can't be accessed directly."
965
894
if !constant_arguments. contains ( & i) {
966
895
return
967
896
}
968
- if this. can_promote ( this . qualif ) {
897
+ if this. qualif . is_empty ( ) {
969
898
this. promotion_candidates . push ( candidate) ;
970
899
} else {
971
900
this. tcx . sess . span_err ( this. span ,
@@ -1059,7 +988,7 @@ This does not pose a problem by itself because they can't be accessed directly."
1059
988
// HACK(eddyb) Emulate a bit of dataflow analysis,
1060
989
// conservatively, that drop elaboration will do.
1061
990
let needs_drop = if let Place :: Local ( local) = * place {
1062
- if self . local_qualif [ local] . map_or ( true , |q| q. intersects ( Qualif :: NEEDS_DROP ) ) {
991
+ if self . local_qualif [ local] . map_or ( true , |q| q. contains ( Qualif :: NEEDS_DROP ) ) {
1063
992
Some ( self . mir . local_decls [ local] . source_info . span )
1064
993
} else {
1065
994
None
@@ -1111,7 +1040,7 @@ This does not pose a problem by itself because they can't be accessed directly."
1111
1040
}
1112
1041
1113
1042
// Avoid a generic error for other uses of arguments.
1114
- if self . qualif . intersects ( Qualif :: FN_ARGUMENT ) {
1043
+ if self . qualif . contains ( Qualif :: FN_ARGUMENT ) {
1115
1044
let decl = & self . mir . local_decls [ index] ;
1116
1045
let mut err = feature_err (
1117
1046
& self . tcx . sess . parse_sess ,
0 commit comments