diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index b5612c1820d..228f3463058 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -188,6 +188,9 @@ ast_passes_module_nonascii = trying to load file for module `{$name}` with non-a ast_passes_negative_bound_not_supported = negative bounds are not supported +ast_passes_negative_bound_with_parenthetical_notation = + parenthetical notation may not be used for negative bounds + ast_passes_nested_impl_trait = nested `impl Trait` is not allowed .outer = outer `impl Trait` .inner = nested `impl Trait` here diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index bc5cf463f12..cd41e6a99b1 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1257,13 +1257,24 @@ fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) { if let GenericBound::Trait(trait_ref, modifiers) = bound && let BoundPolarity::Negative(_) = modifiers.polarity && let Some(segment) = trait_ref.trait_ref.path.segments.last() - && let Some(ast::GenericArgs::AngleBracketed(args)) = segment.args.as_deref() { - for arg in &args.args { - if let ast::AngleBracketedArg::Constraint(constraint) = arg { - self.dcx() - .emit_err(errors::ConstraintOnNegativeBound { span: constraint.span }); + match segment.args.as_deref() { + Some(ast::GenericArgs::AngleBracketed(args)) => { + for arg in &args.args { + if let ast::AngleBracketedArg::Constraint(constraint) = arg { + self.dcx().emit_err(errors::ConstraintOnNegativeBound { + span: constraint.span, + }); + } + } } + // The lowered form of parenthesized generic args contains a type binding. + Some(ast::GenericArgs::Parenthesized(args)) => { + self.dcx().emit_err(errors::NegativeBoundWithParentheticalNotation { + span: args.span, + }); + } + None => {} } } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 0cec4374be2..c5c6d45a63d 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -745,6 +745,13 @@ pub struct ConstraintOnNegativeBound { pub span: Span, } +#[derive(Diagnostic)] +#[diag(ast_passes_negative_bound_with_parenthetical_notation)] +pub struct NegativeBoundWithParentheticalNotation { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(ast_passes_invalid_unnamed_field_ty)] pub struct InvalidUnnamedFieldTy { diff --git a/tests/ui/traits/negative-bounds/associated-constraints.rs b/tests/ui/traits/negative-bounds/associated-constraints.rs index 23ca2e41f34..4a7132ccde9 100644 --- a/tests/ui/traits/negative-bounds/associated-constraints.rs +++ b/tests/ui/traits/negative-bounds/associated-constraints.rs @@ -16,4 +16,7 @@ fn test3>() {} fn test4() where T: !Trait {} //~^ ERROR associated type constraints not allowed on negative bounds +fn test5() where T: !Fn() -> i32 {} +//~^ ERROR parenthetical notation may not be used for negative bounds + fn main() {} diff --git a/tests/ui/traits/negative-bounds/associated-constraints.stderr b/tests/ui/traits/negative-bounds/associated-constraints.stderr index eae0ba4e6e4..c1a6d2ca6a2 100644 --- a/tests/ui/traits/negative-bounds/associated-constraints.stderr +++ b/tests/ui/traits/negative-bounds/associated-constraints.stderr @@ -22,4 +22,11 @@ error: associated type constraints not allowed on negative bounds LL | fn test4() where T: !Trait {} | ^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: parenthetical notation may not be used for negative bounds + --> $DIR/associated-constraints.rs:19:25 + | +LL | fn test5() where T: !Fn() -> i32 {} + | ^^^^^^^^^^^ + +error: aborting due to 5 previous errors +