Skip to content

Commit 2407256

Browse files
Merge pull request #65748 from LucianoPAlmeida/parse-attr-fix-it
[Parser] Check let/var context when fix-it moving attributes from type to decl
2 parents 8db4b9f + 109b785 commit 2407256

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4034,13 +4034,20 @@ ParserStatus Parser::parseTypeAttribute(TypeAttributes &Attributes,
40344034
if (justChecking) return makeParserError();
40354035

40364036
// If this is the first attribute, and if we are on a simple decl, emit a
4037-
// fixit to move the attribute. Otherwise, we don't have the location of
4038-
// the @ sign, or we don't have confidence that the fixit will be right.
4037+
// fixit to move or just remove the attribute. Otherwise, we don't have
4038+
// the location of the @ sign, or we don't have confidence that the fixit
4039+
// will be right.
40394040
if (!Attributes.empty() || StructureMarkers.empty() ||
4040-
StructureMarkers.back().Kind != StructureMarkerKind::Declaration ||
40414041
StructureMarkers.back().Loc.isInvalid() ||
40424042
peekToken().is(tok::equal)) {
40434043
diagnose(Tok, diag::decl_attribute_applied_to_type);
4044+
} else if (InBindingPattern != PatternBindingState::NotInBinding ||
4045+
StructureMarkers.back().Kind !=
4046+
StructureMarkerKind::Declaration) {
4047+
// In let/var/inout pattern binding declaration context or in non-decl,
4048+
// so we can only suggest a remove fix-it.
4049+
diagnose(Tok, diag::decl_attribute_applied_to_type)
4050+
.fixItRemove(SourceRange(Attributes.AtLoc, Tok.getLoc()));
40444051
} else {
40454052
// Otherwise, this is the first type attribute and we know where the
40464053
// declaration is. Emit the same diagnostic, but include a fixit to

test/attr/attributes.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,3 +348,21 @@ enum E1 {
348348
}
349349

350350
@_custom func testCustomAttribute() {} // expected-error {{unknown attribute '_custom'}}
351+
352+
// https://github.com/apple/swift/issues/65705
353+
struct GI65705<A> {}
354+
struct I65705 {
355+
let m1: @discardableResult () -> Int // expected-error {{attribute can only be applied to declarations, not types}} {{11-30=}} {{none}}
356+
var m2: @discardableResult () -> Int // expected-error {{attribute can only be applied to declarations, not types}} {{11-30=}} {{none}}
357+
let m3: GI65705<@discardableResult () -> Int> // expected-error{{attribute can only be applied to declarations, not types}} {{19-37=}} {{none}}
358+
359+
func f1(_: inout @discardableResult Int) {} // expected-error {{attribute can only be applied to declarations, not types}} {{20-39=}} {{3-3=@discardableResult }} {{none}}
360+
func f2(_: @discardableResult Int) {} // expected-error {{attribute can only be applied to declarations, not types}} {{14-33=}} {{3-3=@discardableResult }} {{none}}
361+
362+
func stmt(_ a: Int?) {
363+
if let _: @discardableResult Int = a { // expected-error {{attribute can only be applied to declarations, not types}} {{15-34=}}
364+
}
365+
if var _: @discardableResult Int = a { // expected-error {{attribute can only be applied to declarations, not types}} {{15-34=}}
366+
}
367+
}
368+
}

0 commit comments

Comments
 (0)