1
Fork 0

Account for impl Trait { when impl Trait for Type { was intended

On editions where bare traits are never allowed, detect if the user has
written `impl Trait` with no type, silence any dyn-compatibility errors,
and provide a structured suggestion for the potentially missing type:

```
error[E0782]: trait objects must include the `dyn` keyword
  --> $DIR/missing-for-type-in-impl.rs:8:6
   |
LL | impl Foo<i64> {
   |      ^^^^^^^^
   |
help: add `dyn` keyword before this trait
   |
LL | impl dyn Foo<i64> {
   |      +++
help: you might have intended to implement this trait for a given type
   |
LL | impl Foo<i64> for /* Type */ {
   |               ++++++++++++++
```
This commit is contained in:
Esteban Küber 2024-10-04 22:59:03 +00:00
parent 14f303bc14
commit e057c43382
5 changed files with 158 additions and 8 deletions

View file

@ -1,6 +1,7 @@
use core::ops::ControlFlow;
use std::borrow::Cow;
use rustc_ast::TraitObjectSyntax;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::unord::UnordSet;
use rustc_errors::codes::*;
@ -573,7 +574,26 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
ty::PredicateKind::DynCompatible(trait_def_id) => {
let violations = self.tcx.dyn_compatibility_violations(trait_def_id);
report_dyn_incompatibility(self.tcx, span, None, trait_def_id, violations)
let mut err = report_dyn_incompatibility(
self.tcx,
span,
None,
trait_def_id,
violations,
);
if let hir::Node::Item(item) =
self.tcx.hir_node_by_def_id(obligation.cause.body_id)
&& let hir::ItemKind::Impl(impl_) = item.kind
&& let None = impl_.of_trait
&& let hir::TyKind::TraitObject(_, _, syntax) = impl_.self_ty.kind
&& let TraitObjectSyntax::None = syntax
&& impl_.self_ty.span.edition().at_least_rust_2021()
{
// Silence the dyn-compatibility error in favor of the missing dyn on
// self type error. #131051.
err.downgrade_to_delayed_bug();
}
err
}
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty)) => {