Skip to content

Received "note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on unknown free region bounded by scope CodeExtent(9898/CallSiteScope { fn_id: NodeId(4519), body_id: NodeId(18425) })..." #37884

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

Closed
k4rtik opened this issue Nov 19, 2016 · 13 comments · Fixed by #38552
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints P-high High priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@k4rtik
Copy link

k4rtik commented Nov 19, 2016

Receiving info about MIR or some other intermediate form in a user error report.

I tried this code which most likely has some lifetime issue that I am yet to resolve:

pub fn accept_cmd(tcp_ctx: &Arc<RwLock<TCP>>, dl_ctx: &Arc<RwLock<DataLink>>, port: u16) {
    let s = (*tcp_ctx.write().unwrap()).v_socket();                                       
    {                                                                                     
        let tcp = &mut (*tcp_ctx.write().unwrap());                                       
        match s {                                                                         
            Ok(ref sock) => {                                                             
                match tcp.v_bind(dl_ctx, *sock, None, port) {                             
                    Ok(_) => {                                                            
                        match tcp.v_listen(dl_ctx, *sock) {                               
                            Ok(_) => trace!("v_listen() succeeded"),                      
                            Err(e) => error!("v_listen: {}", e),                          
                        }                                                                 
                    }                                                                     
                                                                                          
                    Err(e) => error!("v_bind: {}", e),                                    
                }                                                                         
            }                                                                             
            Err(ref e) => error!("v_socket: {}", e),                                      
        }                                                                                 
    }                                                                                     
    let sock = s.unwrap();                                                                
    let tcp_ctx_clone = tcp_ctx.clone(); // <------------- Error here
    thread::spawn(move || {                                                               
        loop {                                                                            
            match tcp::v_accept(&tcp_ctx_clone, sock, None) {                             
                Ok(socket) => trace!("v_accept returned {}", socket),                     
                Err(e) => error!("v_accept: {}", e),                                      
            }                                                                             
        }                                                                                 
    });                                                                                   
}                                                                                         

I should have received information about the scope defined by some part of my code or if the issue is with auto-generated code then possibly no information about an internal scope.

Instead, this happened:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
   --> src/main.rs:128:33
    |
128 |     let tcp_ctx_clone = tcp_ctx.clone();
    |                                 ^^^^^
    |
    = note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on unknown free region bounded by scope CodeExtent(9898/CallSiteScope { fn_id: NodeId(4519), body_id: NodeId(18425) })...
note: ...so that types are compatible (expected &std::sync::Arc<std::sync::RwLock<tcp::TCP<'_>>>, found &std::sync::Arc<std::sync::RwLock<tcp::TCP<'_>>>)
   --> src/main.rs:128:33
    |
128 |     let tcp_ctx_clone = tcp_ctx.clone();
    |                                 ^^^^^
    = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `[closure@src/main.rs:129:19: 136:6 tcp_ctx_clone:std::sync::Arc<std::sync::RwLock<tcp::TCP<'_>>>, sock:usize]` will meet its required lifetime bounds
   --> src/main.rs:129:5
    |
