Skip to content

Commit c02bb27

Browse files
committed
---
yaml --- r: 217065 b: refs/heads/stable c: b4bbf3a h: refs/heads/master i: 217063: 6bfe552 v: v3
1 parent 13d731d commit c02bb27

35 files changed

+183
-149
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,5 @@ refs/heads/tmp: 378a370ff2057afeb1eae86eb6e78c476866a4a6
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: a5286998df566e736b32f6795bfc3803bdaf453d
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: 4774d5d9a112563b86e8294f6fb76dcee6577d25
32+
refs/heads/stable: b4bbf3a88dd965222c8e06ee113aa3a3730e3739
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375

branches/stable/src/librustc_typeck/check/method/mod.rs

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@ use middle::def;
1616
use middle::privacy::{AllPublic, DependsOn, LastPrivate, LastMod};
1717
use middle::subst;
1818
use middle::traits;
19-
use middle::ty::*;
20-
use middle::ty;
19+
use middle::ty::{self, AsPredicate, ToPolyTraitRef};
2120
use middle::infer;
2221
use util::ppaux::Repr;
2322

24-
use std::rc::Rc;
2523
use syntax::ast::DefId;
2624
use syntax::ast;
2725
use syntax::codemap::Span;
@@ -39,7 +37,7 @@ pub enum MethodError {
3937
// Did not find an applicable method, but we did find various
4038
// static methods that may apply, as well as a list of
4139
// not-in-scope traits which may work.
42-
NoMatch(Vec<CandidateSource>, Vec<ast::DefId>),
40+
NoMatch(Vec<CandidateSource>, Vec<ast::DefId>, probe::Mode),
4341

4442
// Multiple methods might apply.
4543
Ambiguity(Vec<CandidateSource>),
@@ -62,7 +60,7 @@ type ItemIndex = usize; // just for doc purposes
6260
pub fn exists<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
6361
span: Span,
6462
method_name: ast::Name,
65-
self_ty: Ty<'tcx>,
63+
self_ty: ty::Ty<'tcx>,
6664
call_expr_id: ast::NodeId)
6765
-> bool
6866
{
@@ -92,11 +90,11 @@ pub fn exists<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
9290
pub fn lookup<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
9391
span: Span,
9492
method_name: ast::Name,
95-
self_ty: Ty<'tcx>,
96-
supplied_method_types: Vec<Ty<'tcx>>,
93+
self_ty: ty::Ty<'tcx>,
94+
supplied_method_types: Vec<ty::Ty<'tcx>>,
9795
call_expr: &'tcx ast::Expr,
9896
self_expr: &'tcx ast::Expr)
99-
-> Result<MethodCallee<'tcx>, MethodError>
97+
-> Result<ty::MethodCallee<'tcx>, MethodError>
10098
{
10199
debug!("lookup(method_name={}, self_ty={}, call_expr={}, self_expr={})",
102100
method_name.repr(fcx.tcx()),
@@ -115,9 +113,9 @@ pub fn lookup_in_trait<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
115113
self_expr: Option<&ast::Expr>,
116114
m_name: ast::Name,
117115
trait_def_id: DefId,
118-
self_ty: Ty<'tcx>,
119-
opt_input_types: Option<Vec<Ty<'tcx>>>)
120-
-> Option<MethodCallee<'tcx>>
116+
self_ty: ty::Ty<'tcx>,
117+
opt_input_types: Option<Vec<ty::Ty<'tcx>>>)
118+
-> Option<ty::MethodCallee<'tcx>>
121119
{
122120
lookup_in_trait_adjusted(fcx, span, self_expr, m_name, trait_def_id,
123121
0, false, self_ty, opt_input_types)
@@ -139,9 +137,9 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
139137
trait_def_id: DefId,
140138
autoderefs: usize,
141139
unsize: bool,
142-
self_ty: Ty<'tcx>,
143-
opt_input_types: Option<Vec<Ty<'tcx>>>)
144-
-> Option<MethodCallee<'tcx>>
140+
self_ty: ty::Ty<'tcx>,
141+
opt_input_types: Option<Vec<ty::Ty<'tcx>>>)
142+
-> Option<ty::MethodCallee<'tcx>>
145143
{
146144
debug!("lookup_in_trait_adjusted(self_ty={}, self_expr={}, m_name={}, trait_def_id={})",
147145
self_ty.repr(fcx.tcx()),
@@ -186,7 +184,9 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
186184
// Trait must have a method named `m_name` and it should not have
187185
// type parameters or early-bound regions.
188186
let tcx = fcx.tcx();
189-
let (method_num, method_ty) = trait_method(tcx, trait_def_id, m_name).unwrap();
187+
let (method_num, method_ty) = trait_item(tcx, trait_def_id, m_name)
188+
.and_then(|(idx, item)| item.as_opt_method().map(|m| (idx, m)))
189+
.unwrap();
190190
assert_eq!(method_ty.generics.types.len(subst::FnSpace), 0);
191191
assert_eq!(method_ty.generics.regions.len(subst::FnSpace), 0);
192192

@@ -288,10 +288,10 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
288288
}
289289
}
290290

291-
let callee = MethodCallee {
292-
origin: MethodTypeParam(MethodParam{trait_ref: trait_ref.clone(),
293-
method_num: method_num,
294-
impl_def_id: None}),
291+
let callee = ty::MethodCallee {
292+
origin: ty::MethodTypeParam(ty::MethodParam{trait_ref: trait_ref.clone(),
293+
method_num: method_num,
294+
impl_def_id: None}),
295295
ty: fty,
296296
substs: trait_ref.substs.clone()
297297
};
@@ -304,7 +304,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
304304
pub fn resolve_ufcs<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
305305
span: Span,
306306
method_name: ast::Name,
307-
self_ty: Ty<'tcx>,
307+
self_ty: ty::Ty<'tcx>,
308308
expr_id: ast::NodeId)
309309
-> Result<(def::Def, LastPrivate), MethodError>
310310
{
@@ -322,41 +322,40 @@ pub fn resolve_ufcs<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
322322
_ => def::FromTrait(pick.item.container().id())
323323
};
324324
let def_result = match pick.item {
325-
ImplOrTraitItem::MethodTraitItem(..) => def::DefMethod(def_id, provenance),
326-
ImplOrTraitItem::ConstTraitItem(..) => def::DefAssociatedConst(def_id, provenance),
327-
ImplOrTraitItem::TypeTraitItem(..) => {
325+
ty::ImplOrTraitItem::MethodTraitItem(..) => def::DefMethod(def_id, provenance),
326+
ty::ImplOrTraitItem::ConstTraitItem(..) => def::DefAssociatedConst(def_id, provenance),
327+
ty::ImplOrTraitItem::TypeTraitItem(..) => {
328328
fcx.tcx().sess.span_bug(span, "resolve_ufcs: probe picked associated type");
329329
}
330330
};
331331
Ok((def_result, lp))
332332
}
333333

334334

335-
/// Find method with name `method_name` defined in `trait_def_id` and return it, along with its
336-
/// index (or `None`, if no such method).
337-
fn trait_method<'tcx>(tcx: &ty::ctxt<'tcx>,
338-
trait_def_id: ast::DefId,
339-
method_name: ast::Name)
340-
-> Option<(usize, Rc<ty::Method<'tcx>>)>
335+
/// Find item with name `item_name` defined in `trait_def_id` and return it, along with its
336+
/// index (or `None`, if no such item).
337+
fn trait_item<'tcx>(tcx: &ty::ctxt<'tcx>,
338+
trait_def_id: ast::DefId,
339+
item_name: ast::Name)
340+
-> Option<(usize, ty::ImplOrTraitItem<'tcx>)>
341341
{
342342
let trait_items = ty::trait_items(tcx, trait_def_id);
343343
trait_items
344344
.iter()
345345
.enumerate()
346-
.find(|&(_, ref item)| item.name() == method_name)
347-
.and_then(|(idx, item)| item.as_opt_method().map(|m| (idx, m)))
346+
.find(|&(_, ref item)| item.name() == item_name)
347+
.map(|(num, item)| (num, (*item).clone()))
348348
}
349349

350-
fn impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
351-
impl_def_id: ast::DefId,
352-
method_name: ast::Name)
353-
-> Option<Rc<ty::Method<'tcx>>>
350+
fn impl_item<'tcx>(tcx: &ty::ctxt<'tcx>,
351+
impl_def_id: ast::DefId,
352+
item_name: ast::Name)
353+
-> Option<ty::ImplOrTraitItem<'tcx>>
354354
{
355355
let impl_items = tcx.impl_items.borrow();
356356
let impl_items = impl_items.get(&impl_def_id).unwrap();
357357
impl_items
358358
.iter()
359359
.map(|&did| ty::impl_or_trait_item(tcx, did.def_id()))
360-
.find(|m| m.name() == method_name)
361-
.and_then(|item| item.as_opt_method())
360+
.find(|m| m.name() == item_name)
362361
}

branches/stable/src/librustc_typeck/check/method/probe.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ pub fn probe<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
136136
let steps = if mode == Mode::MethodCall {
137137
match create_steps(fcx, span, self_ty) {
138138
Some(steps) => steps,
139-
None => return Err(MethodError::NoMatch(Vec::new(), Vec::new())),
139+
None => return Err(MethodError::NoMatch(Vec::new(), Vec::new(), mode)),
140140
}
141141
} else {
142142
vec![CandidateStep {
@@ -866,7 +866,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
866866
}
867867
}
868868
}).collect(),
869-
Some(Err(MethodError::NoMatch(_, others))) => {
869+
Some(Err(MethodError::NoMatch(_, others, _))) => {
870870
assert!(others.is_empty());
871871
vec![]
872872
}
@@ -877,7 +877,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
877877
None => vec![],
878878
};
879879

880-
Err(MethodError::NoMatch(static_candidates, out_of_scope_traits))
880+
Err(MethodError::NoMatch(static_candidates, out_of_scope_traits, self.mode))
881881
}
882882

883883
fn pick_core(&mut self) -> Option<PickResult<'tcx>> {

branches/stable/src/librustc_typeck/check/method/suggest.rs

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
//! Give useful errors and suggestions to users when a method can't be
11+
//! Give useful errors and suggestions to users when an item can't be
1212
//! found or is otherwise invalid.
1313
1414
use CrateCtxt;
@@ -27,12 +27,13 @@ use syntax::print::pprust;
2727
use std::cell;
2828
use std::cmp::Ordering;
2929

30-
use super::{MethodError, CandidateSource, impl_method, trait_method};
30+
use super::{MethodError, CandidateSource, impl_item, trait_item};
31+
use super::probe::Mode;
3132

3233
pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3334
span: Span,
3435
rcvr_ty: Ty<'tcx>,
35-
method_name: ast::Name,
36+
item_name: ast::Name,
3637
rcvr_expr: Option<&ast::Expr>,
3738
error: MethodError)
3839
{
@@ -42,28 +43,30 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
4243
}
4344

4445
match error {
45-
MethodError::NoMatch(static_sources, out_of_scope_traits) => {
46+
MethodError::NoMatch(static_sources, out_of_scope_traits, mode) => {
4647
let cx = fcx.tcx();
47-
let method_ustring = method_name.user_string(cx);
48+
let item_ustring = item_name.user_string(cx);
4849

4950
fcx.type_error_message(
5051
span,
5152
|actual| {
52-
format!("type `{}` does not implement any \
53-
method in scope named `{}`",
54-
actual,
55-
method_ustring)
53+
format!("no {} named `{}` found for type `{}` \
54+
in the current scope",
55+
if mode == Mode::MethodCall { "method" }
56+
else { "associated item" },
57+
item_ustring,
58+
actual)
5659
},
5760
rcvr_ty,
5861
None);
5962

60-
// If the method has the name of a field, give a help note
63+
// If the item has the name of a field, give a help note
6164
if let (&ty::ty_struct(did, _), Some(_)) = (&rcvr_ty.sty, rcvr_expr) {
6265
let fields = ty::lookup_struct_fields(cx, did);
63-
if fields.iter().any(|f| f.name == method_name) {
66+
if fields.iter().any(|f| f.name == item_name) {
6467
cx.sess.span_note(span,
6568
&format!("use `(s.{0})(...)` if you meant to call the \
66-
function stored in the `{0}` field", method_ustring));
69+
function stored in the `{0}` field", item_ustring));
6770
}
6871
}
6972

@@ -72,25 +75,25 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
7275
span,
7376
"found defined static methods, maybe a `self` is missing?");
7477

75-
report_candidates(fcx, span, method_name, static_sources);
78+
report_candidates(fcx, span, item_name, static_sources);
7679
}
7780

78-
suggest_traits_to_import(fcx, span, rcvr_ty, method_name,
81+
suggest_traits_to_import(fcx, span, rcvr_ty, item_name,
7982
rcvr_expr, out_of_scope_traits)
8083
}
8184

8285
MethodError::Ambiguity(sources) => {
8386
span_err!(fcx.sess(), span, E0034,
84-
"multiple applicable methods in scope");
87+
"multiple applicable items in scope");
8588

86-
report_candidates(fcx, span, method_name, sources);
89+
report_candidates(fcx, span, item_name, sources);
8790
}
8891

8992
MethodError::ClosureAmbiguity(trait_def_id) => {
9093
let msg = format!("the `{}` method from the `{}` trait cannot be explicitly \
9194
invoked on this closure as we have not yet inferred what \
9295
kind of closure it is",
93-
method_name.user_string(fcx.tcx()),
96+
item_name.user_string(fcx.tcx()),
9497
ty::item_path_str(fcx.tcx(), trait_def_id));
9598
let msg = if let Some(callee) = rcvr_expr {
9699
format!("{}; use overloaded call notation instead (e.g., `{}()`)",
@@ -104,19 +107,19 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
104107

105108
fn report_candidates(fcx: &FnCtxt,
106109
span: Span,
107-
method_name: ast::Name,
110+
item_name: ast::Name,
108111
mut sources: Vec<CandidateSource>) {
109112
sources.sort();
110113
sources.dedup();
111114

112115
for (idx, source) in sources.iter().enumerate() {
113116
match *source {
114117
CandidateSource::ImplSource(impl_did) => {
115-
// Provide the best span we can. Use the method, if local to crate, else
116-
// the impl, if local to crate (method may be defaulted), else the call site.
117-
let method = impl_method(fcx.tcx(), impl_did, method_name).unwrap();
118+
// Provide the best span we can. Use the item, if local to crate, else
119+
// the impl, if local to crate (item may be defaulted), else the call site.
120+
let item = impl_item(fcx.tcx(), impl_did, item_name).unwrap();
118121
let impl_span = fcx.tcx().map.def_id_span(impl_did, span);
119-
let method_span = fcx.tcx().map.def_id_span(method.def_id, impl_span);
122+
let item_span = fcx.tcx().map.def_id_span(item.def_id(), impl_span);
120123

121124
let impl_ty = check::impl_self_ty(fcx, span, impl_did).ty;
122125

@@ -127,16 +130,16 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
127130
trait_ref.def_id)),
128131
};
129132

130-
span_note!(fcx.sess(), method_span,
133+
span_note!(fcx.sess(), item_span,
131134
"candidate #{} is defined in an impl{} for the type `{}`",
132135
idx + 1,
133136
insertion,
134137
impl_ty.user_string(fcx.tcx()));
135138
}
136139
CandidateSource::TraitSource(trait_did) => {
137-
let (_, method) = trait_method(fcx.tcx(), trait_did, method_name).unwrap();
138-
let method_span = fcx.tcx().map.def_id_span(method.def_id, span);
139-
span_note!(fcx.sess(), method_span,
140+
let (_, item) = trait_item(fcx.tcx(), trait_did, item_name).unwrap();
141+
let item_span = fcx.tcx().map.def_id_span(item.def_id(), span);
142+
span_note!(fcx.sess(), item_span,
140143
"candidate #{} is defined in the trait `{}`",
141144
idx + 1,
142145
ty::item_path_str(fcx.tcx(), trait_did));
@@ -152,19 +155,19 @@ pub type AllTraitsVec = Vec<TraitInfo>;
152155
fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
153156
span: Span,
154157
rcvr_ty: Ty<'tcx>,
155-
method_name: ast::Name,
158+
item_name: ast::Name,
156159
rcvr_expr: Option<&ast::Expr>,
157160
valid_out_of_scope_traits: Vec<ast::DefId>)
158161
{
159162
let tcx = fcx.tcx();
160-
let method_ustring = method_name.user_string(tcx);
163+
let item_ustring = item_name.user_string(tcx);
161164

162165
if !valid_out_of_scope_traits.is_empty() {
163166
let mut candidates = valid_out_of_scope_traits;
164167
candidates.sort();
165168
candidates.dedup();
166169
let msg = format!(
167-
"methods from traits can only be called if the trait is in scope; \
170+
"items from traits can only be used if the trait is in scope; \
168171
the following {traits_are} implemented but not in scope, \
169172
perhaps add a `use` for {one_of_them}:",
170173
traits_are = if candidates.len() == 1 {"trait is"} else {"traits are"},
@@ -185,7 +188,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
185188
let type_is_local = type_derefs_to_local(fcx, span, rcvr_ty, rcvr_expr);
186189

187190
// there's no implemented traits, so lets suggest some traits to
188-
// implement, by finding ones that have the method name, and are
191+
// implement, by finding ones that have the item name, and are
189192
// legal to implement.
190193
let mut candidates = all_traits(fcx.ccx)
191194
.filter(|info| {
@@ -196,7 +199,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
196199
// implementing a trait would be legal but is rejected
197200
// here).
198201
(type_is_local || ast_util::is_local(info.def_id))
199-
&& trait_method(tcx, info.def_id, method_name).is_some()
202+
&& trait_item(tcx, info.def_id, item_name).is_some()
200203
})
201204
.collect::<Vec<_>>();
202205

@@ -209,12 +212,12 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
209212
// of a type parameter: suggest adding a trait bound rather
210213
// than implementing.
211214
let msg = format!(
212-
"methods from traits can only be called if the trait is implemented and in scope; \
213-
the following {traits_define} a method `{name}`, \
215+
"items from traits can only be used if the trait is implemented and in scope; \
216+
the following {traits_define} an item `{name}`, \
214217
perhaps you need to implement {one_of_them}:",
215218
traits_define = if candidates.len() == 1 {"trait defines"} else {"traits define"},
216219
one_of_them = if candidates.len() == 1 {"it"} else {"one of them"},
217-
name = method_ustring);
220+
name = item_ustring);
218221

219222
fcx.sess().fileline_help(span, &msg[..]);
220223

0 commit comments

Comments
 (0)