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 +140
-64
lines changed Expand file tree Collapse file tree 11 files changed +140
-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 @@ -684,15 +684,17 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
684
684
self . opaque_types_defined_by ( defining_anchor)
685
685
}
686
686
687
- fn opaque_types_and_generators_defined_by (
687
+ fn opaque_types_and_coroutines_defined_by (
688
688
self ,
689
689
defining_anchor : Self :: LocalDefId ,
690
690
) -> Self :: LocalDefIds {
691
691
if self . next_trait_solver_globally ( ) {
692
+ let coroutines_defined_by = self
693
+ . nested_bodies_within ( defining_anchor)
694
+ . iter ( )
695
+ . filter ( |def_id| self . is_coroutine ( def_id. to_def_id ( ) ) ) ;
692
696
self . mk_local_def_ids_from_iter (
693
- self . opaque_types_defined_by ( defining_anchor)
694
- . iter ( )
695
- . chain ( self . stalled_generators_within ( defining_anchor) ) ,
697
+ self . opaque_types_defined_by ( defining_anchor) . iter ( ) . chain ( coroutines_defined_by) ,
696
698
)
697
699
} else {
698
700
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 > (
8
+ tcx : TyCtxt < ' tcx > ,
9
+ item : LocalDefId ,
10
+ ) -> & ' tcx ty:: List < LocalDefId > {
11
+ let body = tcx. hir_body_owned_by ( item) ;
12
+ let mut collector =
13
+ NestedBodiesVisitor { tcx, root_def_id : item. to_def_id ( ) , nested_bodies : vec ! [ ] } ;
14
+ collector. visit_body ( body) ;
15
+ tcx. mk_local_def_ids ( & collector. nested_bodies )
16
+ }
17
+
18
+ struct NestedBodiesVisitor < ' tcx > {
19
+ tcx : TyCtxt < ' tcx > ,
20
+ root_def_id : DefId ,
21
+ nested_bodies : Vec < LocalDefId > ,
22
+ }
23
+
24
+ impl < ' tcx > Visitor < ' tcx > for NestedBodiesVisitor < ' tcx > {
25
+ fn visit_nested_body ( & mut self , id : hir:: BodyId ) {
26
+ let body_def_id = self . tcx . hir_body_owner_def_id ( id) ;
27
+ if self . tcx . typeck_root_def_id ( body_def_id. to_def_id ( ) )
28
+ == self . root_def_id
29
+ {
30
+ self . nested_bodies . push ( body_def_id) ;
31
+ let body = self . tcx . hir_body ( id) ;
32
+ self . visit_body ( body) ;
33
+ }
34
+ }
35
+ }
36
+
37
+ pub ( super ) fn provide ( providers : & mut Providers ) {
38
+ * providers = Providers { nested_bodies_within, ..* providers } ;
39
+ }
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