This repository was archived by the owner on May 28, 2025. It is now read-only.
File tree Expand file tree Collapse file tree 11 files changed +135
-64
lines changed Expand file tree Collapse file tree 11 files changed +135
-64
lines changed Original file line number Diff line number Diff line change @@ -127,6 +127,14 @@ fn mir_borrowck(
127
127
Ok ( tcx. arena . alloc ( opaque_types) )
128
128
} else {
129
129
let mut root_cx = BorrowCheckRootCtxt :: new ( tcx, def) ;
130
+ // We need to manually borrowck all nested bodies from the HIR as
131
+ // we do not generate MIR for dead code. Not doing so causes us to
132
+ // never check closures in dead code.
133
+ let nested_bodies = tcx. nested_bodies_within ( def) ;
134
+ for def_id in nested_bodies {
135
+ root_cx. get_or_insert_nested ( def_id) ;
136
+ }
137
+
130
138
let PropagatedBorrowCheckResults { closure_requirements, used_mut_upvars } =
131
139
do_mir_borrowck ( & mut root_cx, def, None ) . 0 ;
132
140
debug_assert ! ( closure_requirements. is_none( ) ) ;
Original file line number Diff line number Diff line change @@ -62,7 +62,10 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
62
62
self . tainted_by_errors = Some ( guar) ;
63
63
}
64
64
65
- fn get_or_insert_nested ( & mut self , def_id : LocalDefId ) -> & PropagatedBorrowCheckResults < ' tcx > {
65
+ pub ( super ) fn get_or_insert_nested (
66
+ & mut self ,
67
+ def_id : LocalDefId ,
68
+ ) -> & PropagatedBorrowCheckResults < ' tcx > {
66
69
debug_assert_eq ! (
67
70
self . tcx. typeck_root_def_id( def_id. to_def_id( ) ) ,
68
71
self . root_def_id. to_def_id( )
Original file line number Diff line number Diff line change @@ -387,7 +387,7 @@ rustc_queries! {
387
387
}
388
388
}
389
389
390
- query stalled_generators_within (
390
+ query nested_bodies_within (
391
391
key: LocalDefId
392
392
) -> & ' tcx ty:: List <LocalDefId > {
393
393
desc {
Original file line number Diff line number Diff line change @@ -691,15 +691,17 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
691
691
self . opaque_types_defined_by ( defining_anchor)
692
692
}
693
693
694
- fn opaque_types_and_generators_defined_by (
694
+ fn opaque_types_and_coroutines_defined_by (
695
695
self ,
696
696
defining_anchor : Self :: LocalDefId ,
697
697
) -> Self :: LocalDefIds {
698
698
if self . next_trait_solver_globally ( ) {
699
+ let coroutines_defined_by = self
700
+ . nested_bodies_within ( defining_anchor)
701
+ . iter ( )
702
+ . filter ( |def_id| self . is_coroutine ( def_id. to_def_id ( ) ) ) ;
699
703
self . mk_local_def_ids_from_iter (
700
- self . opaque_types_defined_by ( defining_anchor)
701
- . iter ( )
702
- . chain ( self . stalled_generators_within ( defining_anchor) ) ,
704
+ self . opaque_types_defined_by ( defining_anchor) . iter ( ) . chain ( coroutines_defined_by) ,
703
705
)
704
706
} else {
705
707
self . opaque_types_defined_by ( defining_anchor)
Original file line number Diff line number Diff line change @@ -29,10 +29,10 @@ mod implied_bounds;
29
29
mod instance;
30
30
mod layout;
31
31
mod needs_drop;
32
+ mod nested_bodies;
32
33
mod opaque_types;
33
34
mod representability;
34
35
pub mod sig_types;
35
- mod stalled_generators;
36
36
mod structural_match;
37
37
mod ty;
38
38
@@ -51,5 +51,5 @@ pub fn provide(providers: &mut Providers) {
51
51
ty:: provide ( providers) ;
52
52
instance:: provide ( providers) ;
53
53
structural_match:: provide ( providers) ;
54
- stalled_generators :: provide ( providers) ;
54
+ nested_bodies :: provide ( providers) ;
55
55
}
Original file line number Diff line number Diff line change
1
+ use rustc_hir as hir;
2
+ use rustc_hir:: def_id:: { DefId , LocalDefId } ;
3
+ use rustc_hir:: intravisit:: Visitor ;
4
+ use rustc_middle:: query:: Providers ;
5
+ use rustc_middle:: ty:: { self , TyCtxt } ;
6
+
7
+ fn nested_bodies_within < ' tcx > ( tcx : TyCtxt < ' tcx > , item : LocalDefId ) -> & ' tcx ty:: List < LocalDefId > {
8
+ let body = tcx. hir_body_owned_by ( item) ;
9
+ let mut collector =
10
+ NestedBodiesVisitor { tcx, root_def_id : item. to_def_id ( ) , nested_bodies : vec ! [ ] } ;
11
+ collector. visit_body ( body) ;
12
+ tcx. mk_local_def_ids ( & collector. nested_bodies )
13
+ }
14
+
15
+ struct NestedBodiesVisitor < ' tcx > {
16
+ tcx : TyCtxt < ' tcx > ,
17
+ root_def_id : DefId ,
18
+ nested_bodies : Vec < LocalDefId > ,
19
+ }
20
+
21
+ impl < ' tcx > Visitor < ' tcx > for NestedBodiesVisitor < ' tcx > {
22
+ fn visit_nested_body ( & mut self , id : hir:: BodyId ) {
23
+ let body_def_id = self . tcx . hir_body_owner_def_id ( id) ;
24
+ if self . tcx . typeck_root_def_id ( body_def_id. to_def_id ( ) ) == self . root_def_id {
25
+ self . nested_bodies . push ( body_def_id) ;
26
+ let body = self . tcx . hir_body ( id) ;
27
+ self . visit_body ( body) ;
28
+ }
29
+ }
30
+ }
31
+
32
+ pub ( super ) fn provide ( providers : & mut Providers ) {
33
+ * providers = Providers { nested_bodies_within, ..* providers } ;
34
+ }
Load Diff This file was deleted.
Original file line number Diff line number Diff line change @@ -100,7 +100,7 @@ impl<I: Interner> TypingMode<I> {
100
100
pub fn typeck_for_body ( cx : I , body_def_id : I :: LocalDefId ) -> TypingMode < I > {
101
101
TypingMode :: Analysis {
102
102
defining_opaque_types_and_generators : cx
103
- . opaque_types_and_generators_defined_by ( body_def_id) ,
103
+ . opaque_types_and_coroutines_defined_by ( body_def_id) ,
104
104
}
105
105
}
106
106
Original file line number Diff line number Diff line change @@ -341,7 +341,7 @@ pub trait Interner:
341
341
342
342
fn opaque_types_defined_by ( self , defining_anchor : Self :: LocalDefId ) -> Self :: LocalDefIds ;
343
343
344
- fn opaque_types_and_generators_defined_by (
344
+ fn opaque_types_and_coroutines_defined_by (
345
345
self ,
346
346
defining_anchor : Self :: LocalDefId ,
347
347
) -> Self :: LocalDefIds ;
Original file line number Diff line number Diff line change
1
+ //@ edition: 2024
2
+
3
+ // Regression test for #140583. We want to borrowck nested
4
+ // bodies even if they are in dead code. While not necessary for
5
+ // soundness, it is desirable to error in such cases.
6
+
7
+ fn main ( ) {
8
+ return ;
9
+ |x : & str | -> & ' static str { x } ;
10
+ //~^ ERROR lifetime may not live long enough
11
+ || {
12
+ || {
13
+ let temp = 1 ;
14
+ let p: & ' static u32 = & temp;
15
+ //~^ ERROR `temp` does not live long enough
16
+ } ;
17
+ } ;
18
+ const {
19
+ let temp = 1 ;
20
+ let p: & ' static u32 = & temp;
21
+ //~^ ERROR `temp` does not live long enough
22
+ } ;
23
+ async {
24
+ let temp = 1 ;
25
+ let p: & ' static u32 = & temp;
26
+ //~^ ERROR `temp` does not live long enough
27
+ } ;
28
+ }
You can’t perform that action at this time.
0 commit comments