Skip to content

Commit

Permalink
auto merge of #14265 : Ryman/rust/issue-14254, r=alexcrichton
Browse files Browse the repository at this point in the history
This is hard coding `Box` into this, as it doesn't seem to parse as `TyUniq` like `~` did. This may not be correct for all usages of the box keyword. 

Closes #14254.
  • Loading branch information
bors committed May 20, 2014
2 parents e9018f9 + f9695a6 commit ffe2686
Show file tree
Hide file tree
Showing 3 changed files with 252 additions and 18 deletions.
57 changes: 39 additions & 18 deletions src/librustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4891,6 +4891,25 @@ impl<'a> Resolver<'a> {
}

fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
#[deriving(Eq)]
enum FallbackChecks {
Everything,
OnlyTraitAndStatics
}

fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
-> Option<(Path, NodeId, FallbackChecks)> {
match t.node {
TyPath(ref path, _, node_id) => Some((path.clone(), node_id, allow)),
TyPtr(mut_ty) => extract_path_and_node_id(mut_ty.ty, OnlyTraitAndStatics),
TyRptr(_, mut_ty) => extract_path_and_node_id(mut_ty.ty, allow),
// This doesn't handle the remaining `Ty` variants as they are not
// that commonly the self_type, it might be interesting to provide
// support for those in future.
_ => None,
}
}

fn get_module(this: &mut Resolver, span: Span, ident_path: &[ast::Ident])
-> Option<Rc<Module>> {
let root = this.current_module.clone();
Expand Down Expand Up @@ -4918,27 +4937,29 @@ impl<'a> Resolver<'a> {
}
}

let (path, node_id) = match self.current_self_type {
Some(ref ty) => match ty.node {
TyPath(ref path, _, node_id) => (path.clone(), node_id),
_ => unreachable!(),
let (path, node_id, allowed) = match self.current_self_type {
Some(ref ty) => match extract_path_and_node_id(ty, Everything) {
Some(x) => x,
None => return NoSuggestion,
},
None => return NoSuggestion,
};

// Look for a field with the same name in the current self_type.
match self.def_map.borrow().find(&node_id) {
Some(&DefTy(did))
| Some(&DefStruct(did))
| Some(&DefVariant(_, did, _)) => match self.structs.find(&did) {
None => {}
Some(fields) => {
if fields.iter().any(|&field_name| name == field_name) {
return Field;
if allowed == Everything {
// Look for a field with the same name in the current self_type.
match self.def_map.borrow().find(&node_id) {
Some(&DefTy(did))
| Some(&DefStruct(did))
| Some(&DefVariant(_, did, _)) => match self.structs.find(&did) {
None => {}
Some(fields) => {
if fields.iter().any(|&field_name| name == field_name) {
return Field;
}
}
}
},
_ => {} // Self type didn't resolve properly
},
_ => {} // Self type didn't resolve properly
}
}

let ident_path = path.segments.iter().map(|seg| seg.identifier).collect::<Vec<_>>();
Expand All @@ -4955,8 +4976,8 @@ impl<'a> Resolver<'a> {
FromTrait(_) => unreachable!()
}
}
Some(DefMethod(_, None)) => return Method,
Some(DefMethod(_, _)) => return TraitMethod,
Some(DefMethod(_, None)) if allowed == Everything => return Method,
Some(DefMethod(_, Some(_))) => return TraitMethod,
_ => ()
}
}
Expand Down
113 changes: 113 additions & 0 deletions src/test/compile-fail/issue-14254.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

trait Foo {
fn bar(&self);
fn baz(&self) { }
fn bah(_: Option<Self>) { }
}

struct BarTy {
x : int,
y : f64,
}

impl BarTy {
fn a() {}
fn b(&self) {}
}

impl Foo for *BarTy {
fn bar(&self) {
baz();
//~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
a;
//~^ ERROR: unresolved name `a`. Did you mean to call `BarTy::a`?
}
}

impl<'a> Foo for &'a BarTy {
fn bar(&self) {
baz();
//~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
x;
//~^ ERROR: unresolved name `x`. Did you mean `self.x`?
y;
//~^ ERROR: unresolved name `y`. Did you mean `self.y`?
a;
//~^ ERROR: unresolved name `a`. Did you mean to call `BarTy::a`?
bah;
//~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
b;
//~^ ERROR: unresolved name `b`. Did you mean to call `self.b`?
}
}

impl<'a> Foo for &'a mut BarTy {
fn bar(&self) {
baz();
//~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
x;
//~^ ERROR: unresolved name `x`. Did you mean `self.x`?
y;
//~^ ERROR: unresolved name `y`. Did you mean `self.y`?
a;
//~^ ERROR: unresolved name `a`. Did you mean to call `BarTy::a`?
bah;
//~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
b;
//~^ ERROR: unresolved name `b`. Did you mean to call `self.b`?
}
}

impl Foo for Box<BarTy> {
fn bar(&self) {
baz();
//~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
bah;
//~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
}
}

impl Foo for *int {
fn bar(&self) {
baz();
//~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
bah;
//~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
}
}

impl<'a> Foo for &'a int {
fn bar(&self) {
baz();
//~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
bah;
//~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
}
}

impl<'a> Foo for &'a mut int {
fn bar(&self) {
baz();
//~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
bah;
//~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
}
}

impl Foo for Box<int> {
fn bar(&self) {
baz();
//~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
bah;
//~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
}
}
100 changes: 100 additions & 0 deletions src/test/run-pass/issue-14254.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

trait Foo {
fn bar(&self);
fn baz(&self) { }
fn bah(_: Option<Self>) { }
}

struct BarTy {
x : int,
y : f64,
}

impl BarTy {
fn a() {}
fn b(&self) {}
}

// If these fail, it's necessary to update middle::resolve and the cfail tests.
impl Foo for *BarTy {
fn bar(&self) {
self.baz();
BarTy::a();
Foo::bah(None::<*BarTy>);
}
}

// If these fail, it's necessary to update middle::resolve and the cfail tests.
impl<'a> Foo for &'a BarTy {
fn bar(&self) {
self.baz();
self.x;
self.y;
BarTy::a();
Foo::bah(None::<&BarTy>);
self.b();
}
}

// If these fail, it's necessary to update middle::resolve and the cfail tests.
impl<'a> Foo for &'a mut BarTy {
fn bar(&self) {
self.baz();
self.x;
self.y;
BarTy::a();
Foo::bah(None::<&mut BarTy>);
self.b();
}
}

// If these fail, it's necessary to update middle::resolve and the cfail tests.
impl Foo for Box<BarTy> {
fn bar(&self) {
self.baz();
Foo::bah(None::<Box<BarTy>>);
}
}

// If these fail, it's necessary to update middle::resolve and the cfail tests.
impl Foo for *int {
fn bar(&self) {
self.baz();
Foo::bah(None::<*int>);
}
}

// If these fail, it's necessary to update middle::resolve and the cfail tests.
impl<'a> Foo for &'a int {
fn bar(&self) {
self.baz();
Foo::bah(None::<&int>);
}
}

// If these fail, it's necessary to update middle::resolve and the cfail tests.
impl<'a> Foo for &'a mut int {
fn bar(&self) {
self.baz();
Foo::bah(None::<&mut int>);
}
}

// If these fail, it's necessary to update middle::resolve and the cfail tests.
impl Foo for Box<int> {
fn bar(&self) {
self.baz();
Foo::bah(None::<Box<int>>);
}
}

fn main() {}

0 comments on commit ffe2686

Please sign in to comment.