Avoid an empty trait name in impl blocks.

`resolve_ident_in_lexical_scope` checks for an empty name. Why is this
necessary? Because `parse_item_impl` can produce an `impl` block with an
empty trait name in some cases. This is pretty gross and very
non-obvious.

This commit avoids the use of the empty trait name. In one case the
trait name is instead pulled from `TyKind::ImplTrait`, which prevents
the output for `tests/ui/impl-trait/extra-impl-in-trait-impl.rs` from
changing. In the other case we just fail the parse and don't try to
recover. I think losing error recovery in this obscure case is worth
the code cleanup.

This change affects `tests/ui/parser/impl-parsing.rs`, which is split in
two, and the obsolete `..` syntax cases are removed (they are tested
elsewhere).
This commit is contained in:
Nicholas Nethercote 2025-04-09 14:16:22 +10:00
parent f419b18d16
commit 7ae5c7f32d
6 changed files with 29 additions and 47 deletions

View file

@ -649,6 +649,7 @@ impl<'a> Parser<'a> {
other => {
if let TyKind::ImplTrait(_, bounds) = other
&& let [bound] = bounds.as_slice()
&& let GenericBound::Trait(poly_trait_ref) = bound
{
// Suggest removing extra `impl` keyword:
// `impl<T: Default> impl Default for Wrapper<T>`
@ -658,12 +659,12 @@ impl<'a> Parser<'a> {
extra_impl_kw,
impl_trait_span: ty_first.span,
});
poly_trait_ref.trait_ref.path.clone()
} else {
self.dcx().emit_err(errors::ExpectedTraitInTraitImplFoundType {
span: ty_first.span,
});
return Err(self.dcx().create_err(
errors::ExpectedTraitInTraitImplFoundType { span: ty_first.span },
));
}
ast::Path::from_ident(Ident::new(kw::Empty, ty_first.span))
}
};
let trait_ref = TraitRef { path, ref_id: ty_first.id };