Skip to content

Commit f21dee2

Browse files
committed
Auto merge of #58929 - estebank:elide-object, r=zackmdavis
Elide object safety errors on non-existent trait function Fix #58734. r? @zackmdavis
2 parents 9f91bee + d7bb98f commit f21dee2

File tree

6 files changed

+74
-21
lines changed

6 files changed

+74
-21
lines changed

src/librustc/session/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ pub struct Session {
164164

165165
/// Cap lint level specified by a driver specifically.
166166
pub driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
167+
168+
/// `Span`s of trait methods that weren't found to avoid emitting object safety errors
169+
pub trait_methods_not_found: OneThread<RefCell<FxHashSet<Span>>>,
167170
}
168171

169172
pub struct PerfStats {
@@ -1230,6 +1233,7 @@ fn build_session_(
12301233
has_global_allocator: Once::new(),
12311234
has_panic_handler: Once::new(),
12321235
driver_lint_caps,
1236+
trait_methods_not_found: OneThread::new(RefCell::new(Default::default())),
12331237
};
12341238

12351239
validate_commandline_args_with_session_available(&sess);

src/librustc/traits/error_reporting.rs

+25-11
Original file line numberDiff line numberDiff line change
@@ -754,9 +754,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
754754
ty::Predicate::ObjectSafe(trait_def_id) => {
755755
let violations = self.tcx.global_tcx()
756756
.object_safety_violations(trait_def_id);
757-
self.tcx.report_object_safety_error(span,
758-
trait_def_id,
759-
violations)
757+
if let Some(err) = self.tcx.report_object_safety_error(
758+
span,
759+
trait_def_id,
760+
violations,
761+
) {
762+
err
763+
} else {
764+
return;
765+
}
760766
}
761767

762768
ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
@@ -884,7 +890,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
884890

885891
TraitNotObjectSafe(did) => {
886892
let violations = self.tcx.global_tcx().object_safety_violations(did);
887-
self.tcx.report_object_safety_error(span, did, violations)
893+
if let Some(err) = self.tcx.report_object_safety_error(span, did, violations) {
894+
err
895+
} else {
896+
return;
897+
}
888898
}
889899

890900
// already reported in the query
@@ -1293,12 +1303,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12931303
err
12941304
}
12951305

1296-
pub fn report_object_safety_error(self,
1297-
span: Span,
1298-
trait_def_id: DefId,
1299-
violations: Vec<ObjectSafetyViolation>)
1300-
-> DiagnosticBuilder<'tcx>
1301-
{
1306+
pub fn report_object_safety_error(
1307+
self,
1308+
span: Span,
1309+
trait_def_id: DefId,
1310+
violations: Vec<ObjectSafetyViolation>,
1311+
) -> Option<DiagnosticBuilder<'tcx>> {
1312+
if self.sess.trait_methods_not_found.borrow().contains(&span) {
1313+
// Avoid emitting error caused by non-existing method (#58734)
1314+
return None;
1315+
}
13021316
let trait_str = self.def_path_str(trait_def_id);
13031317
let span = self.sess.source_map().def_span(span);
13041318
let mut err = struct_span_err!(
@@ -1313,7 +1327,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
13131327
err.note(&violation.error_msg());
13141328
}
13151329
}
1316-
err
1330+
Some(err)
13171331
}
13181332
}
13191333

src/librustc_typeck/astconv.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1012,9 +1012,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
10121012
let object_safety_violations =
10131013
tcx.global_tcx().astconv_object_safety_violations(principal.def_id());
10141014
if !object_safety_violations.is_empty() {
1015-
tcx.report_object_safety_error(
1016-
span, principal.def_id(), object_safety_violations)
1017-
.emit();
1015+
tcx.report_object_safety_error(span, principal.def_id(), object_safety_violations)
1016+
.map(|mut err| err.emit());
10181017
return tcx.types.err;
10191018
}
10201019

src/librustc_typeck/check/method/suggest.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
6060
}
6161
}
6262

63-
pub fn report_method_error<'b>(&self,
64-
span: Span,
65-
rcvr_ty: Ty<'tcx>,
66-
item_name: ast::Ident,
67-
source: SelfSource<'b>,
68-
error: MethodError<'tcx>,
69-
args: Option<&'gcx [hir::Expr]>) {
63+
pub fn report_method_error<'b>(
64+
&self,
65+
span: Span,
66+
rcvr_ty: Ty<'tcx>,
67+
item_name: ast::Ident,
68+
source: SelfSource<'b>,
69+
error: MethodError<'tcx>,
70+
args: Option<&'gcx [hir::Expr]>,
71+
) {
7072
// Avoid suggestions when we don't know what's going on.
7173
if rcvr_ty.references_error() {
7274
return;
@@ -390,6 +392,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
390392
}
391393
} else {
392394
err.span_label(span, format!("{} not found in `{}`", item_kind, ty_str));
395+
self.tcx.sess.trait_methods_not_found.borrow_mut().insert(span);
393396
}
394397

395398
if self.is_fn_ty(&rcvr_ty, span) {

src/test/ui/issues/issue-58734.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
trait Trait {
2+
fn exists(self) -> ();
3+
4+
fn not_object_safe() -> Self;
5+
}
6+
7+
impl Trait for () {
8+
fn exists(self) -> () {
9+
}
10+
11+
fn not_object_safe() -> Self {
12+
()
13+
}
14+
}
15+
16+
fn main() {
17+
// object-safe or not, this call is OK
18+
Trait::exists(());
19+
// no object safety error
20+
Trait::nonexistent(());
21+
//~^ ERROR no function or associated item named `nonexistent` found for type `dyn Trait`
22+
}

src/test/ui/issues/issue-58734.stderr

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0599]: no function or associated item named `nonexistent` found for type `dyn Trait` in the current scope
2+
--> $DIR/issue-58734.rs:20:12
3+
|
4+
LL | Trait::nonexistent(());
5+
| -------^^^^^^^^^^^
6+
| |
7+
| function or associated item not found in `dyn Trait`
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)