Skip to content

Commit ffe2686

Browse files
committed
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.
2 parents e9018f9 + f9695a6 commit ffe2686

File tree

3 files changed

+252
-18
lines changed

3 files changed

+252
-18
lines changed

src/librustc/middle/resolve.rs

+39-18
Original file line numberDiff line numberDiff line change
@@ -4891,6 +4891,25 @@ impl<'a> Resolver<'a> {
48914891
}
48924892

48934893
fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
4894+
#[deriving(Eq)]
4895+
enum FallbackChecks {
4896+
Everything,
4897+
OnlyTraitAndStatics
4898+
}
4899+
4900+
fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
4901+
-> Option<(Path, NodeId, FallbackChecks)> {
4902+
match t.node {
4903+
TyPath(ref path, _, node_id) => Some((path.clone(), node_id, allow)),
4904+
TyPtr(mut_ty) => extract_path_and_node_id(mut_ty.ty, OnlyTraitAndStatics),
4905+
TyRptr(_, mut_ty) => extract_path_and_node_id(mut_ty.ty, allow),
4906+
// This doesn't handle the remaining `Ty` variants as they are not
4907+
// that commonly the self_type, it might be interesting to provide
4908+
// support for those in future.
4909+
_ => None,
4910+
}
4911+
}
4912+
48944913
fn get_module(this: &mut Resolver, span: Span, ident_path: &[ast::Ident])
48954914
-> Option<Rc<Module>> {
48964915
let root = this.current_module.clone();
@@ -4918,27 +4937,29 @@ impl<'a> Resolver<'a> {
49184937
}
49194938
}
49204939