129 |     thread::spawn(move || {
    |     ^^^^^^^^^^^^^

Meta

rustc --version --verbose:

rustc 1.15.0-nightly (ba872f270 2016-11-17)
binary: rustc
commit-hash: ba872f270781ada15426cfac7db20b30b81777dc
commit-date: 2016-11-17
host: x86_64-unknown-linux-gnu
release: 1.15.0-nightly
LLVM version: 3.9
@k4rtik
Copy link
Author

k4rtik commented Nov 19, 2016

This seems to be more common than I first thought:

Made tcp_ctx a 'static

pub fn accept_cmd(tcp_ctx: &'static Arc<RwLock<TCP>>, dl_ctx: &Arc<RwLock<DataLink>>, port: u16) {

resulted in:

error[E0491]: in type `&'static std::sync::Arc<std::sync::RwLock<tcp::TCP<'_>>>`, reference has a longer lifetime than the data it references
   --> src/main.rs:106:1
    |
106 | pub fn accept_cmd(tcp_ctx: &'static Arc<RwLock<TCP>>, dl_ctx: &Arc<RwLock<DataLink>>, port: u16) {
    | ^
    |
    = note: the pointer is valid for the static lifetime
    = note: but the referenced data is only valid for the anonymous lifetime #1 defined on unknown free region bounded by scope CodeExtent(9898/CallSiteScope { fn_id: NodeId(4519), body_id: NodeId(18427) })

@k4rtik
Copy link
Author

k4rtik commented Nov 19, 2016

Issue exists in latest nightly as well.

$ rustc --version --verbose
rustc 1.15.0-nightly (ac635aa95 2016-11-18)
binary: rustc
commit-hash: ac635aa95ba851898e125b047ad7b8d6a8fecf8e
commit-date: 2016-11-18
host: x86_64-unknown-linux-gnu
release: 1.15.0-nightly
LLVM version: 3.9

@nagisa
Copy link
Member

nagisa commented Dec 2, 2016

Can confirm experiencing it.

Smaller sample:

struct RepeatMut<'a, T>(T, &'a ());

impl<'a, T: 'a> Iterator for RepeatMut<'a, T> {
    type Item = &'a mut T;
    fn next(&'a mut self) -> Option<Self::Item> {
        Some(&mut self.0)
    }
}

Not an issue in current stable or beta, which reports

error[E0308]: method not compatible with trait
 --> <anon>:5:5
  |
5 |     fn next(&'a mut self) -> Option<Self::Item> {
  |     ^ lifetime mismatch
  |
  = note: expected type `fn(&mut RepeatMut<'a, T>) -> std::option::Option<&mut T>`
  = note:    found type `fn(&'a mut RepeatMut<'a, T>) -> std::option::Option<&mut T>`
note: the anonymous lifetime #1 defined on the block at 5:48...
 --> <anon>:5:49
  |
5 |     fn next(&'a mut self) -> Option<Self::Item> {
  |                                                 ^
note: ...does not necessarily outlive the lifetime 'a as defined on the block at 5:48
 --> <anon>:5:49
  |
5 |     fn next(&'a mut self) -> Option<Self::Item> {
  |                                                 ^

rather than

error[E0308]: method not compatible with trait
 --> <anon>:5:5
  |
5 |     fn next(&'a mut self) -> Option<Self::Item> {
  |     ^ lifetime mismatch
  |
  = note: expected type `fn(&mut RepeatMut<'a, T>) -> std::option::Option<&mut T>`
  = note:    found type `fn(&'a mut RepeatMut<'a, T>) -> std::option::Option<&mut T>`
  = note: the anonymous lifetime #1 defined on unknown free region bounded by scope CodeExtent(7/CallSiteScope { fn_id: NodeId(28), body_id: NodeId(43) })...
  = note: ...does not necessarily outlive the lifetime 'a as defined on unknown free region bounded by scope CodeExtent(7/CallSiteScope { fn_id: NodeId(28), body_id: NodeId(43) })

@steveklabnik steveklabnik added the A-diagnostics Area: Messages for errors, warnings, and lints label Dec 2, 2016
@steveklabnik
Copy link
Member

Does this qualify as a regression? @rust-lang/core @rust-lang/compiler @rust-lang/lang

@nrc
Copy link
Member

nrc commented Dec 2, 2016

Does this qualify as a regression?

Yes, though not the kind we'd do a point release for, IMO

@nagisa
Copy link
Member

nagisa commented Dec 2, 2016

should mark as such then :)

@niconii
Copy link
Contributor

niconii commented Dec 13, 2016

Here's another small one:

pub struct Foo<'a>(&'a i32);

pub trait Bar {
    fn bar(n: &i32) -> Self;
}

impl<'a> Bar for Foo<'a> {
    fn bar(n: &'a i32) -> Foo<'a> {
        Foo(n)
    }
}
error[E0308]: method not compatible with trait
  --> <anon>:8:5
   |
8  |       fn bar(n: &'a i32) -> Foo<'a> {
   |  _____^ starting here...
9  | |         Foo(n)
10 | |     }
   | |_____^ ...ending here: lifetime mismatch
   |
   = note: expected type `fn(&i32) -> Foo<'a>`
   = note:    found type `fn(&'a i32) -> Foo<'a>`
   = note: the anonymous lifetime #1 defined on unknown free region bounded by scope CodeExtent(15/CallSiteScope { fn_id: NodeId(27), body_id: NodeId(43) })...
   = note: ...does not necessarily outlive the lifetime 'a as defined on unknown free region bounded by scope CodeExtent(15/CallSiteScope { fn_id: NodeId(27), body_id: NodeId(43) })
help: consider using an explicit lifetime parameter as shown: fn bar(n: &'a i32) -> Foo<'a>
  --> <anon>:8:5
   |
8  |       fn bar(n: &'a i32) -> Foo<'a> {
   |  _____^ starting here...
9  | |         Foo(n)
10 | |     }
   | |_____^ ...ending here

@withoutboats
Copy link
Contributor

withoutboats commented Dec 13, 2016

It took me a minute to figure out that this issue is about the error message & not the error. I've also been getting CallSiteScope and so on nonsense in my error output recently. This seems like a pretty serious regression in the usability of our error messages! My impression has been that this impacts just about every lifetime issue I've been getting recently, but I could be wrong.

Could we get this fixed by next stable release? I disagree with @nrc that this isn't worth making a point release for (currently its only in nightly, so that's not an issue).

@aturon aturon added I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 13, 2016
@aturon
Copy link
Member

aturon commented Dec 13, 2016

Nominated for consideration by the compiler team.

@Nemo157
Copy link
Member

Nemo157 commented Dec 22, 2016

This appears to be in beta (testing on the playground). Super tiny repro:

fn test(mut a: &i32, b: &i32) {
    a = b;
}
fn main() {}

gives

rustc 1.15.0-beta.1 (d9a0f0df7 2016-12-19)
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
 --> <anon>:2:9
  |
2 |     a = b;
  |         ^
  |
  = note: ...the reference is valid for the anonymous lifetime #1 defined on unknown free region bounded by scope CodeExtent(4/CallSiteScope { fn_id: NodeId(4), body_id: NodeId(22) })...
  = note: ...but the borrowed content is only valid for the anonymous lifetime #2 defined on unknown free region bounded by scope CodeExtent(4/CallSiteScope { fn_id: NodeId(4), body_id: NodeId(22) })
help: consider using an explicit lifetime parameter as shown: fn test<'a>(mut a: &'a i32, b: &'a i32)
 --> <anon>:1:1
  |
1 |   fn test(mut a: &i32, b: &i32) {
  |  _^ starting here...
2 | |     a = b;
3 | | }
  | |_^ ...ending here

error: aborting due to previous error

@eddyb
Copy link
Member

eddyb commented Dec 22, 2016

Has nobody looked into this? I'll take a peek before the compiler meeting today.

EDIT: Of course it was me who introduced this bug, or rather triggered #27942 sigh.

EDIT2: Basically, after #37412, any uses of NodeBlock are suspicious. I'll try to make a PR.

@eddyb
Copy link
Member

eddyb commented Dec 22, 2016

Fix is at #38552, using @nagisa's reduction as the testcase for this issue.

@nikomatsakis
Copy link
Contributor

triage: P-high

We have a fix though =)

@rust-highfive rust-highfive added P-high High priority and removed I-nominated labels Dec 22, 2016
@brson brson added the regression-from-stable-to-stable Performance or correctness regression from one stable version to another. label Dec 29, 2016
bors added a commit that referenced this issue Jan 4, 2017
Don't leak the compiler's internal representation of scopes in error messages.

Fixes #37884 (actually fixes #27942, which was made worse by #37412) by handling more node types.
Ideally we'd turn the unknown node type situations into ICEs and fix them as they show up in errors.
But we might want to backport this patch so I was less aggressive.
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 P-high High priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. 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.