Skip to content

Commit

Permalink
Address nits in trait suggestions.
Browse files Browse the repository at this point in the history
  • Loading branch information
huonw committed Jan 17, 2015
1 parent 0a55aac commit ada312f
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 57 deletions.
79 changes: 35 additions & 44 deletions src/librustc_typeck/check/method/probe.rs
Expand Up @@ -44,7 +44,6 @@ struct ProbeContext<'a, 'tcx:'a> {
extension_candidates: Vec<Candidate<'tcx>>,
impl_dups: HashSet<ast::DefId>,
static_candidates: Vec<CandidateSource>,
all_traits_search: bool,
}

struct CandidateStep<'tcx> {
Expand Down Expand Up @@ -211,7 +210,6 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
steps: Rc::new(steps),
opt_simplified_steps: opt_simplified_steps,
static_candidates: Vec::new(),
all_traits_search: false,
}
}

Expand Down Expand Up @@ -724,60 +722,53 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
// THE ACTUAL SEARCH

fn pick(mut self) -> PickResult<'tcx> {
let steps = self.steps.clone();

for step in steps.iter() {
match self.pick_step(step) {
Some(r) => {
return r;
}
None => { }
}
match self.pick_core() {
Some(r) => return r,
None => {}
}

let static_candidates = mem::replace(&mut self.static_candidates, vec![]);

let out_of_scope_traits = if !self.all_traits_search {
// things failed, and we haven't yet looked through all
// traits, so lets do that now:
self.reset();
self.all_traits_search = true;

let span = self.span;
let tcx = self.tcx();

self.assemble_extension_candidates_for_all_traits();

match self.pick() {
Ok(p) => vec![p.method_ty.container.id()],
Err(Ambiguity(v)) => v.into_iter().map(|source| {
match source {
TraitSource(id) => id,
ImplSource(impl_id) => {
match ty::trait_id_of_impl(tcx, impl_id) {
Some(id) => id,
None => tcx.sess.span_bug(span,
"found inherent method when looking \
at traits")
}
// things failed, so lets look at all traits, for diagnostic purposes now:
self.reset();

let span = self.span;
let tcx = self.tcx();

self.assemble_extension_candidates_for_all_traits();

let out_of_scope_traits = match self.pick_core() {
Some(Ok(p)) => vec![p.method_ty.container.id()],
Some(Err(Ambiguity(v))) => v.into_iter().map(|source| {
match source {
TraitSource(id) => id,
ImplSource(impl_id) => {
match ty::trait_id_of_impl(tcx, impl_id) {
Some(id) => id,
None =>
tcx.sess.span_bug(span,
"found inherent method when looking at traits")
}
}
}).collect(),
// it'd be really weird for this assertion to trigger,
// given the `vec![]` in the else branch below
Err(NoMatch(_, others)) => {
assert!(others.is_empty());
vec![]
}
}).collect(),
Some(Err(NoMatch(_, others))) => {
assert!(others.is_empty());
vec![]
}
} else {
// we've just looked through all traits and didn't find
// anything at all.
vec![]
None => vec![],
};
;
Err(NoMatch(static_candidates, out_of_scope_traits))
}

fn pick_core(&mut self) -> Option<PickResult<'tcx>> {
let steps = self.steps.clone();

// find the first step that works
steps.iter().filter_map(|step| self.pick_step(step)).next()
}

fn pick_step(&mut self, step: &CandidateStep<'tcx>) -> Option<PickResult<'tcx>> {
debug!("pick_step: step={}", step.repr(self.tcx()));

Expand Down
14 changes: 8 additions & 6 deletions src/librustc_typeck/check/method/suggest.rs
Expand Up @@ -147,16 +147,16 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
candidates.sort();
let msg = format!(
"methods from traits can only be called if the trait is in scope; \
the following {traits_are} implemented and {define} a method `{name}`:",
the following {traits_are} implemented but not in scope, \
perhaps add a `use` for {one_of_them}:",
traits_are = if candidates.len() == 1 {"trait is"} else {"traits are"},
define = if candidates.len() == 1 {"defines"} else {"define"},
name = method_ustring);
one_of_them = if candidates.len() == 1 {"it"} else {"one of them"});

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

for (i, trait_did) in candidates.iter().enumerate() {
fcx.sess().fileline_help(span,
&*format!("candidate #{}: `{}`",
&*format!("candidate #{}: use `{}`",
i + 1,
ty::item_path_str(fcx.tcx(), *trait_did)))

Expand All @@ -174,9 +174,11 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
candidates.sort_by(|a, b| a.cmp(b).reverse());

let msg = format!(
"methods from traits can only be called if the trait is implemented and \
in scope; no such traits are but the following {traits_define} a method `{name}`:",
"methods from traits can only be called if the trait is implemented and in scope; \
the following {traits_define} a method `{name}`, \
perhaps you need to implement {one_of_them}:",
traits_define = if candidates.len() == 1 {"trait defines"} else {"traits define"},
one_of_them = if candidates.len() == 1 {"it"} else {"one of them"},
name = method_ustring);

fcx.sess().fileline_help(span, &msg[]);
Expand Down
14 changes: 7 additions & 7 deletions src/test/compile-fail/no-method-suggested-traits.rs
Expand Up @@ -26,24 +26,24 @@ mod foo {

fn main() {
1u32.method();
//~^ ERROR does not implement
//~^^ HELP the following traits are implemented and define a method `method`
//~^ HELP following traits are implemented but not in scope, perhaps add a `use` for one of them
//~^^ ERROR does not implement
//~^^^ HELP `foo::Bar`
//~^^^^ HELP `no_method_suggested_traits::foo::PubPub`

'a'.method();
//~^ ERROR does not implement
//~^^ HELP the following trait is implemented and defines a method `method`
//~^^ HELP the following trait is implemented but not in scope, perhaps add a `use` for it:
//~^^^ HELP `foo::Bar`

1i32.method();
//~^ ERROR does not implement
//~^^ HELP the following trait is implemented and defines a method `method`
//~^^ HELP the following trait is implemented but not in scope, perhaps add a `use` for it:
//~^^^ HELP `no_method_suggested_traits::foo::PubPub`

1u64.method();
//~^ ERROR does not implement
//~^^ HELP the following traits define a method `method`
//~^^ HELP following traits define a method `method`, perhaps you need to implement one of them
//~^^^ HELP `foo::Bar`
//~^^^^ HELP `no_method_suggested_traits::foo::PubPub`
//~^^^^^ HELP `no_method_suggested_traits::reexport::Reexported`
Expand All @@ -53,10 +53,10 @@ fn main() {

1u64.method2();
//~^ ERROR does not implement
//~^^ HELP the following trait defines a method `method2`
//~^^ HELP the following trait defines a method `method2`, perhaps you need to implement it
//~^^^ HELP `foo::Bar`
1u64.method3();
//~^ ERROR does not implement
//~^^ HELP the following trait defines a method `method3`
//~^^ HELP the following trait defines a method `method3`, perhaps you need to implement it
//~^^^ HELP `no_method_suggested_traits::foo::PubPub`
}

8 comments on commit ada312f

@nikomatsakis
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r+

@bors
Copy link
Contributor

@bors bors commented on ada312f Jan 18, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from nikomatsakis
at huonw@ada312f

@bors
Copy link
Contributor

@bors bors commented on ada312f Jan 18, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging huonw/rust/trait-suggestion-nits = ada312f into auto

@bors
Copy link
Contributor

@bors bors commented on ada312f Jan 18, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

status: {"merge_sha": "30f081e54843952e34b0632e1b0ec54547bf6e3c"}

@bors
Copy link
Contributor

@bors bors commented on ada312f Jan 18, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huonw/rust/trait-suggestion-nits = ada312f merged ok, testing candidate = 30f081e

@bors
Copy link
Contributor

@bors bors commented on ada312f Jan 18, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 30f081e

@bors
Copy link
Contributor

@bors bors commented on ada312f Jan 18, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 30f081e

Please sign in to comment.