Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NLL diagnostics for ref mut z @ &mut Some(ref a) uses _ as binding name #67565

Closed
Centril opened this issue Dec 23, 2019 · 5 comments · Fixed by #70389
Closed

NLL diagnostics for ref mut z @ &mut Some(ref a) uses _ as binding name #67565

Centril opened this issue Dec 23, 2019 · 5 comments · Fixed by #70389
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-NLL Area: Non Lexical Lifetimes (NLL) C-bug Category: This is a bug. D-confusing Diagnostics: Confusing error or lint that should be reworked. F-bindings_after_at `#![feature(bindings_after_at)]` NLL-diagnostics Working torwads the "diagnostic parity" goal requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Centril
Copy link
Contributor

Centril commented Dec 23, 2019

Context: #66296 (comment)

The _ below should be z instead.

error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable
  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:31
   |
LL |         ref mut z @ &mut Some(ref a) => {
   |         ----------------------^^^^^-
   |         |                     |
   |         |                     immutable borrow occurs here
   |         mutable borrow occurs here
...
LL |             **z = None;
   |             ---------- mutable borrow later used here

cc @mark-i-m @pnkfelix @matthewjasper

cc #65490


Minimal reproducer:

#![feature(bindings_after_at)]

fn foo() {
    let ref mut _z @ ref _a = &mut 1;
    **_z = 0;
}
@Centril Centril added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. requires-nightly This issue requires a nightly compiler in some way. D-confusing Diagnostics: Confusing error or lint that should be reworked. F-bindings_after_at `#![feature(bindings_after_at)]` labels Dec 23, 2019
@Centril Centril added A-NLL Area: Non Lexical Lifetimes (NLL) NLL-diagnostics Working torwads the "diagnostic parity" goal labels Dec 23, 2019
@mark-i-m
Copy link
Member

I feel like the internal use of _ as a default name for things is a bit undisciplined, and it's leaking into diagnostics in annoying ways. There is also this: #66679

I feel like internally, we should keep a strong separation between names that we get from the source code being compiled and names being generated by the compiler...

@Centril
Copy link
Contributor Author

Centril commented Dec 28, 2019

I think this issue is about the narrow issue of why this happens in the case of ref mut x @ Some(ref y) though whereas it doesn't happen in other cases.

@mark-i-m
Copy link
Member

@Centril Sure, but I think it stems from a larger problem of undisciplined use of _ in various places... If we don't fix that, then we will get weird bugs like this showing up again later even if we fix this particular example....

@Centril
Copy link
Contributor Author

Centril commented Dec 29, 2019

@mark-i-m I don't mind fixing this by fixing the root cause, but can we discuss the bigger issue in a issue made for that and cc this one?

@Centril
Copy link
Contributor Author

Centril commented Feb 17, 2020

Investigation

Source input:

#![feature(bindings_after_at)]

fn foo() {
    let ref mut _z @ ref _a = &mut 1;
    **_z = 0;
}

Results in the following MIR:

fn  foo() -> () {
    let mut _0: ();                      // return place in scope 0 at foo.rs:5:10: 5:10
    let _1: &mut &mut i32;               // in scope 0 at foo.rs:6:9: 6:28
    let _2: &&mut i32;                   // in scope 0 at foo.rs:6:22: 6:28
    let mut _3: &mut i32;                // in scope 0 at foo.rs:6:31: 6:37
    let mut _4: i32;                     // in scope 0 at foo.rs:6:36: 6:37
    scope 1 {
        debug _z => _1;                  // in scope 1 at foo.rs:6:9: 6:28
        debug _a => _2;                  // in scope 1 at foo.rs:6:22: 6:28
    }

    bb0: {
        StorageLive(_3);                 // bb0[0]: scope 0 at foo.rs:6:31: 6:37
        StorageLive(_4);                 // bb0[1]: scope 0 at foo.rs:6:36: 6:37
        _4 = const 1i32;                 // bb0[2]: scope 0 at foo.rs:6:36: 6:37
                                         // ty::Const
                                         // + ty: i32
                                         // + val: Value(Scalar(0x00000001))
                                         // mir::Constant
                                         // + span: foo.rs:6:36: 6:37
                                         // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }   
        _3 = &mut _4;                    // bb0[3]: scope 0 at foo.rs:6:31: 6:37
        StorageLive(_1);                 // bb0[4]: scope 0 at foo.rs:6:9: 6:28
        _1 = &mut _3;                    // bb0[5]: scope 0 at foo.rs:6:9: 6:28
        StorageLive(_2);                 // bb0[6]: scope 0 at foo.rs:6:22: 6:28
        _2 = &_3;                        // bb0[7]: scope 0 at foo.rs:6:22: 6:28
        (*(*_1)) = const 0i32;           // bb0[8]: scope 1 at foo.rs:7:5: 7:13
                                         // ty::Const
                                         // + ty: i32
                                         // + val: Value(Scalar(0x00000000))
                                         // mir::Constant
                                         // + span: foo.rs:7:12: 7:13
                                         // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }   
        _0 = ();                         // bb0[9]: scope 0 at foo.rs:5:10: 8:2
        StorageDead(_2);                 // bb0[10]: scope 0 at foo.rs:8:1: 8:2
        StorageDead(_1);                 // bb0[11]: scope 0 at foo.rs:8:1: 8:2
        StorageDead(_4);                 // bb0[12]: scope 0 at foo.rs:8:1: 8:2
        StorageDead(_3);                 // bb0[13]: scope 0 at foo.rs:8:1: 8:2
        return;                          // bb0[14]: scope 0 at foo.rs:8:2: 8:2
    }
}

And we double check with some debug!s in ast_block_stmts (in the if let Some(init) = initializer { branch):

                        debug!("ast_block_stmts: local_decls={:#?}", this.local_decls);
                        debug!("ast_block_stmts: var_debug_info={:#?}", this.var_debug_info);
                        debug!("ast_block_stmts: var_indices={:#?}", this.var_indices);

using RUSTC_LOG=rustc_mir_build::build::block=debug rustc +gamma-stage1 -Z dump-mir=nll foo.rs we get:

[DEBUG rustc_mir_build::build::block] ast_block_stmts: local_decls=[                                       
        LocalDecl {                                                                                        
            mutability: Mut,                                                                               
            local_info: Other,                                                                             
            internal: false,                                                                               
            is_block_tail: None,                                                                           
            ty: (),                                                                                        
            user_ty: UserTypeProjections {                                                                 
                contents: [],                                                                              
            },                                                                                             
            source_info: SourceInfo {                                                                      
                span: foo.rs:5:10: 5:10,                                                                   
                scope: scope[0],                                                                           
            },                                                                                             
        },                                                                                                 
        LocalDecl {                                                                                        
            mutability: Not,                                                                               
            local_info: User(                                                                              
                Set(                                                                                       
                    Var(                                                                                   
                        VarBindingForm {                                                                   
                            binding_mode: BindByReference(                                                 
                                Not,                                                                       
                            ),                                                                             
                            opt_ty_info: None,                                                             
                            opt_match_place: Some(                                                         
                                (                                                                          
                                    Some(                                                                  
                                        _3,                                                                
                                    ),                                                                     
                                    foo.rs:6:31: 6:37,                                                     
                                ),                                                                         
                            ),                                                                             
                            pat_span: foo.rs:6:9: 6:28,                                                    
                        },                                                                                 
                    ),                                                                                     
                ),                                                                                         
            ),                                                                                             
            internal: false,                                                                               
            is_block_tail: None,                                                                           
            ty: &mut &mut i32,                                                                             
            user_ty: UserTypeProjections {                                                                 
                contents: [],                                                                              
            },                                                                                             
            source_info: SourceInfo {                                                                      
                span: foo.rs:6:9: 6:28,                                                                    
                scope: scope[0],                                                                           
            },                                                                                             
        },
        LocalDecl {                                                                                        
            mutability: Not,                                                                               
            local_info: User(                                                                              
                Set(                                                                                       
                    Var(                                                                                   
                        VarBindingForm {                                                                   
                            binding_mode: BindByReference(                                                 
                                Not,                                                                       
                            ),                                                                             
                            opt_ty_info: None,                                                             
                            opt_match_place: Some(                                                         
                                (
                                    Some(
                                        _3,
                                    ),
                                    foo.rs:6:31: 6:37,
                                ),
                            ),
                            pat_span: foo.rs:6:9: 6:28,
                        },
                    ),
                ),
            ),
            internal: false,
            is_block_tail: None,
            ty: &&mut i32,
            user_ty: UserTypeProjections {
                contents: [],
            },
            source_info: SourceInfo {
                span: foo.rs:6:22: 6:28,
                scope: scope[0],
            },
        },
        LocalDecl {
            mutability: Mut,
            local_info: Other,
            internal: false,
            is_block_tail: None,
            ty: &mut i32,
            user_ty: UserTypeProjections {
                contents: [],
            },
            source_info: SourceInfo {
                span: foo.rs:6:31: 6:37,
                scope: scope[0],
            },
        },
        LocalDecl {
            mutability: Mut,
            local_info: Other,
            internal: false,
            is_block_tail: None,
            ty: i32,
            user_ty: UserTypeProjections {
                contents: [],
            },
            source_info: SourceInfo {
                span: foo.rs:6:36: 6:37,
                scope: scope[0],
            },
        },
    ]
[DEBUG rustc_mir_build::build::block] ast_block_stmts: var_debug_info=[
        VarDebugInfo {
            name: "_z",
            source_info: SourceInfo {
                span: foo.rs:6:9: 6:28,
                scope: scope[1],
            },
            place: _1,
        },
        VarDebugInfo {
            name: "_a",
            source_info: SourceInfo {
                span: foo.rs:6:22: 6:28,
                scope: scope[1],
            },
            place: _2,
        },
    ]
[DEBUG rustc_mir_build::build::block] ast_block_stmts: var_indices={
        HirId {
            owner: DefIndex(4),
            local_id: 1,
        }: One(
            _1,
        ),
        HirId {
            owner: DefIndex(4),
            local_id: 2,
        }: One(
            _2,
        ),
    }

Borrow checking trace:

The error comes from describe_place_for_conflicting_borrow, which is fed:

[DEBUG rustc_mir::borrow_check::diagnostics::conflict_errors] describe_place_for_conflicting_borrow(first = _3, second, _3)

We eventually end up in append_local_to_string, where we have (with some changes to the code):

[DEBUG rustc_mir::borrow_check::diagnostics] append_local_to_string; self.local_names = [
        None,
        Some(
            "_z",
        ),
        Some(
            "_a",
        ),
        None,
        None,
    ]

and so it tries to compute self.local_names[_3] which gives us None and hence there is no name.

The unchanged log output on master is:

[DEBUG rustc_mir::borrow_check] MirBorrowckCtxt::process_statement(bb0[0], StorageLive(_3)): BorrowckAnalyses { borrows: [], uninits: [mp0, mp1, mp2, mp3, mp4], ever_inits: [] }
[DEBUG rustc_mir::borrow_check] MirBorrowckCtxt::process_statement(bb0[1], StorageLive(_4)): BorrowckAnalyses { borrows: [], uninits: [mp0, mp1, mp2, mp3, mp4], ever_inits: [] }
[DEBUG rustc_mir::borrow_check] MirBorrowckCtxt::process_statement(bb0[2], _4 = const 1i32): BorrowckAnalyses { borrows: [], uninits: [mp0, mp1, mp2, mp3, mp4], ever_inits: [] }
[DEBUG rustc_mir::borrow_check] check_if_assigned_path_is_moved place: _4                                                       
[DEBUG rustc_mir::borrow_check] check_access_permissions(_4, Write(Mutate), is_local_mutation_allowed: No)
[DEBUG rustc_mir::borrow_check] check_access_for_conflict(location=bb0[2], place_span=(_4, foo.rs:6:36: 6:37), sd=Shallow(None), rw=Write(Mutate))
[DEBUG rustc_mir::borrow_check] MirBorrowckCtxt::process_statement(bb0[3], _3 = &mut _4): BorrowckAnalyses { borrows: [], uninits: [mp0, mp1, mp2, mp3], ever_inits: [in0] }
[DEBUG rustc_mir::borrow_check] check_access_permissions(_4, Write(MutableBorrow(Mut { allow_two_phase_borrow: false })), is_local_mutation_allowed: No)
[DEBUG rustc_mir::borrow_check] check_access_for_conflict(location=bb0[3], place_span=(_4, foo.rs:6:31: 6:37), sd=Deep, rw=Write(MutableBorrow(Mut { allow_two_phase_borrow: false })))
[DEBUG rustc_mir::borrow_check] check_if_full_path_is_moved place: PlaceRef { local: _4, projection: [] }
[DEBUG rustc_mir::borrow_check] check_if_path_or_subpath_is_moved place: PlaceRef { local: _4, projection: [] }
[DEBUG rustc_mir::borrow_check] check_if_assigned_path_is_moved place: _3
[DEBUG rustc_mir::borrow_check] check_access_permissions(_3, Write(Mutate), is_local_mutation_allowed: No)
[DEBUG rustc_mir::borrow_check] check_access_for_conflict(location=bb0[3], place_span=(_3, foo.rs:6:31: 6:37), sd=Shallow(None), rw=Write(Mutate))
[DEBUG rustc_mir::borrow_check] MirBorrowckCtxt::process_statement(bb0[4], StorageLive(_1)): BorrowckAnalyses { borrows: [bw0], uninits: [mp0, mp1, mp2], ever_inits: [in0, in1] }
[DEBUG rustc_mir::borrow_check] MirBorrowckCtxt::process_statement(bb0[5], _1 = &mut _3): BorrowckAnalyses { borrows: [bw0], uninits: [mp0, mp1, mp2], ever_inits: [in0, in1] }
[DEBUG rustc_mir::borrow_check] check_access_permissions(_3, Write(MutableBorrow(Mut { allow_two_phase_borrow: false })), is_local_mutation_allowed: No)
[DEBUG rustc_mir::borrow_check] check_access_for_conflict(location=bb0[5], place_span=(_3, foo.rs:6:9: 6:28), sd=Deep, rw=Write(MutableBorrow(Mut { allow_two_phase_borrow: false })))
[DEBUG rustc_mir::borrow_check::places_conflict] borrow_conflicts_with_place(_4, PlaceRef { local: _3, projection: [] }, Deep, Overlap)
[DEBUG rustc_mir::borrow_check] check_if_full_path_is_moved place: PlaceRef { local: _3, projection: [] }
[DEBUG rustc_mir::borrow_check] check_if_path_or_subpath_is_moved place: PlaceRef { local: _3, projection: [] }
[DEBUG rustc_mir::borrow_check] check_if_assigned_path_is_moved place: _1
[DEBUG rustc_mir::borrow_check] check_if_reassignment_to_immutable_state(_1)
[DEBUG rustc_mir::borrow_check] MirBorrowckCtxt::process_statement(bb0[6], StorageLive(_2)): BorrowckAnalyses { borrows: [bw0, bw1], uninits: [mp0, mp2], ever_inits: [in0, in1, in2] }
[DEBUG rustc_mir::borrow_check] MirBorrowckCtxt::process_statement(bb0[7], _2 = &_3): BorrowckAnalyses { borrows: [bw0, bw1], uninits: [mp0, mp2], ever_inits: [in0, in1, in2] }
[DEBUG rustc_mir::borrow_check] check_access_permissions(_3, Read(Borrow(Shared)), is_local_mutation_allowed: No)
[DEBUG rustc_mir::borrow_check] check_access_for_conflict(location=bb0[7], place_span=(_3, foo.rs:6:22: 6:28), sd=Deep, rw=Read(Borrow(Shared)))
[DEBUG rustc_mir::borrow_check::places_conflict] borrow_conflicts_with_place(_4, PlaceRef { local: _3, projection: [] }, Deep, Overlap)
[DEBUG rustc_mir::borrow_check::places_conflict] borrow_conflicts_with_place(_3, PlaceRef { local: _3, projection: [] }, Deep, Overlap)
[DEBUG rustc_mir::borrow_check::path_utils] each_borrow_involving_path: bw1 @ BorrowData { reserve_location: bb0[5], activation_location: NotTwoPhase, kind: Mut { allow_two_phase_borrow: false }, region: '_#3r, borrowed_place: _3, 
assigned_place: _1 } vs. _3/Deep
[DEBUG rustc_mir::borrow_check::path_utils] is_active(borrow_data=BorrowData { reserve_location: bb0[5], activation_location: NotTwoPhase, kind: Mut { allow_two_phase_borrow: false }, region: '_#3r, borrowed_place: _3, assigned_place: _1 }, location=bb0[7])
[DEBUG rustc_mir::borrow_check::diagnostics] borrow_spans: use_span=foo.rs:6:9: 6:28 location=bb0[5]
[DEBUG rustc_mir::borrow_check::diagnostics] borrow_spans: use_span=foo.rs:6:22: 6:28 location=bb0[7]
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] explain_why_borrow_contains_point(location=bb0[7], borrow=BorrowData { reserve_location: bb0[5], activation_location: NotTwoPhase, kind: Mut { allow_two_phase_borrow: false }, region: '_#3r, borrowed_place: _3, assigned_place: _1 }, kind_place=None)
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] explain_why_borrow_contains_point: borrow_region_vid='_#3r
[DEBUG rustc_mir::borrow_check::region_infer] find_sub_region_live_at(fr1='_#3r, elem=bb0[7])
[DEBUG rustc_mir::borrow_check::region_infer] find_constraint_paths_between_regions: from_region='_#3r r='_#3r value={bb0[5..=8]}
[DEBUG rustc_mir::borrow_check::region_infer] find_sub_region_live_at: liveness_constraints for '_#3r are "{bb0[5]}"
[DEBUG rustc_mir::borrow_check::region_infer] find_constraint_paths_between_regions: from_region='_#3r r='_#5r value={bb0[6..=8]}
[DEBUG rustc_mir::borrow_check::region_infer] find_sub_region_live_at: liveness_constraints for '_#5r are "{bb0[6..=8]}"
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] explain_why_borrow_contains_point: region_sub='_#5r
[DEBUG rustc_mir::borrow_check::diagnostics] move_spans: moved_place=PlaceRef { local: _1, projection: [] } location=bb0[8] stmt=(*(*_1)) = const 0i32
[DEBUG rustc_mir::borrow_check::diagnostics] borrow_spans: use_span=foo.rs:7:5: 7:13 location=bb0[8]
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] reach_through_backedge: from=bb0[8] to=bb0[8]
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] reach_through_backedge: location=bb0[8] outmost_back_edge=None
                       pending_locations=[] visited_locations={bb0[8]}
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] reach_through_backedge: location=bb0[9] outmost_back_edge=None
                       pending_locations=[] visited_locations={bb0[8], bb0[9]}
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] reach_through_backedge: location=bb0[10] outmost_back_edge=None
                       pending_locations=[] visited_locations={bb0[8], bb0[9], bb0[10]}
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] reach_through_backedge: location=bb0[11] outmost_back_edge=None
                       pending_locations=[] visited_locations={bb0[8], bb0[10], bb0[9], bb0[11]}
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] reach_through_backedge: location=bb0[12] outmost_back_edge=None
                       pending_locations=[] visited_locations={bb0[8], bb0[10], bb0[12], bb0[9], bb0[11]}
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] reach_through_backedge: location=bb0[13] outmost_back_edge=None
                       pending_locations=[] visited_locations={bb0[8], bb0[13], bb0[10], bb0[12], bb0[9], bb0[11]}
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] reach_through_backedge: location=bb0[14] outmost_back_edge=None
                       pending_locations=[] visited_locations={bb0[8], bb0[13], bb0[10], bb0[12], bb0[9], bb0[14], bb0[11]}
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait_object: location=bb0[5] stmt=Some(_1 = &mut _3)
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: target=_1 queue=[bb0[5]]
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: target=_1
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait_object: stmt=_1 = &mut _3
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: queue=[bb0[6]]
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: target=_1
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait_object: stmt=StorageLive(_2)
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: queue=[bb0[7]]
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: target=_1
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait_object: stmt=_2 = &_3
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: queue=[bb0[8]]
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: target=_1
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait_object: stmt=(*(*_1)) = const 0i32
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: target=_1
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait_object: stmt=_0 = ()
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: queue=[bb0[10]]
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: target=_1
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait_object: stmt=StorageDead(_2)
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: queue=[bb0[11]]
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: target=_1
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait_object: stmt=StorageDead(_1)
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: queue=[bb0[12]]
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: target=_1
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait_object: stmt=StorageDead(_4)
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: queue=[bb0[13]]
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: target=_1
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait_object: stmt=StorageDead(_3)
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: queue=[bb0[14]]
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: target=_1
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait_object: terminator=Terminator { source_info: SourceInfo { span: foo.rs:8:2: 8:2, scope: scope[0] }, kind: return }
[DEBUG rustc_mir::borrow_check::diagnostics::explain_borrow] was_captured_by_trait: queue=[]
[DEBUG rustc_mir::borrow_check] access_place: logging error place_span=`(_3, foo.rs:6:22: 6:28)` kind=`(Deep, Read(Borrow(Shared)))`
[DEBUG rustc_mir::borrow_check] check_if_full_path_is_moved place: PlaceRef { local: _3, projection: [] }
[DEBUG rustc_mir::borrow_check] check_if_path_or_subpath_is_moved place: PlaceRef { local: _3, projection: [] }
[DEBUG rustc_mir::borrow_check] check_if_assigned_path_is_moved place: _2
[DEBUG rustc_mir::borrow_check] check_if_reassignment_to_immutable_state(_2)
[DEBUG rustc_mir::borrow_check] MirBorrowckCtxt::process_statement(bb0[8], (*(*_1)) = const 0i32): BorrowckAnalyses { borrows: [bw0, bw1], uninits: [mp0], ever_inits: [in0, in1, in2, in3] }
[DEBUG rustc_mir::borrow_check] check_if_assigned_path_is_moved place: (*(*_1))
[DEBUG rustc_mir::borrow_check] check_if_full_path_is_moved place: PlaceRef { local: _1, projection: [Deref] }
[DEBUG rustc_mir::borrow_check] check_access_permissions((*(*_1)), Write(Mutate), is_local_mutation_allowed: No)
[DEBUG rustc_mir::borrow_check] check_access_for_conflict(location=bb0[8], place_span=((*(*_1)), foo.rs:7:5: 7:13), sd=Shallow(None), rw=Write(Mutate))
[DEBUG rustc_mir::borrow_check::places_conflict] borrow_conflicts_with_place(_4, PlaceRef { local: _1, projection: [Deref, Deref] }, Shallow(None), Overlap)
[DEBUG rustc_mir::borrow_check::places_conflict] place_element_conflict: DISJOINT-LOCAL
[DEBUG rustc_mir::borrow_check::places_conflict] borrow_conflicts_with_place: disjoint
[DEBUG rustc_mir::borrow_check::places_conflict] borrow_conflicts_with_place(_3, PlaceRef { local: _1, projection: [Deref, Deref] }, Shallow(None), Overlap)
[DEBUG rustc_mir::borrow_check::places_conflict] place_element_conflict: DISJOINT-LOCAL
[DEBUG rustc_mir::borrow_check::places_conflict] borrow_conflicts_with_place: disjoint
[DEBUG rustc_mir::borrow_check] MirBorrowckCtxt::process_statement(bb0[9], _0 = ()): BorrowckAnalyses { borrows: [], uninits: [mp0], ever_inits: [in0, in1, in2, in3] }
[DEBUG rustc_mir::borrow_check] check_if_assigned_path_is_moved place: _0
[DEBUG rustc_mir::borrow_check] check_access_permissions(_0, Write(Mutate), is_local_mutation_allowed: No)
[DEBUG rustc_mir::borrow_check] check_access_for_conflict(location=bb0[9], place_span=(_0, foo.rs:5:12: 8:2), sd=Shallow(None), rw=Write(Mutate))
[DEBUG rustc_mir::borrow_check] MirBorrowckCtxt::process_statement(bb0[10], StorageDead(_2)): BorrowckAnalyses { borrows: [], uninits: [], ever_inits: [in0, in1, in2, in3, in4] }
[DEBUG rustc_mir::borrow_check] check_access_permissions(_2, Write(StorageDeadOrDrop), is_local_mutation_allowed: Yes)
[DEBUG rustc_mir::borrow_check] check_access_for_conflict(location=bb0[10], place_span=(_2, foo.rs:8:1: 8:2), sd=Shallow(None), rw=Write(StorageDeadOrDrop))
[DEBUG rustc_mir::borrow_check] MirBorrowckCtxt::process_statement(bb0[11], StorageDead(_1)): BorrowckAnalyses { borrows: [], uninits: [mp2], ever_inits: [in0, in1, in2, in4] }
[DEBUG rustc_mir::borrow_check] check_access_permissions(_1, Write(StorageDeadOrDrop), is_local_mutation_allowed: Yes)
[DEBUG rustc_mir::borrow_check] check_access_for_conflict(location=bb0[11], place_span=(_1, foo.rs:8:1: 8:2), sd=Shallow(None), rw=Write(StorageDeadOrDrop))
[DEBUG rustc_mir::borrow_check] MirBorrowckCtxt::process_statement(bb0[12], StorageDead(_4)): BorrowckAnalyses { borrows: [], uninits: [mp1, mp2], ever_inits: [in0, in1, in4] }
[DEBUG rustc_mir::borrow_check] check_access_permissions(_4, Write(StorageDeadOrDrop), is_local_mutation_allowed: Yes)
[DEBUG rustc_mir::borrow_check] check_access_for_conflict(location=bb0[12], place_span=(_4, foo.rs:8:1: 8:2), sd=Shallow(None), rw=Write(StorageDeadOrDrop))
[DEBUG rustc_mir::borrow_check] MirBorrowckCtxt::process_statement(bb0[13], StorageDead(_3)): BorrowckAnalyses { borrows: [], uninits: [mp1, mp2, mp4], ever_inits: [in1, in4] }
[DEBUG rustc_mir::borrow_check] check_access_permissions(_3, Write(StorageDeadOrDrop), is_local_mutation_allowed: Yes)
[DEBUG rustc_mir::borrow_check] check_access_for_conflict(location=bb0[13], place_span=(_3, foo.rs:8:1: 8:2), sd=Shallow(None), rw=Write(StorageDeadOrDrop))
[DEBUG rustc_mir::borrow_check] MirBorrowckCtxt::process_terminator(bb0[14], Terminator { source_info: SourceInfo { span: foo.rs:8:2: 8:2, scope: scope[0] }, kind: return }): BorrowckAnalyses { borrows: [], uninits: [mp1, mp2, mp3, mp4], ever_inits: [in4] }
[DEBUG rustc_mir::borrow_check::used_muts] visit_statement: statement=_4 = const 1i32 local=_4 never_initialized_mut_locals={}
[DEBUG rustc_mir::borrow_check::used_muts] visit_statement: statement=_3 = &mut _4 local=_3 never_initialized_mut_locals={}
[DEBUG rustc_mir::borrow_check::used_muts] visit_statement: statement=_1 = &mut _3 local=_1 never_initialized_mut_locals={}
[DEBUG rustc_mir::borrow_check::used_muts] visit_statement: statement=_2 = &_3 local=_2 never_initialized_mut_locals={}
[DEBUG rustc_mir::borrow_check::used_muts] visit_statement: statement=(*(*_1)) = const 0i32 local=_1 never_initialized_mut_locals={}
[DEBUG rustc_mir::borrow_check::used_muts] visit_statement: statement=_0 = () local=_0 never_initialized_mut_locals={}
[DEBUG rustc_mir::borrow_check::used_muts] visit_terminator_kind: kind=return
[DEBUG rustc_mir::borrow_check::used_muts] gather_used_muts: never_initialized_mut_locals={}
[DEBUG rustc_mir::borrow_check] mbcx.used_mut: {_4, _3}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-NLL Area: Non Lexical Lifetimes (NLL) C-bug Category: This is a bug. D-confusing Diagnostics: Confusing error or lint that should be reworked. F-bindings_after_at `#![feature(bindings_after_at)]` NLL-diagnostics Working torwads the "diagnostic parity" goal requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants