Skip to content

Instantly share code, notes, and snippets.

@nikomatsakis
Created March 2, 2017 10:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nikomatsakis/96b8dcc7f44c79104c07c52b8df24918 to your computer and use it in GitHub Desktop.
Save nikomatsakis/96b8dcc7f44c79104c07c52b8df24918 to your computer and use it in GitHub Desktop.
borrowck-challenges.md

non-lexical lifetimes

plan exists to address

nested method calls

vec.push(vec.len()

plan exists

closures always borrow locals, even if you only use a sub-path

fn foo(&mut self) {
    let inc = || self.bar += 1;
    read(self.baz); // ERROR
}

SOLUTION: upvar inference can probably transform that closure so it borrows &mut self.bar instead of &mut self

&mut self or &self methods that only use, or only mutate, a small subset of the state

fn foo(&mut self) {
    let p = self.lookup(22); // I know this only uses `self.map`
    self.set.insert(p.clone()); // ERROR: self already borrowed
}    

OR

fn foo(&mut self) {
    let p = self.lookup();
    self.process(p);
}

fn lookup(&self) -> &Data {
    // uses self.map only
}

fn process(&mut self, p: &Data) {
    // this does not use `self.map`
}

This is much harder. I can imagine some special cases that use interprocedural analysis to figure things out, but other than that we're going to require some fancy annotations. Once you start thinking about trait methods, public APIs, it gets even more fun. Lots of related work here, but feels like a big step up in complexity.

relinquishing borrows

fn foo(&mut self) -> &u32 { ... }

after calling x.foo(), it'd be nice for caller to have a shared borrow on x

T: 'a annotations on structs

struct Foo<'a, T: 'a> { ... }

Solve with a combination of inference and elision. Draft RFC in the works. That particular struct would be:

struct Foo<', T> { ... }

but more generally you'd never have to type T: 'a or 'a: 'b in a struct.

lots and lots of region declarations

fn foo<'a, 'tcx: 'a, 'gcx: 'tcx, ...> { ... }

Personally, I'd like to permit generic modules:

mod tcx<'tcx, 'gcx: 'tcx> { // now all code in here can just refer to 'tcx and 'gcx
    fn foo<'a> { ... }
}

Obviously this requires some sketching out. :P

frustrating interactions around invariance and mutability

This often leads to an explosion in lifetime parameters and weird error messages. Hard to fix given &mut.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment