auto merge of #14265 : Ryman/rust/issue-14254, r=alexcrichton
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.
This commit is contained in:
commit
ffe2686063
3 changed files with 252 additions and 18 deletions
|
@ -4891,6 +4891,25 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
|
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])
|
fn get_module(this: &mut Resolver, span: Span, ident_path: &[ast::Ident])
|
||||||
-> Option<Rc<Module>> {
|
-> Option<Rc<Module>> {
|
||||||
let root = this.current_module.clone();
|
let root = this.current_module.clone();
|
||||||
|
@ -4918,27 +4937,29 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (path, node_id) = match self.current_self_type {
|
let (path, node_id, allowed) = match self.current_self_type {
|
||||||
Some(ref ty) => match ty.node {
|
Some(ref ty) => match extract_path_and_node_id(ty, Everything) {
|
||||||
TyPath(ref path, _, node_id) => (path.clone(), node_id),
|
Some(x) => x,
|
||||||
_ => unreachable!(),
|
None => return NoSuggestion,
|
||||||
},
|
},
|
||||||
None => return NoSuggestion,
|
None => return NoSuggestion,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Look for a field with the same name in the current self_type.
|
if allowed == Everything {
|
||||||
match self.def_map.borrow().find(&node_id) {
|
// Look for a field with the same name in the current self_type.
|
||||||
Some(&DefTy(did))
|
match self.def_map.borrow().find(&node_id) {
|
||||||
| Some(&DefStruct(did))
|
Some(&DefTy(did))
|
||||||
| Some(&DefVariant(_, did, _)) => match self.structs.find(&did) {
|
| Some(&DefStruct(did))
|
||||||
None => {}
|
| Some(&DefVariant(_, did, _)) => match self.structs.find(&did) {
|
||||||
Some(fields) => {
|
None => {}
|
||||||
if fields.iter().any(|&field_name| name == field_name) {
|
Some(fields) => {
|
||||||
return Field;
|
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<_>>();
|
let ident_path = path.segments.iter().map(|seg| seg.identifier).collect::<Vec<_>>();
|
||||||
|
@ -4955,8 +4976,8 @@ impl<'a> Resolver<'a> {
|
||||||
FromTrait(_) => unreachable!()
|
FromTrait(_) => unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(DefMethod(_, None)) => return Method,
|
Some(DefMethod(_, None)) if allowed == Everything => return Method,
|
||||||
Some(DefMethod(_, _)) => return TraitMethod,
|
Some(DefMethod(_, Some(_))) => return TraitMethod,
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
113
src/test/compile-fail/issue-14254.rs
Normal file
113
src/test/compile-fail/issue-14254.rs
Normal file
|
@ -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
src/test/run-pass/issue-14254.rs
Normal file
100
src/test/run-pass/issue-14254.rs
Normal file
|
@ -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() {}
|
Loading…
Add table
Add a link
Reference in a new issue