Skip to content

Commit 30ab30f

Browse files
[Parser] Check let/var context when fix-it moving attributes from type to decl
1 parent a1dc63e commit 30ab30f

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-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: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,3 +348,18 @@ enum E1 {
348348
}
349349

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

0 commit comments

Comments
 (0)