about summary refs log tree commit diff
path: root/compiler/rustc_parse
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_parse')
-rw-r--r--compiler/rustc_parse/messages.ftl5
-rw-r--r--compiler/rustc_parse/src/errors.rs14
-rw-r--r--compiler/rustc_parse/src/parser/item.rs36
3 files changed, 54 insertions, 1 deletions
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index aaf1b6c05bf..7970d8d552f 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -869,6 +869,11 @@ parse_trait_alias_cannot_be_auto = trait aliases cannot be `auto`
 parse_trait_alias_cannot_be_const = trait aliases cannot be `const`
 parse_trait_alias_cannot_be_unsafe = trait aliases cannot be `unsafe`
 
+parse_trait_impl_modifier_in_inherent_impl = inherent impls cannot be {$annotation}
+    .because = {$annotation} because of this
+    .type = inherent impl for this type
+    .only_trait = only trait implementations may be annotated with {$annotation}
+
 parse_transpose_dyn_or_impl = `for<...>` expected after `{$kw}`, not before
     .suggestion = move `{$kw}` before the `for<...>`
 
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index ddb2c545c78..2a704ee61ec 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -71,6 +71,20 @@ pub(crate) struct BadQPathStage2 {
     pub wrap: WrapType,
 }
 
+#[derive(Diagnostic)]
+#[diag(parse_trait_impl_modifier_in_inherent_impl)]
+pub(crate) struct TraitImplModifierInInherentImpl<'a> {
+    #[primary_span]
+    pub span: Span,
+    #[label(parse_because)]
+    pub annotation_span: Span,
+    pub annotation: &'a str,
+    #[label(parse_type)]
+    pub self_ty: Span,
+    #[note(parse_only_trait)]
+    pub only_trait: bool,
+}
+
 #[derive(Subdiagnostic)]
 #[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
 pub(crate) struct WrapType {
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 14a90e74049..96d7120e21e 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -665,7 +665,41 @@ impl<'a> Parser<'a> {
 
                 (Some(trait_ref), ty_second)
             }
-            None => (None, ty_first), // impl Type
+            None => {
+                let self_ty = ty_first;
+                let error = |annotation_span, annotation, only_trait| {
+                    errors::TraitImplModifierInInherentImpl {
+                        span: self_ty.span,
+                        annotation_span,
+                        annotation,
+                        self_ty: self_ty.span,
+                        only_trait,
+                    }
+                };
+
+                if let Safety::Unsafe(span) = safety {
+                    self.dcx()
+                        .create_err(errors::TraitImplModifierInInherentImpl {
+                            span: self_ty.span,
+                            annotation_span: span,
+                            annotation: "unsafe",
+                            self_ty: self_ty.span,
+                            only_trait: true,
+                        })
+                        .with_code(E0197)
+                        .emit();
+                }
+                if let ImplPolarity::Negative(span) = polarity {
+                    self.dcx().emit_err(error(span, "negative", false));
+                }
+                if let Defaultness::Default(def_span) = defaultness {
+                    self.dcx().emit_err(error(def_span, "`default`", true));
+                }
+                if let Const::Yes(span) = constness {
+                    self.dcx().emit_err(error(span, "`const`", true));
+                }
+                (None, self_ty)
+            }
         };
         Ok(ItemKind::Impl(Box::new(Impl {
             safety,