auto merge of #14086 : Ryman/rust/resolve_error_suggestions, r=alexcrichton

Provides better help for the resolve failures inside an `impl` if the name matches:
- a field on the self type
- a method on the self type
- a method on the current trait ref (in a trait impl)

Not handling trait method suggestions if in a regular `impl` (as you can see on line 69 of the test), I believe it is possible though.

Also, provides a better message when `self` fails to resolve due to being a static method.

It's using some unsafe pointers to skip copying the larger structures (which are only used in error conditions); it's likely possible to get it working with lifetimes (all the useful refs should outlive the visitor calls) but I haven't really figured that out for this case. (can switch to copying code if wanted)

Closes #2356.
This commit is contained in:
bors 2014-05-14 12:06:29 -07:00
commit 2a7a39191a
2 changed files with 324 additions and 115 deletions

View file

@ -8,12 +8,83 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// ignore-test Resolve code for classes knew how to do this, impls don't
trait Groom {
fn shave();
}
struct cat {
tail: int,
pub struct cat {
whiskers: int,
}
pub enum MaybeDog {
Dog,
NoDog
}
impl MaybeDog {
fn bark() {
// If this provides a suggestion, it's a bug as MaybeDog doesn't impl Groom
shave();
//~^ ERROR: unresolved name `shave`.
}
}
impl Groom for cat {
fn shave(&self, other: uint) {
whiskers -= other;
//~^ ERROR: unresolved name `whiskers`. Did you mean `self.whiskers`?
shave(4);
//~^ ERROR: unresolved name `shave`. Did you mean to call `Groom::shave`?
purr();
//~^ ERROR: unresolved name `purr`. Did you mean to call `self.purr`?
}
}
impl cat {
pub fn meow() { tail += 1; } //~ ERROR: Did you mean: `self.tail`
fn static_method() {}
fn purr_louder() {
static_method();
//~^ ERROR: unresolved name `static_method`. Did you mean to call `cat::static_method`
purr();
//~^ ERROR: unresolved name `purr`. Did you mean to call `self.purr`?
purr();
//~^ ERROR: unresolved name `purr`. Did you mean to call `self.purr`?
purr();
//~^ ERROR: unresolved name `purr`. Did you mean to call `self.purr`?
}
}
impl cat {
fn meow() {
if self.whiskers > 3 {
//~^ ERROR: `self` is not available in a static method. Maybe a `self` argument is missing?
println!("MEOW");
}
}
fn purr(&self) {
grow_older();
//~^ ERROR: unresolved name `grow_older`. Did you mean to call `cat::grow_older`
shave();
//~^ ERROR: unresolved name `shave`.
}
fn burn_whiskers(&mut self) {
whiskers = 0;
//~^ ERROR: unresolved name `whiskers`. Did you mean `self.whiskers`?
}
pub fn grow_older(other:uint) {
whiskers = 4;
//~^ ERROR: unresolved name `whiskers`. Did you mean `self.whiskers`?
purr_louder();
//~^ ERROR: unresolved name `purr_louder`. Did you mean to call `cat::purr_louder`
}
}
fn main() {
self += 1;
//~^ ERROR: unresolved name `self`.
// it's a bug if this suggests a missing `self` as we're not in a method
}