From 109b785e5dd56ead4c1bfab075af75310a553877 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Sun, 7 May 2023 11:51:50 -0300 Subject: [PATCH] [Parser] Check let/var context when fix-it moving attributes from type to decl --- lib/Parse/ParseDecl.cpp | 13 ++++++++++--- test/attr/attributes.swift | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index c2461392adebc..bdda1e1323a34 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -4034,13 +4034,20 @@ ParserStatus Parser::parseTypeAttribute(TypeAttributes &Attributes, if (justChecking) return makeParserError(); // If this is the first attribute, and if we are on a simple decl, emit a - // fixit to move the attribute. Otherwise, we don't have the location of - // the @ sign, or we don't have confidence that the fixit will be right. + // fixit to move or just remove the attribute. Otherwise, we don't have + // the location of the @ sign, or we don't have confidence that the fixit + // will be right. if (!Attributes.empty() || StructureMarkers.empty() || - StructureMarkers.back().Kind != StructureMarkerKind::Declaration || StructureMarkers.back().Loc.isInvalid() || peekToken().is(tok::equal)) { diagnose(Tok, diag::decl_attribute_applied_to_type); + } else if (InBindingPattern != PatternBindingState::NotInBinding || + StructureMarkers.back().Kind != + StructureMarkerKind::Declaration) { + // In let/var/inout pattern binding declaration context or in non-decl, + // so we can only suggest a remove fix-it. + diagnose(Tok, diag::decl_attribute_applied_to_type) + .fixItRemove(SourceRange(Attributes.AtLoc, Tok.getLoc())); } else { // Otherwise, this is the first type attribute and we know where the // declaration is. Emit the same diagnostic, but include a fixit to diff --git a/test/attr/attributes.swift b/test/attr/attributes.swift index f1082ee83264f..da50239ab74bf 100644 --- a/test/attr/attributes.swift +++ b/test/attr/attributes.swift @@ -348,3 +348,21 @@ enum E1 { } @_custom func testCustomAttribute() {} // expected-error {{unknown attribute '_custom'}} + +// https://github.com/apple/swift/issues/65705 +struct GI65705 {} +struct I65705 { + let m1: @discardableResult () -> Int // expected-error {{attribute can only be applied to declarations, not types}} {{11-30=}} {{none}} + var m2: @discardableResult () -> Int // expected-error {{attribute can only be applied to declarations, not types}} {{11-30=}} {{none}} + let m3: GI65705<@discardableResult () -> Int> // expected-error{{attribute can only be applied to declarations, not types}} {{19-37=}} {{none}} + + func f1(_: inout @discardableResult Int) {} // expected-error {{attribute can only be applied to declarations, not types}} {{20-39=}} {{3-3=@discardableResult }} {{none}} + func f2(_: @discardableResult Int) {} // expected-error {{attribute can only be applied to declarations, not types}} {{14-33=}} {{3-3=@discardableResult }} {{none}} + + func stmt(_ a: Int?) { + if let _: @discardableResult Int = a { // expected-error {{attribute can only be applied to declarations, not types}} {{15-34=}} + } + if var _: @discardableResult Int = a { // expected-error {{attribute can only be applied to declarations, not types}} {{15-34=}} + } + } +}