Skip to content

Commit aec9eeb

Browse files
committed
Do not produce incorrect dyn Trait suggestion in fn
``` error[E0782]: trait objects must include the `dyn` keyword --> $DIR/not-on-bare-trait-2021.rs:8:12 | LL | fn foo(_x: Foo + Send) { | ^^^^^^^^^^ | help: use a new generic type parameter, constrained by `Foo + Send` | LL | fn foo<T: Foo + Send>(_x: T) { | +++++++++++++++ ~ help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference | LL | fn foo(_x: impl Foo + Send) { | ++++ help: alternatively, use a trait object to accept any type that implements `Foo + Send`, accessing its methods at runtime using dynamic dispatch | LL | fn foo(_x: &(dyn Foo + Send)) { | +++++ + - help: add `dyn` keyword before this trait - | - LL | fn foo(_x: dyn Foo + Send) { - | +++ ```
1 parent f116d4d commit aec9eeb

File tree

2 files changed

+9
-37
lines changed

2 files changed

+9
-37
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
6969
let mut diag =
7070
rustc_errors::struct_span_code_err!(tcx.dcx(), self_ty.span, E0782, "{}", msg);
7171
if self_ty.span.can_be_used_for_suggestions() {
72-
self.maybe_suggest_impl_trait(self_ty, &mut diag);
73-
if object_safe {
72+
if !self.maybe_suggest_impl_trait(self_ty, &mut diag) && object_safe {
7473
// Only emit this suggestion if the trait is object safe.
7574
diag.multipart_suggestion_verbose(
7675
label,
@@ -212,34 +211,25 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
212211
let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id;
213212
// FIXME: If `type_alias_impl_trait` is enabled, also look for `Trait0<Ty = Trait1>`
214213
// and suggest `Trait0<Ty = impl Trait1>`.
215-
let (sig, generics, owner) = match tcx.hir_node_by_def_id(parent_id) {
214+
let (sig, generics) = match tcx.hir_node_by_def_id(parent_id) {
216215
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, generics, _), .. }) => {
217-
(sig, generics, None)
216+
(sig, generics)
218217
}
219218
hir::Node::TraitItem(hir::TraitItem {
220219
kind: hir::TraitItemKind::Fn(sig, _),
221220
generics,
222-
owner_id,
223221
..
224-
}) => (sig, generics, Some(tcx.parent(owner_id.to_def_id()))),
222+
}) => (sig, generics),
225223
_ => return false,
226224
};
227225
let Ok(trait_name) = tcx.sess.source_map().span_to_snippet(self_ty.span) else {
228226
return false;
229227
};
230228
let impl_sugg = vec![(self_ty.span.shrink_to_lo(), "impl ".to_string())];
231-
let mut is_downgradable = true;
232-
let mut downgrade = false;
233229
let is_object_safe = match self_ty.kind {
234230
hir::TyKind::TraitObject(objects, ..) => {
235231
objects.iter().all(|o| match o.trait_ref.path.res {
236-
Res::Def(DefKind::Trait, id) => {
237-
if Some(id) == owner {
238-
// For recursive traits, don't downgrade the error. (#119652)
239-
is_downgradable = false;
240-
}
241-
tcx.object_safety_violations(id).is_empty()
242-
}
232+
Res::Def(DefKind::Trait, id) => tcx.object_safety_violations(id).is_empty(),
243233
_ => false,
244234
})
245235
}
@@ -267,11 +257,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
267257
],
268258
Applicability::MachineApplicable,
269259
);
270-
} else if is_downgradable {
271-
// We'll emit the object safety error already, with a structured suggestion.
272-
downgrade = true;
260+
return true;
273261
}
274-
return downgrade;
262+
return false;
275263
}
276264
for ty in sig.decl.inputs {
277265
if ty.hir_id != self_ty.hir_id {
@@ -293,10 +281,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
293281
}
294282
if !is_object_safe {
295283
diag.note(format!("`{trait_name}` it is not object safe, so it can't be `dyn`"));
296-
if is_downgradable {
297-
// We'll emit the object safety error already, with a structured suggestion.
298-
downgrade = true;
299-
}
300284
} else {
301285
let sugg = if let hir::TyKind::TraitObject([_, _, ..], _, _) = self_ty.kind {
302286
// There are more than one trait bound, we need surrounding parentheses.
@@ -316,9 +300,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
316300
Applicability::MachineApplicable,
317301
);
318302
}
319-
return downgrade;
303+
return true;
320304
}
321-
downgrade
305+
false
322306
}
323307

324308
fn maybe_suggest_assoc_ty_bound(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) {

tests/ui/traits/bound/not-on-bare-trait-2021.stderr

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ help: alternatively, use a trait object to accept any type that implements `Foo
1616
|
1717
LL | fn foo(_x: &(dyn Foo + Send)) {
1818
| +++++ +
19-
help: add `dyn` keyword before this trait
20-
|
21-
LL | fn foo(_x: dyn Foo + Send) {
22-
| +++
2319

2420
error[E0782]: trait objects must include the `dyn` keyword
2521
--> $DIR/not-on-bare-trait-2021.rs:11:11
@@ -39,10 +35,6 @@ help: alternatively, use a trait object to accept any type that implements `Foo`
3935
|
4036
LL | fn bar(x: &dyn Foo) -> Foo {
4137
| ++++
42-
help: add `dyn` keyword before this trait
43-
|
44-
LL | fn bar(x: dyn Foo) -> Foo {
45-
| +++
4638

4739
error[E0782]: trait objects must include the `dyn` keyword
4840
--> $DIR/not-on-bare-trait-2021.rs:11:19
@@ -58,10 +50,6 @@ help: alternatively, you can return an owned trait object
5850
|
5951
LL | fn bar(x: Foo) -> Box<dyn Foo> {
6052
| +++++++ +
61-
help: add `dyn` keyword before this trait
62-
|
63-
LL | fn bar(x: Foo) -> dyn Foo {
64-
| +++
6553

6654
error: aborting due to 3 previous errors
6755

0 commit comments

Comments
 (0)