diff --git a/src/item.rs b/src/item.rs index a24623edb6..0b7707bf8c 100644 --- a/src/item.rs +++ b/src/item.rs @@ -2593,7 +2593,6 @@ pub(crate) mod parsing { input.parse::()?; } - let begin = input.fork(); let polarity = if input.peek(Token![!]) && !input.peek2(token::Brace) { Some(input.parse::()?) } else { @@ -2631,13 +2630,14 @@ pub(crate) mod parsing { trait_ = None; } self_ty = input.parse()?; + } else if let Some(polarity) = polarity { + return Err(Error::new( + polarity.span, + "inherent impls cannot be negative", + )); } else { trait_ = None; - self_ty = if polarity.is_none() { - first_ty - } else { - Type::Verbatim(verbatim::between(&begin, input)) - }; + self_ty = first_ty; } generics.where_clause = input.parse()?; diff --git a/tests/common/eq.rs b/tests/common/eq.rs index 4fe699b6b5..6df66de677 100644 --- a/tests/common/eq.rs +++ b/tests/common/eq.rs @@ -143,6 +143,7 @@ use rustc_ast::ast::StructRest; use rustc_ast::ast::Term; use rustc_ast::ast::Trait; use rustc_ast::ast::TraitBoundModifiers; +use rustc_ast::ast::TraitImplHeader; use rustc_ast::ast::TraitObjectSyntax; use rustc_ast::ast::TraitRef; use rustc_ast::ast::Ty; @@ -508,7 +509,7 @@ spanless_eq_struct!(FormatOptions; width precision alignment fill sign alternate spanless_eq_struct!(FormatPlaceholder; argument span format_trait format_options); spanless_eq_struct!(GenericParam; id ident attrs bounds is_placeholder kind !colon_span); spanless_eq_struct!(Generics; params where_clause span); -spanless_eq_struct!(Impl; defaultness safety generics constness polarity of_trait self_ty items); +spanless_eq_struct!(Impl; generics of_trait self_ty items); spanless_eq_struct!(InlineAsm; asm_macro template template_strs operands clobber_abis options line_spans); spanless_eq_struct!(InlineAsmSym; id qself path); spanless_eq_struct!(Item; attrs id span vis kind !tokens); @@ -539,6 +540,7 @@ spanless_eq_struct!(StructExpr; qself path fields rest); spanless_eq_struct!(Token; kind span); spanless_eq_struct!(Trait; constness safety is_auto ident generics bounds items); spanless_eq_struct!(TraitBoundModifiers; constness asyncness polarity); +spanless_eq_struct!(TraitImplHeader; defaultness safety constness polarity trait_ref); spanless_eq_struct!(TraitRef; path ref_id); spanless_eq_struct!(Ty; id kind span tokens); spanless_eq_struct!(TyAlias; defaultness ident generics where_clauses bounds ty); diff --git a/tests/repo/mod.rs b/tests/repo/mod.rs index 81b29e2a0c..81573456cd 100644 --- a/tests/repo/mod.rs +++ b/tests/repo/mod.rs @@ -222,7 +222,11 @@ static EXCLUDE_FILES: &[&str] = &[ // Rustc bug: https://github.com/rust-lang/rust/issues/132080 "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0073_safe_declarations_in_extern_blocks.rs", - // Compile-fail expr parameter in const generic position: f::<1 + 2>() + // Negative inherent impl: `impl !Box {}` + "src/tools/rustfmt/tests/source/negative-impl.rs", + "src/tools/rustfmt/tests/target/negative-impl.rs", + + // Compile-fail expr parameter in const generic position: `f::<1 + 2>()` "tests/ui/const-generics/early/closing-args-token.rs", "tests/ui/const-generics/early/const-expression-parameter.rs", diff --git a/tests/test_item.rs b/tests/test_item.rs index 05a316909f..d9a7b5b6b0 100644 --- a/tests/test_item.rs +++ b/tests/test_item.rs @@ -53,8 +53,6 @@ fn test_macro_variable_attr() { #[test] fn test_negative_impl() { - // Rustc parses all of the following. - #[cfg(any())] impl ! {} let tokens = quote! { @@ -67,18 +65,11 @@ fn test_negative_impl() { } "#); - #[cfg(any())] - #[rustfmt::skip] - impl !Trait {} let tokens = quote! { impl !Trait {} }; - snapshot!(tokens as Item, @r#" - Item::Impl { - generics: Generics, - self_ty: Type::Verbatim(`! Trait`), - } - "#); + let err = syn::parse2::(tokens).unwrap_err(); + assert_eq!(err.to_string(), "inherent impls cannot be negative"); #[cfg(any())] impl !Trait for T {} @@ -109,19 +100,6 @@ fn test_negative_impl() { }, } "#); - - #[cfg(any())] - #[rustfmt::skip] - impl !! {} - let tokens = quote! { - impl !! {} - }; - snapshot!(tokens as Item, @r#" - Item::Impl { - generics: Generics, - self_ty: Type::Verbatim(`! !`), - } - "#); } #[test]