@@ -412,6 +412,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
412
412
. insert ( ( root_place. clone ( ) , borrow_span) ) ;
413
413
414
414
let mut err = match & self . describe_place ( & borrow. borrowed_place ) {
415
+ Some ( _) if self . is_place_thread_local ( root_place) => {
416
+ self . report_thread_local_value_does_not_live_long_enough (
417
+ drop_span,
418
+ borrow_span,
419
+ )
420
+ }
415
421
Some ( name) => self . report_local_value_does_not_live_long_enough (
416
422
context,
417
423
name,
@@ -455,9 +461,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
455
461
context, name, scope_tree, borrow, drop_span, borrow_span
456
462
) ;
457
463
458
- let tcx = self . tcx ;
459
- let mut err =
460
- tcx . path_does_not_live_long_enough ( borrow_span , & format ! ( "`{}`" , name ) , Origin :: Mir ) ;
464
+ let mut err = self . tcx . path_does_not_live_long_enough (
465
+ borrow_span , & format ! ( "`{}`" , name ) , Origin :: Mir ) ;
466
+
461
467
err. span_label ( borrow_span, "borrowed value does not live long enough" ) ;
462
468
err. span_label (
463
469
drop_span,
@@ -468,6 +474,27 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
468
474
err
469
475
}
470
476
477
+ fn report_thread_local_value_does_not_live_long_enough (
478
+ & mut self ,
479
+ drop_span : Span ,
480
+ borrow_span : Span ,
481
+ ) -> DiagnosticBuilder < ' cx > {
482
+ debug ! (
483
+ "report_thread_local_value_does_not_live_long_enough(\
484
+ {:?}, {:?}\
485
+ )",
486
+ drop_span, borrow_span
487
+ ) ;
488
+
489
+ let mut err = self . tcx . thread_local_value_does_not_live_long_enough (
490
+ borrow_span, Origin :: Mir ) ;
491
+
492
+ err. span_label ( borrow_span,
493
+ "thread-local variables cannot be borrowed beyond the end of the function" ) ;
494
+ err. span_label ( drop_span, "end of enclosing function is here" ) ;
495
+ err
496
+ }
497
+
471
498
fn report_temporary_value_does_not_live_long_enough (
472
499
& mut self ,
473
500
context : Context ,
@@ -856,6 +883,21 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
856
883
} ,
857
884
}
858
885
}
886
+
887
+ /// Check if a place is a thread-local static.
888
+ pub fn is_place_thread_local ( & self , place : & Place < ' tcx > ) -> bool {
889
+ if let Place :: Static ( statik) = place {
890
+ let attrs = self . tcx . get_attrs ( statik. def_id ) ;
891
+ let is_thread_local = attrs. iter ( ) . any ( |attr| attr. check_name ( "thread_local" ) ) ;
892
+
893
+ debug ! ( "is_place_thread_local: attrs={:?} is_thread_local={:?}" ,
894
+ attrs, is_thread_local) ;
895
+ is_thread_local
896
+ } else {
897
+ debug ! ( "is_place_thread_local: no" ) ;
898
+ false
899
+ }
900
+ }
859
901
}
860
902
861
903
// The span(s) associated to a use of a place.
0 commit comments