4921-
let (path, node_id) = match self.current_self_type {
4922-
Some(ref ty) => match ty.node {
4923-
TyPath(ref path, _, node_id) => (path.clone(), node_id),
4924-
_ => unreachable!(),
4940+
let (path, node_id, allowed) = match self.current_self_type {
4941+
Some(ref ty) => match extract_path_and_node_id(ty, Everything) {
4942+
Some(x) => x,
4943+
None => return NoSuggestion,
49254944
},
49264945
None => return NoSuggestion,
49274946
};
49284947

4929-
// Look for a field with the same name in the current self_type.
4930-
match self.def_map.borrow().find(&node_id) {
4931-
Some(&DefTy(did))
4932-
| Some(&DefStruct(did))
4933-
| Some(&DefVariant(_, did, _)) => match self.structs.find(&did) {
4934-
None => {}
4935-
Some(fields) => {
4936-
if fields.iter().any(|&field_name| name == field_name) {
4937-
return Field;
4948+
if allowed == Everything {
4949+
// Look for a field with the same name in the current self_type.
4950+
match self.def_map.borrow().find(&node_id) {
4951+
Some(&DefTy(did))
4952+
| Some(&DefStruct(did))
4953+
| Some(&DefVariant(_, did, _)) => match self.structs.find(&did) {
4954+
None => {}
4955+
Some(fields) => {
4956+
if fields.iter().any(|&field_name| name == field_name) {
4957+
return Field;
4958+
}
49384959
}
4939-
}
4940-
},
4941-
_ => {} // Self type didn't resolve properly
4960+
},
4961+
_ => {} // Self type didn't resolve properly
4962+
}
49424963
}
49434964

49444965
let ident_path = path.segments.iter().map(|seg| seg.identifier).collect::<Vec<_>>();
@@ -4955,8 +4976,8 @@ impl<'a> Resolver<'a> {
49554976
FromTrait(_) => unreachable!()
49564977
}
49574978
}
4958-
Some(DefMethod(_, None)) => return Method,
4959-
Some(DefMethod(_, _)) => return TraitMethod,
4979+
Some(DefMethod(_, None)) if allowed == Everything => return Method,
4980+
Some(DefMethod(_, Some(_))) => return TraitMethod,
49604981
_ => ()
49614982
}
49624983
}

src/test/compile-fail/issue-14254.rs

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
trait Foo {
12+
fn bar(&self);
13+
fn baz(&self) { }
14+
fn bah(_: Option<Self>) { }
15+
}
16+
17+
struct BarTy {
18+
x : int,
19+
y : f64,
20+
}
21+
22+
impl BarTy {
23+
fn a() {}
24+
fn b(&self) {}
25+
}
26+
27+
impl Foo for *BarTy {
28+
fn bar(&self) {
29+
baz();
30+
//~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
31+
a;
32+
//~^ ERROR: unresolved name `a`. Did you mean to call `BarTy::a`?
33+
}
34+
}
35+
36+
impl<'a> Foo for &'a BarTy {
37+
fn bar(&self) {
38+
baz();
39+
//~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
40+
x;
41+
//~^ ERROR: unresolved name `x`. Did you mean `self.x`?
42+
y;
43+
//~^ ERROR: unresolved name `y`. Did you mean `self.y`?
44+
a;
45+
//~^ ERROR: unresolved name `a`. Did you mean to call `BarTy::a`?
46+
bah;
47+
//~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
48+
b;
49+
//~^ ERROR: unresolved name `b`. Did you mean to call `self.b`?
50+
}
51+
}
52+
53+
impl<'a> Foo for &'a mut BarTy {
54+
fn bar(&self) {
55+
baz();
56+
//~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
57+
x;
58+
//~^ ERROR: unresolved name `x`. Did you mean `self.x`?
59+
y;
60+
//~^ ERROR: unresolved name `y`. Did you mean `self.y`?
61+
a;
62+
//~^ ERROR: unresolved name `a`. Did you mean to call `BarTy::a`?
63+
bah;
64+
//~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
65+
b;
66+
//~^ ERROR: unresolved name `b`. Did you mean to call `self.b`?
67+
}
68+
}
69+
70+
impl Foo for Box<BarTy> {
71+
fn bar(&self) {
72+
baz();
73+
//~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
74+
bah;
75+
//~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
76+
}
77+
}
78+
79+
impl Foo for *int {
80+
fn bar(&self) {
81+
baz();
82+
//~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
83+
bah;
84+
//~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
85+
}
86+
}
87+
88+
impl<'a> Foo for &'a int {
89+
fn bar(&self) {
90+
baz();
91+
//~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
92+
bah;
93+
//~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
94+
}
95+
}
96+
97+
impl<'a> Foo for &'a mut int {
98+
fn bar(&self) {
99+
baz();
100+
//~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
101+
bah;
102+
//~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
103+
}
104+
}
105+
106+
impl Foo for Box<int> {
107+
fn bar(&self) {
108+
baz();
109+
//~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
110+
bah;
111+
//~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
112+
}
113+
}

src/test/run-pass/issue-14254.rs

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
trait Foo {
12+
fn bar(&self);
13+
fn baz(&self) { }
14+
fn bah(_: Option<Self>) { }
15+
}
16+
17+
struct BarTy {
18+
x : int,
19+
y : f64,
20+
}
21+
22+
impl BarTy {
23+
fn a() {}
24+
fn b(&self) {}
25+
}
26+
27+
// If these fail, it's necessary to update middle::resolve and the cfail tests.
28+
impl Foo for *BarTy {
29+
fn bar(&self) {
30+
self.baz();
31+
BarTy::a();
32+
Foo::bah(None::<*BarTy>);
33+
}
34+
}
35+
36+
// If these fail, it's necessary to update middle::resolve and the cfail tests.
37+
impl<'a> Foo for &'a BarTy {
38+
fn bar(&self) {
39+
self.baz();
40+
self.x;
41+
self.y;
42+
BarTy::a();
43+
Foo::bah(None::<&BarTy>);
44+
self.b();
45+
}
46+
}
47+
48+
// If these fail, it's necessary to update middle::resolve and the cfail tests.
49+
impl<'a> Foo for &'a mut BarTy {
50+
fn bar(&self) {
51+
self.baz();
52+
self.x;
53+
self.y;
54+
BarTy::a();
55+
Foo::bah(None::<&mut BarTy>);
56+
self.b();
57+
}
58+
}
59+
60+
// If these fail, it's necessary to update middle::resolve and the cfail tests.
61+
impl Foo for Box<BarTy> {
62+
fn bar(&self) {
63+
self.baz();
64+
Foo::bah(None::<Box<BarTy>>);
65+
}
66+
}
67+
68+
// If these fail, it's necessary to update middle::resolve and the cfail tests.
69+
impl Foo for *int {
70+
fn bar(&self) {
71+
self.baz();
72+
Foo::bah(None::<*int>);
73+
}
74+
}
75+
76+
// If these fail, it's necessary to update middle::resolve and the cfail tests.
77+
impl<'a> Foo for &'a int {
78+
fn bar(&self) {
79+
self.baz();
80+
Foo::bah(None::<&int>);
81+
}
82+
}
83+
84+
// If these fail, it's necessary to update middle::resolve and the cfail tests.
85+
impl<'a> Foo for &'a mut int {
86+
fn bar(&self) {
87+
self.baz();
88+
Foo::bah(None::<&mut int>);
89+
}
90+
}
91+
92+
// If these fail, it's necessary to update middle::resolve and the cfail tests.
93+
impl Foo for Box<int> {
94+
fn bar(&self) {
95+
self.baz();
96+
Foo::bah(None::<Box<int>>);
97+
}
98+
}
99+
100+
fn main() {}

0 commit comments

Comments
 (0)