Skip to content

Commit 2ac5f7d

Browse files
committed
Auto merge of #43737 - GuillaumeGomez:duplicate-method, r=eddyb
Improve error message when duplicate names for type and trait method Fixes #43626.
2 parents 16268a8 + aaa14d1 commit 2ac5f7d

File tree

6 files changed

+69
-14
lines changed

6 files changed

+69
-14
lines changed

src/librustc_typeck/check/method/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,9 @@ pub enum MethodError<'tcx> {
5858
ClosureAmbiguity(// DefId of fn trait
5959
DefId),
6060

61-
// Found an applicable method, but it is not visible.
62-
PrivateMatch(Def),
61+
// Found an applicable method, but it is not visible. The second argument contains a list of
62+
// not-in-scope traits which may work.
63+
PrivateMatch(Def, Vec<DefId>),
6364

6465
// Found a `Self: Sized` bound where `Self` is a trait object, also the caller may have
6566
// forgotten to import a trait.

src/librustc_typeck/check/method/probe.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1013,7 +1013,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
10131013
};
10141014

10151015
if let Some(def) = private_candidate {
1016-
return Err(MethodError::PrivateMatch(def));
1016+
return Err(MethodError::PrivateMatch(def, out_of_scope_traits));
10171017
}
10181018

10191019
Err(MethodError::NoMatch(NoMatchData::new(static_candidates,

src/librustc_typeck/check/method/suggest.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -311,9 +311,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
311311
self.sess().span_err(span, &msg);
312312
}
313313

314-
MethodError::PrivateMatch(def) => {
315-
struct_span_err!(self.tcx.sess, span, E0624,
316-
"{} `{}` is private", def.kind_name(), item_name).emit();
314+
MethodError::PrivateMatch(def, out_of_scope_traits) => {
315+
let mut err = struct_span_err!(self.tcx.sess, span, E0624,
316+
"{} `{}` is private", def.kind_name(), item_name);
317+
self.suggest_valid_traits(&mut err, out_of_scope_traits);
318+
err.emit();
317319
}
318320

319321
MethodError::IllegalSizedBound(candidates) => {
@@ -353,13 +355,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
353355
err.note(&msg[..]);
354356
}
355357

356-
fn suggest_traits_to_import(&self,
357-
err: &mut DiagnosticBuilder,
358-
span: Span,
359-
rcvr_ty: Ty<'tcx>,
360-
item_name: ast::Name,
361-
rcvr_expr: Option<&hir::Expr>,
362-
valid_out_of_scope_traits: Vec<DefId>) {
358+
fn suggest_valid_traits(&self,
359+
err: &mut DiagnosticBuilder,
360+
valid_out_of_scope_traits: Vec<DefId>) -> bool {
363361
if !valid_out_of_scope_traits.is_empty() {
364362
let mut candidates = valid_out_of_scope_traits;
365363
candidates.sort();
@@ -379,6 +377,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
379377
});
380378

381379
self.suggest_use_candidates(err, msg, candidates);
380+
true
381+
} else {
382+
false
383+
}
384+
}
385+
386+
fn suggest_traits_to_import(&self,
387+
err: &mut DiagnosticBuilder,
388+
span: Span,
389+
rcvr_ty: Ty<'tcx>,
390+
item_name: ast::Name,
391+
rcvr_expr: Option<&hir::Expr>,
392+
valid_out_of_scope_traits: Vec<DefId>) {
393+
if self.suggest_valid_traits(err, valid_out_of_scope_traits) {
382394
return;
383395
}
384396

src/librustc_typeck/check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4016,7 +4016,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
40164016
Ok(def) => def,
40174017
Err(error) => {
40184018
let def = match error {
4019-
method::MethodError::PrivateMatch(def) => def,
4019+
method::MethodError::PrivateMatch(def, _) => def,
40204020
_ => Def::Err,
40214021
};
40224022
if item_name != keywords::Invalid.name() {

src/test/ui/trait-method-private.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2017 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+
mod inner {
12+
pub trait Bar {
13+
fn method(&self);
14+
}
15+
16+
pub struct Foo;
17+
18+
impl Foo {
19+
fn method(&self) {}
20+
}
21+
22+
impl Bar for Foo {
23+
fn method(&self) {}
24+
}
25+
}
26+
27+
fn main() {
28+
let foo = inner::Foo;
29+
foo.method();
30+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0624]: method `method` is private
2+
--> $DIR/trait-method-private.rs:29:9
3+
|
4+
29 | foo.method();
5+
| ^^^^^^
6+
|
7+
= help: items from traits can only be used if the trait is in scope
8+
= note: the following trait is implemented but not in scope, perhaps add a `use` for it:
9+
candidate #1: `use inner::Bar;`
10+
11+
error: aborting due to previous error
12+

0 commit comments

Comments
 (0)