From 3b5a8cdd4457b00664d45954630fd4ff0a18327b Mon Sep 17 00:00:00 2001 From: Trent Nadeau Date: Sat, 26 Mar 2016 22:24:22 +0000 Subject: [PATCH] Added @discardableResult attribute parsing. Future commits will add use in diagnostic generation, stdlib, etc. --- include/swift/AST/Attr.def | 3 +++ include/swift/AST/PrintOptions.h | 1 + lib/Sema/TypeCheckAttr.cpp | 2 ++ lib/Sema/TypeCheckDecl.cpp | 1 + test/IDE/complete_decl_attribute.swift | 6 ++++-- test/IDE/print_ast_tc_decls.swift | 13 +++++++++++++ test/attr/attr_discardableResult.swift | 17 +++++++++++++++++ 7 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 test/attr/attr_discardableResult.swift diff --git a/include/swift/AST/Attr.def b/include/swift/AST/Attr.def index 2e07908891c98..70c3e15aead0e 100644 --- a/include/swift/AST/Attr.def +++ b/include/swift/AST/Attr.def @@ -260,6 +260,9 @@ SIMPLE_DECL_ATTR(_versioned, Versioned, LongAttribute | UserInaccessible, 64) +SIMPLE_DECL_ATTR(discardableResult, DiscardableResult, + OnFunc | OnConstructor | LongAttribute, 65) + #undef TYPE_ATTR #undef DECL_ATTR_ALIAS #undef SIMPLE_DECL_ATTR diff --git a/include/swift/AST/PrintOptions.h b/include/swift/AST/PrintOptions.h index d87e36a20f38b..0f656bce142ea 100644 --- a/include/swift/AST/PrintOptions.h +++ b/include/swift/AST/PrintOptions.h @@ -332,6 +332,7 @@ struct PrintOptions { result.SkipUnderscoredStdlibProtocols = true; result.SkipDeinit = true; result.ExcludeAttrList.push_back(DAK_WarnUnusedResult); + result.ExcludeAttrList.push_back(DAK_DiscardableResult); result.EmptyLineBetweenMembers = true; result.ElevateDocCommentFromConformance = true; return result; diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index 5d0849dc66d88..bc96283d524e1 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -82,6 +82,7 @@ class AttributeEarlyChecker : public AttributeVisitor { IGNORED_ATTR(Versioned) IGNORED_ATTR(WarnUnusedResult) IGNORED_ATTR(ShowInInterface) + IGNORED_ATTR(DiscardableResult) #undef IGNORED_ATTR void visitAlignmentAttr(AlignmentAttr *attr) { @@ -653,6 +654,7 @@ class AttributeChecker : public AttributeVisitor { IGNORED_ATTR(Testable) IGNORED_ATTR(WarnUnqualifiedAccess) IGNORED_ATTR(ShowInInterface) + IGNORED_ATTR(DiscardableResult) // FIXME: We actually do have things to enforce for versioned API. IGNORED_ATTR(Versioned) diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index 3cfd7b9c7638d..d8c60a5c20c40 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -5108,6 +5108,7 @@ class DeclChecker : public DeclVisitor { UNINTERESTING_ATTR(WarnUnusedResult) UNINTERESTING_ATTR(WarnUnqualifiedAccess) + UNINTERESTING_ATTR(DiscardableResult) #undef UNINTERESTING_ATTR diff --git a/test/IDE/complete_decl_attribute.swift b/test/IDE/complete_decl_attribute.swift index ecd9f4942603b..48652678d8908 100644 --- a/test/IDE/complete_decl_attribute.swift +++ b/test/IDE/complete_decl_attribute.swift @@ -43,7 +43,7 @@ func method(@#^KEYWORD1^#) {} @#^KEYWORD2^# func method(){} -// KEYWORD2: Begin completions, 10 items +// KEYWORD2: Begin completions, 11 items // KEYWORD2-NEXT: Keyword/None: available[#Func Attribute#]; name=available{{$}} // KEYWORD2-NEXT: Keyword/None: objc[#Func Attribute#]; name=objc{{$}} // KEYWORD2-NEXT: Keyword/None: swift3_migration[#Func Attribute#]; name=swift3_migration{{$}} @@ -54,6 +54,7 @@ func method(){} // KEYWORD2-NEXT: Keyword/None: nonobjc[#Func Attribute#]; name=nonobjc{{$}} // KEYWORD2-NEXT: Keyword/None: warn_unused_result[#Func Attribute#]; name=warn_unused_result{{$}} // KEYWORD2-NEXT: Keyword/None: warn_unqualified_access[#Func Attribute#]; name=warn_unqualified_access{{$}} +// KEYWORD2-NEXT: Keyword/None: discardableResult[#Func Attribute#]; name=discardableResult // KEYWORD2-NEXT: End completions @#^KEYWORD3^# @@ -89,7 +90,7 @@ struct S{} @#^KEYWORD_LAST^# -// KEYWORD_LAST: Begin completions, 20 items +// KEYWORD_LAST: Begin completions, 21 items // KEYWORD_LAST-NEXT: Keyword/None: available[#Declaration Attribute#]; name=available{{$}} // KEYWORD_LAST-NEXT: Keyword/None: objc[#Declaration Attribute#]; name=objc{{$}} // KEYWORD_LAST-NEXT: Keyword/None: swift3_migration[#Declaration Attribute#]; name=swift3_migration{{$}} @@ -110,4 +111,5 @@ struct S{} // KEYWORD_LAST-NEXT: Keyword/None: objc_non_lazy_realization[#Declaration Attribute#]; name=objc_non_lazy_realization{{$}} // KEYWORD_LAST-NEXT: Keyword/None: warn_unused_result[#Declaration Attribute#]; name=warn_unused_result // KEYWORD_LAST-NEXT: Keyword/None: warn_unqualified_access[#Declaration Attribute#]; name=warn_unqualified_access +// KEYWORD_LAST-NEXT: Keyword/None: discardableResult[#Declaration Attribute#]; name=discardableResult // KEYWORD_LAST-NEXT: End completions diff --git a/test/IDE/print_ast_tc_decls.swift b/test/IDE/print_ast_tc_decls.swift index 28dd7156d16f3..087b65423e07b 100644 --- a/test/IDE/print_ast_tc_decls.swift +++ b/test/IDE/print_ast_tc_decls.swift @@ -1311,6 +1311,19 @@ public struct ArrayThingy { public func mineCopper() -> Int { return 0 } } +// @discardableResult attribute +public struct DiscardableThingy { + // PASS_PRINT_AST: @discardableResult + // PASS_PRINT_AST-NEXT: public init() + @discardableResult + public init() {} + + // PASS_PRINT_AST: @discardableResult + // PASS_PRINT_AST-NEXT: public func useless() -> Int + @discardableResult + public func useless() -> Int { return 0 } +} + // Parameter Attributes. diff --git a/test/attr/attr_discardableResult.swift b/test/attr/attr_discardableResult.swift new file mode 100644 index 0000000000000..e04aa11dbb314 --- /dev/null +++ b/test/attr/attr_discardableResult.swift @@ -0,0 +1,17 @@ +// RUN: %target-parse-verify-swift + +// --------------------------------------------------------------------------- +// Mark function's return value as discardable and silence warning +// --------------------------------------------------------------------------- +@discardableResult func f1() -> [Int] { } + +class C1 { + @discardableResult init() { } + + @discardableResult + func f1() -> Int { } +} + +struct Inits1 { + @discardableResult init() { } +}