diff --git a/benchmark/scripts/Benchmark_Driver b/benchmark/scripts/Benchmark_Driver index 708e3d6ffdd0d..388e262cdae25 100755 --- a/benchmark/scripts/Benchmark_Driver +++ b/benchmark/scripts/Benchmark_Driver @@ -73,7 +73,25 @@ class BenchmarkDriver(object): def test_harness(self): """Full path to test harness binary.""" suffix = self.args.optimization if hasattr(self.args, "optimization") else "O" - return os.path.join(self.args.tests, "Benchmark_" + suffix) + if hasattr(self.args, "architecture") and self.args.architecture: + suffix += "-" + self.args.architecture + "*" + pattern = os.path.join(self.args.tests, "Benchmark_" + suffix) + executables = [] + if hasattr(self._subprocess, "test_mode") and self._subprocess.test_mode: + executables = [pattern] + else: + executables = glob.glob(pattern) + if len(executables) == 0: + raise ValueError( + "No benchmark executable for file name pattern " + + pattern + " found") + if len(executables) > 1: + raise ValueError( + "Multiple benchmark executables for file name pattern " + + pattern + " found\n" + + str(executables) + + "\nSpecify the architecture to select the right benchmark executable") + return executables[0] def _git(self, cmd): """Execute the Git command in the `swift-repo`.""" diff --git a/benchmark/scripts/run_smoke_bench b/benchmark/scripts/run_smoke_bench index 03e518d344d02..a09c59d003e5b 100755 --- a/benchmark/scripts/run_smoke_bench +++ b/benchmark/scripts/run_smoke_bench @@ -48,12 +48,13 @@ VERBOSE = False class DriverArgs(object): """Arguments for BenchmarkDriver.""" - def __init__(self, tests, optimization="O"): + def __init__(self, tests, optimization="O", architecture=None): """Initialize with path to the build-dir and optimization level.""" self.benchmarks = None self.filters = None self.tests = os.path.join(tests, "bin") self.optimization = optimization + self.architecture = architecture def log(msg): @@ -126,6 +127,12 @@ def main(): help="The number of re-runs until it's assumed to be a real change", default=8, ) + argparser.add_argument( + "-arch", + type=str, + help="The architecture. The default is x86_64", + default="x86_64", + ) argparser.add_argument( "-platform", type=str, help="The benchmark build platform", default="macosx" ) @@ -158,6 +165,7 @@ def test_opt_levels(args): args.num_samples, args.num_reruns, output_file, + args.arch ): changes = True @@ -167,6 +175,7 @@ def test_opt_levels(args): opt_level, args.oldbuilddir[0], args.newbuilddir[0], + args.arch, args.platform, output_file, ): @@ -177,6 +186,7 @@ def test_opt_levels(args): "swiftlibs", args.oldbuilddir[0], args.newbuilddir[0], + args.arch, args.platform, output_file, ): @@ -221,7 +231,8 @@ def merge(results, other_results): def test_performance( - opt_level, old_dir, new_dir, threshold, num_samples, num_reruns, output_file + opt_level, old_dir, new_dir, threshold, num_samples, num_reruns, + output_file, arch ): """Detect performance changes in benchmarks. @@ -231,7 +242,7 @@ def test_performance( i, unchanged_length_count = 0, 0 old, new = [ - BenchmarkDriver(DriverArgs(dir, optimization=opt_level)) + BenchmarkDriver(DriverArgs(dir, optimization=opt_level, architecture=arch)) for dir in [old_dir, new_dir] ] results = [measure(driver, driver.tests, i) for driver in [old, new]] @@ -260,12 +271,13 @@ def test_performance( ) -def report_code_size(opt_level, old_dir, new_dir, platform, output_file): +def report_code_size(opt_level, old_dir, new_dir, architecture, platform, output_file): if opt_level == "swiftlibs": files = glob.glob(os.path.join(old_dir, "lib", "swift", platform, "*.dylib")) else: files = glob.glob( - os.path.join(old_dir, opt_level + "-*" + platform + "*", "*.o") + os.path.join(old_dir, opt_level + "-" + architecture + "*" + + platform + "*", "*.o") ) idx = 1 @@ -370,8 +382,8 @@ performance team (@eeckstein). def check_added(args, output_file=None): - old = BenchmarkDriver(DriverArgs(args.oldbuilddir[0])) - new = BenchmarkDriver(DriverArgs(args.newbuilddir[0])) + old = BenchmarkDriver(DriverArgs(args.oldbuilddir[0], architecture=args.arch)) + new = BenchmarkDriver(DriverArgs(args.newbuilddir[0], architecture=args.arch)) added = set(new.tests).difference(set(old.tests)) new.tests = list(added) doctor = BenchmarkDoctor(args, driver=new) diff --git a/benchmark/scripts/test_Benchmark_Driver.py b/benchmark/scripts/test_Benchmark_Driver.py index 62d93d7f93cc1..7690aacf31bac 100644 --- a/benchmark/scripts/test_Benchmark_Driver.py +++ b/benchmark/scripts/test_Benchmark_Driver.py @@ -198,6 +198,9 @@ def record_and_respond(self, args, stdin, stdout, stderr, shell): self.calls.append(args) return self.respond.get(args, "") + def test_mode(): + return True + class TestBenchmarkDriverInitialization(unittest.TestCase): def setUp(self): @@ -206,13 +209,19 @@ def setUp(self): def test_test_harness(self): self.assertEqual( - BenchmarkDriver(self.args, tests=["ignored"]).test_harness, + BenchmarkDriver( + self.args, + tests=["ignored"], + _subprocess=self.subprocess_mock).test_harness, "/benchmarks/Benchmark_O", ) self.args.tests = "/path" self.args.optimization = "Suffix" self.assertEqual( - BenchmarkDriver(self.args, tests=["ignored"]).test_harness, + BenchmarkDriver( + self.args, + tests=["ignored"], + _subprocess=self.subprocess_mock).test_harness, "/path/Benchmark_Suffix", ) @@ -271,6 +280,7 @@ def test_log_file(self): swift_repo=None, ), tests=["ignored"], + _subprocess=self.subprocess_mock ) self.assertEqual(driver.log_file, "/path/Benchmark_Suffix-" + now + ".log") diff --git a/include/swift/AST/diagnostics/en.yaml b/include/swift/AST/diagnostics/en.yaml index 561ed57dfff71..952fb8b16f9d5 100644 --- a/include/swift/AST/diagnostics/en.yaml +++ b/include/swift/AST/diagnostics/en.yaml @@ -12,8 +12,11798 @@ # # This file defines the diagnostic messages for the English language. # Each diagnostic is described in the following format: -# - id: "" -# msg: "" -# +# - id: +# msg: >- +# +# #===----------------------------------------------------------------------===# +- id: invalid_diagnostic + msg: >- + INTERNAL ERROR: this diagnostic should not be produced + +- id: not_implemented + msg: >- + INTERNAL ERROR: feature not implemented: %0 + +- id: error_opening_output + msg: >- + error opening '%0' for output: %1 + +- id: cannot_find_group_info_file + msg: >- + cannot find group info file at path: '%0' + +- id: cannot_parse_group_info_file + msg: >- + cannot parse group info file at path: '%0' + +- id: error_no_group_info + msg: >- + no group info found for file: '%0' + +- id: previous_decldef + msg: >- + previous definition of %0 is here + +- id: brace_stmt_suggest_do + msg: >- + did you mean to use a 'do' statement? + +- id: while_parsing_as_left_angle_bracket + msg: >- + while parsing this '<' as a type parameter bracket + +- id: remark_max_determinism_overriding + msg: >- + SWIFTC_MAXIMUM_DETERMINISM overriding %0 + +- id: super_not_in_class_method + msg: >- + 'super' cannot be used outside of class members + +- id: class_func_not_in_class + msg: >- + class methods are only allowed within classes; use 'static' to declare a + %select{static|requirement fulfilled by either a static or class}0 method + +- id: class_var_not_in_class + msg: >- + class properties are only allowed within classes; use 'static' to declare + a %select{static|requirement fulfilled by either a static or class}0 + property + +- id: class_subscript_not_in_class + msg: >- + class subscripts are only allowed within classes; use 'static' to declare + a %select{static|requirement fulfilled by either a static or class}0 + subscript + +- id: func_decl_without_brace + msg: >- + expected '{' in body of function declaration + +- id: convert_let_to_var + msg: >- + change 'let' to 'var' to make it mutable + +- id: note_typo_candidate + msg: >- + did you mean '%0'? + +- id: profile_read_error + msg: >- + failed to load profile data '%0': '%1' + +- id: protocol_extension_redundant_requirement + msg: >- + requirement of '%1' to '%2' is redundant in an extension of '%0' + +- id: attr_only_on_parameters + msg: >- + '%0' may only be used on parameters + +- id: function_type_no_parens + msg: >- + single argument function types require parentheses + +- id: error_underlying_module_not_found + msg: >- + underlying Objective-C module %0 not found + +- id: generic_signature_not_minimal + msg: >- + generic requirement '%0' is redundant in %1 + +- id: generic_signature_not_valid + msg: >- + generic signature %0 is invalid + +- id: generic_signature_not_equal + msg: >- + generic signature %0 is not equal to new signature %1 + +- id: sdk_node_unrecognized_key + msg: >- + unrecognized key '%0' in SDK node + +- id: sdk_node_unrecognized_node_kind + msg: >- + unrecognized SDK node kind '%0' + +- id: sdk_node_unrecognized_type_attr_kind + msg: >- + unrecognized type attribute '%0' in SDK node + +- id: sdk_node_unrecognized_decl_attr_kind + msg: >- + unrecognized declaration attribute '%0' in SDK node + +- id: sdk_node_unrecognized_decl_kind + msg: >- + unrecognized declaration kind '%0' in SDK node + +- id: sdk_node_unrecognized_accessor_kind + msg: >- + unrecognized accessor kind '%0' in SDK node + +- id: pound_source_location_creates_pound_file_conflicts + msg: >- + '#sourceLocation' directive produces '#file' string of '%0', which + conflicts with '#file' strings produced by other paths in the module + +- id: fixit_correct_source_location_file + msg: >- + change file in '#sourceLocation' to '%0' + +- id: circular_reference + msg: >- + circular reference + +- id: circular_reference_through + msg: >- + through reference here + +- id: circular_class_inheritance + msg: >- + %0 inherits from itself + +- id: circular_enum_inheritance + msg: >- + %0 has a raw type that depends on itself + +- id: circular_protocol_def + msg: >- + protocol %0 refines itself + +- id: kind_declname_declared_here + msg: >- + %0 %1 declared here + +- id: warn_property_wrapper_module_scope + msg: >- + ignoring associated type %0 in favor of module-scoped property wrapper + %0; please qualify the reference with %1 + +- id: circular_type_resolution_note + msg: >- + while resolving type %0 + +- id: cannot_load_swiftoverlay_file + msg: >- + cannot load cross-import overlay for '%0' and '%1': %2 (declared by '%3') + +- id: cannot_list_swiftcrossimport_dir + msg: >- + cannot list cross-import overlays for '%0': %1 (declared in '%2') + +- id: cross_imported_by_both_modules + msg: >- + modules %0 and %1 both declare module %2 as a cross-import overlay, which + may cause paradoxical behavior when looking up names in them; please report this + bug to the maintainers of these modules + +- id: opening_brace + msg: >- + to match this opening '{' + +- id: opening_bracket + msg: >- + to match this opening '[' + +- id: opening_paren + msg: >- + to match this opening '(' + +- id: opening_angle + msg: >- + to match this opening '<' + +- id: extra_rbrace + msg: >- + extraneous '}' at top level + +- id: structure_overflow + msg: >- + structure nesting level exceeded maximum of %0 + +- id: expected_close_to_if_directive + msg: >- + expected #else or #endif at end of conditional compilation block + +- id: expected_close_after_else_directive + msg: >- + further conditions after #else are unreachable + +- id: unexpected_conditional_compilation_block_terminator + msg: >- + unexpected conditional compilation block terminator + +- id: incomplete_conditional_compilation_directive + msg: >- + incomplete condition in conditional compilation directive + +- id: extra_tokens_conditional_compilation_directive + msg: >- + extra tokens following conditional compilation directive + +- id: unexpected_rbrace_in_conditional_compilation_block + msg: >- + unexpected '}' in conditional compilation block + +- id: unexpected_if_following_else_compilation_directive + msg: >- + unexpected 'if' keyword following '#else' conditional compilation + directive; did you mean '#elseif'? + +- id: pound_diagnostic_expected_string + msg: >- + expected string literal in %select{#warning|#error}0 directive + +- id: pound_diagnostic_expected + msg: >- + expected '%0' in %select{#warning|#error}1 directive + +- id: pound_diagnostic_expected_parens + msg: >- + %select{#warning|#error}0 directive requires parentheses + +- id: pound_diagnostic_interpolation + msg: >- + string interpolation is not allowed in %select{#warning|#error}0 + directives + +- id: extra_tokens_pound_diagnostic_directive + msg: >- + extra tokens following %select{#warning|#error}0 directive + +- id: sourceLocation_expected + msg: >- + expected '%0' in #sourceLocation directive + +- id: unexpected_line_directive + msg: >- + parameterless closing #sourceLocation() directive without prior opening + #sourceLocation(file:,line:) directive + +- id: expected_line_directive_number + msg: >- + expected starting line number for #sourceLocation directive + +- id: expected_line_directive_name + msg: >- + expected filename string literal for #sourceLocation directive + +- id: extra_tokens_line_directive + msg: >- + extra tokens at the end of #sourceLocation directive + +- id: line_directive_line_zero + msg: >- + the line number needs to be greater than zero + +- id: escaped_parameter_name + msg: >- + keyword '%0' does not need to be escaped in argument list + +- id: forbidden_interpolated_string + msg: >- + %0 cannot be an interpolated string literal + +- id: forbidden_extended_escaping_string + msg: >- + %0 cannot be an extended escaping string literal + +- id: lex_nul_character + msg: >- + nul character embedded in middle of file + +- id: lex_utf16_bom_marker + msg: >- + input files must be encoded as UTF-8 instead of UTF-16 + +- id: lex_hashbang_not_allowed + msg: >- + hashbang line is allowed only in the main file + +- id: lex_unprintable_ascii_character + msg: >- + unprintable ASCII character found in source file + +- id: lex_invalid_utf8 + msg: >- + invalid UTF-8 found in source file + +- id: lex_single_quote_string + msg: >- + single-quoted string literal found, use '"' + +- id: lex_invalid_curly_quote + msg: >- + unicode curly quote found, replace with '"' + +- id: lex_confusable_character + msg: >- + unicode character '%0' looks similar to '%1'; did you mean to use '%1'? + +- id: lex_nonbreaking_space + msg: >- + non-breaking space (U+00A0) used instead of regular space + +- id: lex_unterminated_block_comment + msg: >- + unterminated '/*' comment + +- id: lex_comment_start + msg: >- + comment started here + +- id: lex_unterminated_string + msg: >- + unterminated string literal + +- id: lex_invalid_escape + msg: >- + invalid escape sequence in literal + +- id: lex_invalid_u_escape + msg: >- + \u{...} escape sequence expects between 1 and 8 hex digits + +- id: lex_invalid_u_escape_rbrace + msg: >- + expected '}' in \u{...} escape sequence + +- id: lex_invalid_escape_delimiter + msg: >- + too many '#' characters in delimited escape + +- id: lex_invalid_closing_delimiter + msg: >- + too many '#' characters in closing delimiter + +- id: lex_invalid_unicode_scalar + msg: >- + invalid unicode scalar + +- id: lex_unicode_escape_braces + msg: >- + expected hexadecimal code in braces after unicode escape + +- id: lex_illegal_multiline_string_start + msg: >- + multi-line string literal content must begin on a new line + +- id: lex_illegal_multiline_string_end + msg: >- + multi-line string literal closing delimiter must begin on a new line + +- id: lex_multiline_string_indent_inconsistent + msg: >- + %select{unexpected space in|unexpected tab in|insufficient}2 indentation + of %select{line|next %1 lines}0 in multi-line string literal + +- id: lex_multiline_string_indent_should_match_here + msg: >- + should match %select{space|tab}0 here + +- id: lex_multiline_string_indent_change_line + msg: >- + change indentation of %select{this line|these lines}0 to match closing + delimiter + +- id: lex_escaped_newline_at_lastline + msg: >- + escaped newline at the last line is not allowed + +- id: lex_invalid_character + msg: >- + invalid character in source file + +- id: lex_invalid_identifier_start_character + msg: >- + an identifier cannot begin with this character + +- id: lex_expected_digit_in_fp_exponent + msg: >- + expected a digit in floating point exponent + +- id: lex_invalid_digit_in_fp_exponent + msg: >- + '%0' is not a valid %select{digit|first character}1 in floating point + exponent + +- id: lex_invalid_digit_in_int_literal + msg: >- + '%0' is not a valid %select{binary digit (0 or 1)|octal digit + (0-7)|digit|hexadecimal digit (0-9, A-F)}1 in integer literal + +- id: lex_expected_binary_exponent_in_hex_float_literal + msg: >- + hexadecimal floating point literal must end with an exponent + +- id: lex_unexpected_block_comment_end + msg: >- + unexpected end of block comment + +- id: lex_unary_equal + msg: >- + '=' must have consistent whitespace on both sides + +- id: extra_whitespace_period + msg: >- + extraneous whitespace after '.' is not permitted + +- id: lex_editor_placeholder + msg: >- + editor placeholder in source file + +- id: lex_editor_placeholder_in_playground + msg: >- + editor placeholder in source file + +- id: lex_conflict_marker_in_file + msg: >- + source control conflict marker in source file + +- id: note_in_decl_extension + msg: >- + in %select{declaration|extension}0 of %1 + +- id: line_directive_style_deprecated + msg: >- + #line directive was renamed to #sourceLocation + +- id: declaration_same_line_without_semi + msg: >- + consecutive declarations on a line must be separated by ';' + +- id: expected_decl + msg: >- + expected declaration + +- id: expected_identifier_in_decl + msg: >- + expected identifier in %0 declaration + +- id: expected_keyword_in_decl + msg: >- + expected '%0' keyword in %1 declaration + +- id: number_cant_start_decl_name + msg: >- + %0 name can only start with a letter or underscore, not a number + +- id: expected_identifier_after_case_comma + msg: >- + expected identifier after comma in enum 'case' declaration + +- id: decl_redefinition + msg: >- + definition conflicts with previous value + +- id: let_cannot_be_computed_property + msg: >- + 'let' declarations cannot be computed properties + +- id: let_cannot_be_observing_property + msg: >- + 'let' declarations cannot be observing properties + +- id: let_cannot_be_addressed_property + msg: >- + 'let' declarations cannot have addressors + +- id: disallowed_var_multiple_getset + msg: >- + 'var' declarations with multiple variables cannot have explicit + getters/setters + +- id: disallowed_init + msg: >- + initial value is not allowed here + +- id: var_init_self_referential + msg: >- + variable used within its own initial value + +- id: disallowed_enum_element + msg: >- + enum 'case' is not allowed outside of an enum + +- id: decl_inner_scope + msg: >- + declaration is only valid at file scope + +- id: decl_not_static + msg: >- + declaration cannot be marked %0 + +- id: cskeyword_not_attribute + msg: >- + '%0' is a declaration modifier, not an attribute + +- id: decl_already_static + msg: >- + %0 cannot appear after another 'static' or 'class' keyword + +- id: enum_case_dot_prefix + msg: >- + extraneous '.' in enum 'case' declaration + +- id: static_var_decl_global_scope + msg: >- + %select{%error|static properties|class properties}0 may only be declared + on a type + +- id: computed_property_no_accessors + msg: >- + %select{computed property|subscript}0 must have accessors specified + +- id: expected_getset_in_protocol + msg: >- + expected get or set in a protocol property + +- id: computed_property_missing_type + msg: >- + computed property must have an explicit type + +- id: getset_nontrivial_pattern + msg: >- + getter/setter can only be defined for a single variable + +- id: expected_rbrace_in_getset + msg: >- + expected '}' at end of variable get/set clause + +- id: duplicate_accessor + msg: >- + %select{variable|subscript}0 already has %1 + +- id: conflicting_accessor + msg: >- + %select{variable|subscript}0 cannot provide both %1 and %2 + +- id: previous_accessor + msg: >- + %select{|previous definition of }1%0 %select{defined |}1here + +- id: expected_accessor_parameter_name + msg: >- + expected %select{setter|willSet|didSet}0 parameter name + +- id: expected_rparen_set_name + msg: >- + expected ')' after setter parameter name + +- id: expected_rparen_willSet_name + msg: >- + expected ')' after willSet parameter name + +- id: expected_rparen_didSet_name + msg: >- + expected ')' after didSet parameter name + +- id: expected_lbrace_accessor + msg: >- + expected '{' to start %0 definition + +- id: expected_accessor_kw + msg: >- + expected 'get', 'set', 'willSet', or 'didSet' keyword to start an + accessor definition + +- id: missing_getter + msg: >- + %select{variable|subscript}0 with %1 must also have a getter + +- id: missing_reading_accessor + msg: >- + %select{variable|subscript}0 with %1 must also have a getter, addressor, + or 'read' accessor + +- id: observing_accessor_conflicts_with_accessor + msg: >- + %select{'willSet'|'didSet'}0 cannot be provided together with %1 + +- id: observing_accessor_in_subscript + msg: >- + %select{'willSet'|'didSet'}0 is not allowed in subscripts + +- id: getset_cannot_be_implied + msg: >- + variable with implied type cannot have implied getter/setter + +- id: decl_expected_module_name + msg: >- + expected module name in import declaration + +- id: expected_lbrace_extension + msg: >- + expected '{' in extension + +- id: expected_rbrace_extension + msg: >- + expected '}' at end of extension + +- id: extension_type_expected + msg: >- + expected type name in extension declaration + +- id: expected_equal_in_typealias + msg: >- + expected '=' in type alias declaration + +- id: expected_type_in_typealias + msg: >- + expected type in type alias declaration + +- id: expected_type_in_associatedtype + msg: >- + expected type in associated type declaration + +- id: associated_type_generic_parameter_list + msg: >- + associated types must not have a generic parameter list + +- id: func_decl_without_paren + msg: >- + expected '(' in argument list of function declaration + +- id: static_func_decl_global_scope + msg: >- + %select{%error|static methods|class methods}0 may only be declared on a + type + +- id: func_decl_expected_arrow + msg: >- + expected '->' after function parameter tuple + +- id: operator_static_in_protocol + msg: >- + operator '%0' declared in protocol must be 'static' + +- id: expected_lbrace_enum + msg: >- + expected '{' in enum + +- id: expected_rbrace_enum + msg: >- + expected '}' at end of enum + +- id: expected_lbrace_struct + msg: >- + expected '{' in struct + +- id: expected_rbrace_struct + msg: >- + expected '}' in struct + +- id: expected_lbrace_class + msg: >- + expected '{' in class + +- id: expected_rbrace_class + msg: >- + expected '}' in class + +- id: expected_colon_class + msg: >- + expected ':' to begin inheritance clause + +- id: generic_arguments_protocol + msg: >- + protocols do not allow generic parameters; use associated types instead + +- id: expected_lbrace_protocol + msg: >- + expected '{' in protocol type + +- id: expected_rbrace_protocol + msg: >- + expected '}' in protocol + +- id: protocol_setter_name + msg: >- + setter in a protocol cannot have a name + +- id: protocol_method_with_body + msg: >- + protocol methods must not have bodies + +- id: protocol_init_with_body + msg: >- + protocol initializers must not have bodies + +- id: subscript_decl_wrong_scope + msg: >- + 'subscript' functions may only be declared within a type + +- id: expected_lparen_subscript + msg: >- + expected '(' for subscript parameters + +- id: subscript_has_name + msg: >- + subscripts cannot have a name + +- id: expected_arrow_subscript + msg: >- + expected '->' for subscript element type + +- id: expected_type_subscript + msg: >- + expected subscripting element type + +- id: expected_lbrace_subscript + msg: >- + expected '{' in subscript to specify getter and setter implementation + +- id: expected_lbrace_subscript_protocol + msg: >- + subscript in protocol must have explicit { get } or { get set } specifier + +- id: subscript_without_get + msg: >- + subscript declarations must have a getter + +- id: invalid_nested_init + msg: >- + missing '%select{super.|self.}0' at initializer invocation + +- id: initializer_decl_wrong_scope + msg: >- + initializers may only be declared within a type + +- id: expected_lparen_initializer + msg: >- + expected '(' for initializer parameters + +- id: initializer_has_name + msg: >- + initializers cannot have a name + +- id: destructor_decl_outside_class + msg: >- + deinitializers may only be declared within a class + +- id: expected_lbrace_destructor + msg: >- + expected '{' for deinitializer + +- id: destructor_has_name + msg: >- + deinitializers cannot have a name + +- id: opened_destructor_expected_rparen + msg: >- + expected ')' to close parameter list + +- id: destructor_params + msg: >- + no parameter clause allowed on deinitializer + +- id: operator_decl_inner_scope + msg: >- + 'operator' may only be declared at file scope + +- id: expected_operator_name_after_operator + msg: >- + expected operator name in operator declaration + +- id: identifier_within_operator_name + msg: >- + '%0' is considered an identifier and must not appear within an operator + name + +- id: operator_name_invalid_char + msg: >- + '%0' is not allowed in operator names + +- id: postfix_operator_name_cannot_start_with_unwrap + msg: >- + postfix operator names starting with '?' or '!' are disallowed to avoid + collisions with built-in unwrapping operators + +- id: deprecated_operator_body + msg: >- + operator should no longer be declared with body + +- id: deprecated_operator_body_use_group + msg: >- + operator should no longer be declared with body; use a precedence group + instead + +- id: operator_decl_no_fixity + msg: >- + operator must be declared as 'prefix', 'postfix', or 'infix' + +- id: operator_decl_expected_type + msg: >- + expected designated type in operator declaration + +- id: operator_decl_trailing_comma + msg: >- + trailing comma in operator declaration + +- id: precedencegroup_not_infix + msg: >- + only infix operators may declare a precedence + +- id: expected_precedencegroup_name + msg: >- + expected identifier after 'precedencegroup' + +- id: expected_precedencegroup_lbrace + msg: >- + expected '{' after name of precedence group + +- id: expected_precedencegroup_attribute + msg: >- + expected operator attribute identifier in precedence group body + +- id: unknown_precedencegroup_attribute + msg: >- + '%0' is not a valid precedence group attribute + +- id: expected_precedencegroup_attribute_colon + msg: >- + expected colon after attribute name in precedence group + +- id: precedencegroup_attribute_redeclared + msg: >- + '%0' attribute for precedence group declared multiple times + +- id: expected_precedencegroup_associativity + msg: >- + expected 'none', 'left', or 'right' after 'associativity' + +- id: expected_precedencegroup_assignment + msg: >- + expected 'true' or 'false' after 'assignment' + +- id: expected_precedencegroup_relation + msg: >- + expected name of related precedence group after '%0' + +- id: expected_sil_keyword + msg: >- + expected SIL keyword + +- id: inout_not_attribute + msg: >- + @inout is no longer an attribute + +- id: only_allowed_in_sil + msg: >- + '%0' only allowed in SIL modules + +- id: expected_sil_type + msg: >- + expected type in SIL code + +- id: expected_sil_colon_value_ref + msg: >- + expected ':' before type in SIL value reference + +- id: expected_sil_value_name + msg: >- + expected SIL value name + +- id: expected_sil_type_kind + msg: >- + expected SIL type to %0 + +- id: expected_sil_constant + msg: >- + expected constant in SIL code + +- id: referenced_value_no_accessor + msg: >- + referenced declaration has no %select{getter|setter}0 + +- id: expected_sil_value_ownership_kind + msg: >- + expected value ownership kind in SIL code + +- id: silfunc_and_silarg_have_incompatible_sil_value_ownership + msg: >- + SILFunction and SILArgument have mismatching ValueOwnershipKinds. + Function type specifies: '@%0'. SIL argument specifies: '@%1'. + +- id: expected_sil_colon + msg: >- + expected ':' before %0 + +- id: expected_sil_tuple_index + msg: >- + expected tuple element index + +- id: invalid_index_subset + msg: >- + invalid index subset; expected '[SU]+' where 'S' represents set indices + and 'U' represents unset indices + +- id: sil_value_redefinition + msg: >- + redefinition of value '%0' + +- id: sil_value_use_type_mismatch + msg: >- + value '%0' defined with mismatching type %1 (expected %2) + +- id: sil_value_def_type_mismatch + msg: >- + value '%0' used with mismatching type %1 (expected %2) + +- id: sil_use_of_undefined_value + msg: >- + use of undefined value '%0' + +- id: sil_prior_reference + msg: >- + prior reference was here + +- id: expected_colon_in_sil_location + msg: >- + expected ':' in SIL location + +- id: sil_invalid_line_in_sil_location + msg: >- + line number must be a positive integer + +- id: sil_invalid_column_in_sil_location + msg: >- + column number must be a positive integer + +- id: sil_invalid_scope_slot + msg: >- + scope number must be a positive integer + +- id: sil_scope_undeclared + msg: >- + scope number %0 needs to be declared before first use + +- id: sil_scope_redefined + msg: >- + scope number %0 is already defined + +- id: expected_sil_instr_start_of_line + msg: >- + SIL instructions must be at the start of a line + +- id: expected_equal_in_sil_instr + msg: >- + expected '=' in SIL instruction + +- id: wrong_result_count_in_sil_instr + msg: >- + wrong number of results for SIL instruction, expected %0 + +- id: expected_sil_instr_opcode + msg: >- + expected SIL instruction opcode + +- id: expected_tok_in_sil_instr + msg: >- + expected '%0' in SIL instruction + +- id: sil_property_generic_signature_mismatch + msg: >- + sil_property generic signature must match original declaration + +- id: sil_string_no_encoding + msg: >- + string_literal instruction requires an encoding + +- id: sil_string_invalid_encoding + msg: >- + unknown string literal encoding '%0' + +- id: expected_tuple_type_in_tuple + msg: >- + tuple instruction requires a tuple type + +- id: sil_tuple_inst_wrong_value_count + msg: >- + tuple instruction requires %0 values + +- id: sil_tuple_inst_wrong_field + msg: >- + tuple instruction requires a field number + +- id: sil_struct_inst_wrong_field + msg: >- + struct instruction requires a field name + +- id: sil_ref_inst_wrong_field + msg: >- + ref_element_addr instruction requires a field name + +- id: sil_invalid_instr_operands + msg: >- + invalid instruction operands + +- id: sil_operand_not_address + msg: >- + %0 operand of '%1' must have address type + +- id: sil_operand_not_ref_storage_address + msg: >- + %0 operand of '%1' must have address of %2 type + +- id: sil_integer_literal_not_integer_type + msg: >- + integer_literal instruction requires a 'Builtin.Int' type + +- id: sil_integer_literal_not_well_formed + msg: >- + integer_literal value not well-formed for type %0 + +- id: sil_float_literal_not_float_type + msg: >- + float_literal instruction requires a 'Builtin.FP' type + +- id: sil_substitutions_on_non_polymorphic_type + msg: >- + apply of non-polymorphic function cannot have substitutions + +- id: sil_witness_method_not_protocol + msg: >- + witness_method is not a protocol method + +- id: sil_witness_method_type_does_not_conform + msg: >- + witness_method type does not conform to protocol + +- id: sil_member_decl_not_found + msg: >- + member not found + +- id: sil_named_member_decl_not_found + msg: >- + member %0 not found in type %1 + +- id: sil_member_lookup_bad_type + msg: >- + cannot lookup member %0 in non-nominal, non-module type %1 + +- id: sil_member_decl_type_mismatch + msg: >- + member defined with mismatching type %0 (expected %1) + +- id: sil_substitution_mismatch + msg: >- + substitution replacement type %0 does not conform to protocol %1 + +- id: sil_not_class + msg: >- + substitution replacement type %0 is not a class type + +- id: sil_missing_substitutions + msg: >- + missing substitutions + +- id: sil_too_many_substitutions + msg: >- + too many substitutions + +- id: sil_dbg_unknown_key + msg: >- + unknown key '%0' in debug variable declaration + +- id: sil_objc_with_tail_elements + msg: >- + alloc_ref [objc] cannot have tail allocated elements + +- id: sil_expected_access_kind + msg: >- + %0 instruction must have explicit access kind + +- id: sil_expected_access_enforcement + msg: >- + %0 instruction must have explicit access enforcement + +- id: sil_keypath_expected_component_kind + msg: >- + expected keypath component kind + +- id: sil_keypath_unknown_component_kind + msg: >- + unknown keypath component kind %0 + +- id: sil_keypath_computed_property_missing_part + msg: >- + keypath %select{gettable|settable}0_property component needs an + %select{id and getter|id, getter, and setter}0 + +- id: sil_keypath_no_root + msg: >- + keypath must have a root component declared + +- id: sil_keypath_index_not_hashable + msg: >- + key path index type %0 does not conform to Hashable + +- id: sil_keypath_index_operand_type_conflict + msg: >- + conflicting types for key path operand %0: %1 vs. %2 + +- id: sil_keypath_no_use_of_operand_in_pattern + msg: >- + operand %0 is not referenced by any component in the pattern + +- id: expected_sil_block_name + msg: >- + expected basic block name or '}' + +- id: expected_sil_block_colon + msg: >- + expected ':' after basic block name + +- id: sil_undefined_basicblock_use + msg: >- + use of undefined basic block %0 + +- id: sil_basicblock_redefinition + msg: >- + redefinition of basic block %0 + +- id: sil_basicblock_arg_rparen + msg: >- + expected ')' in basic block argument list + +- id: expected_sil_function_name + msg: >- + expected SIL function name + +- id: expected_sil_rbrace + msg: >- + expected '}' at the end of a sil body + +- id: expected_sil_function_type + msg: >- + sil function expected to have SIL function type + +- id: sil_dynamically_replaced_func_not_found + msg: >- + dynamically replaced function not found %0 + +- id: sil_availability_expected_version + msg: >- + expected version number in 'available' attribute + +- id: expected_sil_stage_name + msg: >- + expected 'raw' or 'canonical' after 'sil_stage' + +- id: multiple_sil_stage_decls + msg: >- + sil_stage declared multiple times + +- id: expected_sil_vtable_colon + msg: >- + expected ':' in a vtable entry + +- id: sil_vtable_func_not_found + msg: >- + sil function not found %0 + +- id: sil_vtable_class_not_found + msg: >- + sil class not found %0 + +- id: sil_vtable_bad_entry_kind + msg: >- + expected 'inherited' or 'override' + +- id: sil_vtable_expect_rsquare + msg: >- + expected ']' after vtable entry kind + +- id: sil_global_variable_not_found + msg: >- + sil global not found %0 + +- id: expected_sil_witness_colon + msg: >- + expected ':' in a witness table + +- id: expected_sil_witness_lparen + msg: >- + expected '(' in a witness table + +- id: expected_sil_witness_rparen + msg: >- + expected ')' in a witness table + +- id: sil_witness_func_not_found + msg: >- + sil function not found %0 + +- id: sil_witness_protocol_not_found + msg: >- + sil protocol not found %0 + +- id: sil_witness_assoc_not_found + msg: >- + sil associated type decl not found %0 + +- id: sil_witness_assoc_conf_not_found + msg: >- + sil associated type path for conformance not found %0 + +- id: sil_witness_protocol_conformance_not_found + msg: >- + sil protocol conformance not found + +- id: sil_diff_witness_expected_token + msg: >- + expected '%0' in differentiability witness + +- id: sil_diff_witness_serialized_declaration + msg: >- + differentiability witness declaration should not be serialized + +- id: sil_diff_witness_undefined + msg: >- + reference to undefined differentiability witness + +- id: sil_diff_witness_invalid_generic_signature + msg: >- + expected witness generic signature '%0' does not have same generic + parameters as original function generic signature '%1' + +- id: sil_coverage_invalid_hash + msg: >- + expected coverage hash + +- id: sil_coverage_expected_lbrace + msg: >- + expected '{' in coverage map + +- id: sil_coverage_expected_loc + msg: >- + expected line:column pair + +- id: sil_coverage_expected_arrow + msg: >- + expected '->' after start location + +- id: sil_coverage_expected_colon + msg: >- + expected ':' after source range + +- id: sil_coverage_invalid_counter + msg: >- + expected counter expression, id, or 'zero' + +- id: sil_coverage_expected_rparen + msg: >- + expected ')' to end counter expression + +- id: sil_coverage_expected_quote + msg: >- + expected quotes surrounding PGO function name + +- id: sil_coverage_invalid_operator + msg: >- + expected '+' or '-' + +- id: expected_type + msg: >- + expected type + +- id: expected_init_value + msg: >- + expected initial value after '=' + +- id: expected_identifier_in_dotted_type + msg: >- + expected identifier in dotted type + +- id: expected_identifier_for_type + msg: >- + expected identifier for type name + +- id: expected_rangle_generic_arg_list + msg: >- + expected '>' to complete generic argument list + +- id: expected_type_function_result + msg: >- + expected type for function result + +- id: generic_non_function + msg: >- + only syntactic function types can be generic + +- id: rethrowing_function_type + msg: >- + only function declarations may be marked 'rethrows'; did you mean + 'throws'? + +- id: throws_in_wrong_position + msg: >- + 'throws' may only occur before '->' + +- id: rethrows_in_wrong_position + msg: >- + 'rethrows' may only occur before '->' + +- id: throw_in_function_type + msg: >- + expected throwing specifier; did you mean 'throws'? + +- id: expected_type_before_arrow + msg: >- + expected type before '->' + +- id: expected_type_after_arrow + msg: >- + expected type after '->' + +- id: function_type_argument_label + msg: >- + function types cannot have argument labels; use '_' before %0 + +- id: expected_dynamic_func_attr + msg: >- + expected a dynamically_replaceable function + +- id: expected_expr_enum_case_raw_value + msg: >- + expected expression after '=' in 'case' + +- id: nonliteral_enum_case_raw_value + msg: >- + raw value for enum case must be a literal + +- id: new_array_syntax + msg: >- + array types are now written with the brackets around the element type + +- id: expected_rbracket_array_type + msg: >- + expected ']' in array type + +- id: expected_element_type + msg: >- + expected element type + +- id: expected_dictionary_value_type + msg: >- + expected dictionary value type + +- id: expected_rbracket_dictionary_type + msg: >- + expected ']' in dictionary type + +- id: extra_rbracket + msg: >- + unexpected ']' in type; did you mean to write an array type? + +- id: extra_colon + msg: >- + unexpected ':' in type; did you mean to write a dictionary type? + +- id: subscript_array_element + msg: >- + unexpected subscript in array literal; did you mean to write two separate + elements instead? + +- id: subscript_array_element_fix_it_add_comma + msg: >- + add a separator between the elements + +- id: subscript_array_element_fix_it_remove_space + msg: >- + remove the space between the elements to silence this warning + +- id: expected_rparen_tuple_type_list + msg: >- + expected ')' at end of tuple list + +- id: multiple_ellipsis_in_tuple + msg: >- + only a single element can be variadic + +- id: tuple_type_init + msg: >- + default argument not permitted in a tuple type + +- id: protocol_method_argument_init + msg: >- + default argument not permitted in a protocol method + +- id: protocol_init_argument_init + msg: >- + default argument not permitted in a protocol initializer + +- id: tuple_type_multiple_labels + msg: >- + tuple element cannot have two labels + +- id: expected_rangle_protocol + msg: >- + expected '>' to complete protocol-constrained type + +- id: deprecated_protocol_composition + msg: >- + 'protocol<...>' composition syntax has been removed; join the protocols + using '&' + +- id: deprecated_protocol_composition_single + msg: >- + 'protocol<...>' composition syntax has been removed and is not needed + here + +- id: deprecated_any_composition + msg: >- + 'protocol<>' syntax has been removed; use 'Any' instead + +- id: sil_box_expected_var_or_let + msg: >- + expected 'var' or 'let' to introduce SIL box field type + +- id: sil_box_expected_r_brace + msg: >- + expected '}' to complete SIL box field type list + +- id: sil_box_expected_r_angle + msg: >- + expected '>' to complete SIL box generic argument list + +- id: sil_function_subst_expected_l_angle + msg: >- + expected '<' to begin SIL function type substitution list after 'for' + +- id: sil_function_subst_expected_r_angle + msg: >- + expected '>' to end SIL function type substitution list after 'for <...' + +- id: sil_function_subst_expected_generics + msg: >- + expected '<' to begin substituted parameter list after '@substituted' + +- id: sil_function_subst_expected_function + msg: >- + expected function type after '@substituted' + +- id: sil_function_subst_expected_subs + msg: >- + expected 'for' to begin substitutions after '@substituted' function type + +- id: sil_function_subs_without_generics + msg: >- + unexpected 'for' to begin substitutions after non-generic function type + +- id: opaque_mid_composition + msg: >- + 'some' should appear at the beginning of a composition + +- id: layout_size_should_be_positive + msg: >- + expected non-negative size to be specified in layout constraint + +- id: layout_alignment_should_be_positive + msg: >- + expected non-negative alignment to be specified in layout constraint + +- id: expected_rparen_layout_constraint + msg: >- + expected ')' to complete layout constraint + +- id: layout_constraints_only_inside_specialize_attr + msg: >- + layout constraints are only allowed inside '_specialize' attributes + +- id: expected_pattern + msg: >- + expected pattern + +- id: keyword_cant_be_identifier + msg: >- + keyword '%0' cannot be used as an identifier here + +- id: repeated_identifier + msg: >- + found an unexpected second identifier in %0 declaration; is there an + accidental break? + +- id: join_identifiers + msg: >- + join the identifiers together + +- id: join_identifiers_camel_case + msg: >- + join the identifiers together with camel-case + +- id: backticks_to_escape + msg: >- + if this name is unavoidable, use backticks to escape it + +- id: expected_rparen_tuple_pattern_list + msg: >- + expected ')' at end of tuple pattern + +- id: untyped_pattern_ellipsis + msg: >- + '...' cannot be applied to a subpattern which is not explicitly typed + +- id: no_default_arg_closure + msg: >- + default arguments are not allowed in closures + +- id: no_default_arg_curried + msg: >- + default arguments are not allowed in curried parameter lists + +- id: var_pattern_in_var + msg: >- + '%select{var|let}0' cannot appear nested inside another 'var' or 'let' + pattern + +- id: extra_var_in_multiple_pattern_list + msg: >- + %0 must be bound in every pattern + +- id: let_pattern_in_immutable_context + msg: >- + 'let' pattern cannot appear nested in an already immutable context + +- id: specifier_must_have_type + msg: >- + %0 arguments must have a type specified + +- id: expected_rparen_parameter + msg: >- + expected ')' in parameter + +- id: expected_parameter_type + msg: >- + expected parameter type following ':' + +- id: expected_parameter_name + msg: >- + expected parameter name followed by ':' + +- id: expected_parameter_colon + msg: >- + expected ':' following argument label and parameter name + +- id: expected_assignment_instead_of_comparison_operator + msg: >- + expected '=' instead of '==' to assign default value for parameter + +- id: multiple_parameter_ellipsis + msg: >- + only a single variadic parameter '...' is permitted + +- id: parameter_vararg_default + msg: >- + variadic parameter cannot have a default value + +- id: parameter_specifier_as_attr_disallowed + msg: >- + '%0' before a parameter name is not allowed, place it before the + parameter type instead + +- id: parameter_specifier_repeated + msg: >- + parameter must not have multiple '__owned', 'inout', or '__shared' + specifiers + +- id: parameter_let_var_as_attr + msg: >- + '%0' in this position is interpreted as an argument label + +- id: parameter_extraneous_double_up + msg: >- + extraneous duplicate parameter name; %0 already has an argument label + +- id: parameter_operator_keyword_argument + msg: >- + %select{operator|closure|enum case}0 cannot have keyword arguments + +- id: parameter_unnamed + msg: >- + unnamed parameters must be written with the empty name '_' + +- id: parameter_unnamed_warn + msg: >- + unnamed parameters must be written with the empty name '_' + +- id: parameter_curry_syntax_removed + msg: >- + cannot have more than one parameter list + +- id: initializer_as_typed_pattern + msg: >- + unexpected initializer in pattern; did you mean to use '='? + +- id: unlabeled_parameter_following_variadic_parameter + msg: >- + a parameter following a variadic parameter requires a label + +- id: enum_element_empty_arglist + msg: >- + enum element with associated values must have at least one associated + value + +- id: enum_element_empty_arglist_swift4 + msg: >- + enum element with associated values must have at least one associated + value; this will be an error in the future version of Swift + +- id: enum_element_empty_arglist_delete + msg: >- + did you mean to remove the empty associated value list? + +- id: enum_element_empty_arglist_add_void + msg: >- + did you mean to explicitly add a 'Void' associated value? + +- id: expected_stmt + msg: >- + expected statement + +- id: illegal_top_level_stmt + msg: >- + statements are not allowed at the top level + +- id: illegal_top_level_expr + msg: >- + expressions are not allowed at the top level + +- id: illegal_semi_stmt + msg: >- + ';' statements are not allowed + +- id: statement_begins_with_closure + msg: >- + top-level statement cannot begin with a closure expression + +- id: statement_same_line_without_semi + msg: >- + consecutive statements on a line must be separated by ';' + +- id: invalid_label_on_stmt + msg: >- + labels are only valid on loops, if, and switch statements + +- id: labeled_block_needs_do + msg: >- + labeled block needs 'do' + +- id: snake_case_deprecated + msg: >- + %0 has been replaced with %1 in Swift 3 + +- id: expected_expr_assignment + msg: >- + expected expression in assignment + +- id: expected_rbrace_in_brace_stmt + msg: >- + expected '}' at end of brace statement + +- id: typealias_inside_protocol_without_type + msg: >- + type alias is missing an assigned type; use 'associatedtype' to define an + associated type requirement + +- id: associatedtype_outside_protocol + msg: >- + associated types can only be defined in a protocol; define a type or + introduce a 'typealias' to satisfy an associated type requirement + +- id: expected_expr_return + msg: >- + expected expression in 'return' statement + +- id: unindented_code_after_return + msg: >- + expression following 'return' is treated as an argument of the 'return' + +- id: indent_expression_to_silence + msg: >- + indent the expression to silence this warning + +- id: expected_expr_throw + msg: >- + expected expression in 'throw' statement + +- id: expected_expr_yield + msg: >- + expected expression in 'yield' statement + +- id: expected_lbrace_after_defer + msg: >- + expected '{' after 'defer' + +- id: expected_comma_stmtcondition + msg: >- + expected ',' joining parts of a multi-clause condition + +- id: expected_expr_conditional + msg: >- + expected expression in conditional + +- id: expected_binding_keyword + msg: >- + expected '%0' in conditional + +- id: expected_expr_conditional_var + msg: >- + expected expression after '=' in conditional binding + +- id: conditional_var_initializer_required + msg: >- + variable binding in a condition requires an initializer + +- id: wrong_condition_case_location + msg: >- + pattern matching binding is spelled with 'case %0', not '%0 case' + +- id: expected_condition_if + msg: >- + expected expression, var, or let in 'if' condition + +- id: missing_condition_after_if + msg: >- + missing condition in an 'if' statement + +- id: expected_lbrace_after_if + msg: >- + expected '{' after 'if' condition + +- id: expected_lbrace_or_if_after_else + msg: >- + expected '{' or 'if' after 'else' + +- id: expected_lbrace_or_if_after_else_fixit + msg: >- + expected '{' or 'if' after 'else'; did you mean to write 'if'? + +- id: unexpected_else_after_if + msg: >- + unexpected 'else' immediately following 'if' condition + +- id: suggest_removing_else + msg: >- + remove 'else' to execute the braced block of statements when the + condition is true + +- id: expected_condition_guard + msg: >- + expected expression, var, let or case in 'guard' condition + +- id: missing_condition_after_guard + msg: >- + missing condition in an 'guard' statement + +- id: expected_else_after_guard + msg: >- + expected 'else' after 'guard' condition + +- id: expected_lbrace_after_guard + msg: >- + expected '{' after 'guard' else + +- id: bound_var_guard_body + msg: >- + variable declared in 'guard' condition is not usable in its body + +- id: expected_condition_while + msg: >- + expected expression, var, or let in 'while' condition + +- id: missing_condition_after_while + msg: >- + missing condition in a 'while' statement + +- id: expected_lbrace_after_while + msg: >- + expected '{' after 'while' condition + +- id: expected_lbrace_after_repeat + msg: >- + expected '{' after 'repeat' + +- id: expected_while_after_repeat_body + msg: >- + expected 'while' after body of 'repeat' statement + +- id: expected_expr_repeat_while + msg: >- + expected expression in 'repeat-while' condition + +- id: do_while_now_repeat_while + msg: >- + 'do-while' statement is not allowed + +- id: do_while_expected_repeat_while + msg: >- + did you mean 'repeat-while' statement? + +- id: do_while_expected_separate_stmt + msg: >- + did you mean separate 'do' and 'while' statements? + +- id: expected_lbrace_after_do + msg: >- + expected '{' after 'do' + +- id: expected_lbrace_after_catch + msg: >- + expected '{' after 'catch' pattern + +- id: expected_catch_where_expr + msg: >- + expected expression for 'where' guard of 'catch' + +- id: docatch_not_trycatch + msg: >- + the 'do' keyword is used to specify a 'catch' region + +- id: c_style_for_stmt_removed + msg: >- + C-style for statement has been removed in Swift 3 + +- id: expected_foreach_in + msg: >- + expected 'in' after for-each pattern + +- id: expected_foreach_container + msg: >- + expected Sequence expression for for-each loop + +- id: expected_foreach_lbrace + msg: >- + expected '{' to start the body of for-each loop + +- id: expected_foreach_where_expr + msg: >- + expected expression in 'where' guard of 'for/in' + +- id: expected_switch_expr + msg: >- + expected expression in 'switch' statement + +- id: expected_lbrace_after_switch + msg: >- + expected '{' after 'switch' subject expression + +- id: expected_rbrace_switch + msg: >- + expected '}' at end of 'switch' statement + +- id: case_outside_of_switch + msg: >- + '%0' label can only appear inside a 'switch' statement + +- id: stmt_in_switch_not_covered_by_case + msg: >- + all statements inside a switch must be covered by a 'case' or 'default' + +- id: case_after_default + msg: >- + additional 'case' blocks cannot appear after the 'default' block of a + 'switch' + +- id: expected_case_where_expr + msg: >- + expected expression for 'where' guard of 'case' + +- id: expected_case_colon + msg: >- + expected ':' after '%0' + +- id: default_with_where + msg: >- + 'default' cannot be used with a 'where' guard expression + +- id: case_stmt_without_body + msg: >- + %select{'case'|'default'}0 label in a 'switch' should have at least one + executable statement + +- id: try_on_stmt + msg: >- + 'try' cannot be used with '%0' + +- id: try_on_return_throw_yield + msg: >- + 'try' must be placed on the %select{returned|thrown|yielded}0 expression + +- id: try_on_var_let + msg: >- + 'try' must be placed on the initial value expression + +- id: expected_expr + msg: >- + expected expression + +- id: expected_separator + msg: >- + expected '%0' separator + +- id: unexpected_separator + msg: >- + unexpected '%0' separator + +- id: expected_expr_after_operator + msg: >- + expected expression after operator + +- id: expected_expr_after_unary_operator + msg: >- + expected expression after unary operator + +- id: expected_prefix_operator + msg: >- + unary operator cannot be separated from its operand + +- id: expected_operator_ref + msg: >- + expected operator name in operator reference + +- id: invalid_postfix_operator + msg: >- + operator with postfix spacing cannot start a subexpression + +- id: expected_member_name + msg: >- + expected member name following '.' + +- id: dollar_numeric_too_large + msg: >- + numeric value following '$' is too large + +- id: numeric_literal_numeric_member + msg: >- + expected named member of numeric literal + +- id: standalone_dollar_identifier + msg: >- + '$' is not an identifier; use backticks to escape it + +- id: dollar_identifier_decl + msg: >- + cannot declare entity named %0; the '$' prefix is reserved for + implicitly-synthesized declarations + +- id: anon_closure_arg_not_in_closure + msg: >- + anonymous closure argument not contained in a closure + +- id: anon_closure_arg_in_closure_with_args + msg: >- + anonymous closure arguments cannot be used inside a closure that has + explicit arguments + +- id: anon_closure_arg_in_closure_with_args_typo + msg: >- + anonymous closure arguments cannot be used inside a closure that has + explicit arguments; did you mean '%0'? + +- id: anon_closure_tuple_param_destructuring + msg: >- + closure tuple parameter does not support destructuring + +- id: expected_closure_parameter_name + msg: >- + expected the name of a closure parameter + +- id: expected_capture_specifier + msg: >- + expected 'weak', 'unowned', or no specifier in capture list + +- id: expected_capture_specifier_name + msg: >- + expected name of in closure capture list + +- id: expected_init_capture_specifier + msg: >- + expected initializer for closure capture specifier + +- id: expected_capture_list_end_rsquare + msg: >- + expected ']' at end of capture list + +- id: cannot_capture_fields + msg: >- + fields may only be captured by assigning to a specific name + +- id: expected_closure_result_type + msg: >- + expected closure result type after '->' + +- id: expected_closure_in + msg: >- + expected 'in' after the closure signature + +- id: unexpected_tokens_before_closure_in + msg: >- + unexpected tokens prior to 'in' + +- id: expected_closure_rbrace + msg: >- + expected '}' at end of closure + +- id: trailing_closure_after_newlines + msg: >- + braces here form a trailing closure separated from its callee by multiple + newlines + +- id: trailing_closure_callee_here + msg: >- + callee is here + +- id: string_literal_no_atsign + msg: >- + string literals in Swift are not preceded by an '@' sign + +- id: invalid_float_literal_missing_leading_zero + msg: >- + '.%0' is not a valid floating point literal; it must be written '0.%0' + +- id: availability_query_outside_if_stmt_guard + msg: >- + #available may only be used as condition of an 'if', 'guard' or 'while' + statement + +- id: empty_arg_label_underscore + msg: >- + an empty argument label is spelled with '_' + +- id: expected_identifier_after_dot_expr + msg: >- + expected identifier after '.' expression + +- id: expected_identifier_after_super_dot_expr + msg: >- + expected identifier or 'init' after super '.' expression + +- id: expected_dot_or_subscript_after_super + msg: >- + expected '.' or '[' after 'super' + +- id: super_in_closure_with_capture + msg: >- + using 'super' in a closure where 'self' is explicitly captured is not yet + supported + +- id: super_in_closure_with_capture_here + msg: >- + 'self' explicitly captured here + +- id: expected_expr_in_expr_list + msg: >- + expected expression in list of expressions + +- id: expected_expr_in_collection_literal + msg: >- + expected expression in container literal + +- id: expected_key_in_dictionary_literal + msg: >- + expected key expression in dictionary literal + +- id: expected_value_in_dictionary_literal + msg: >- + expected value in dictionary literal + +- id: expected_colon_in_dictionary_literal + msg: >- + expected ':' in dictionary literal + +- id: expected_rparen_expr_list + msg: >- + expected ')' in expression list + +- id: expected_rsquare_expr_list + msg: >- + expected ']' in expression list + +- id: expected_rsquare_array_expr + msg: >- + expected ']' in container literal expression + +- id: expected_arg_list_in_object_literal + msg: >- + expected argument list in object literal + +- id: legacy_object_literal + msg: >- + '%select{|[}0#%1(...)%select{|#]}0' has been renamed to '#%2(...)' + +- id: unknown_pound_expr + msg: >- + use of unknown directive '#%0' + +- id: expected_expr_after_if_question + msg: >- + expected expression after '?' in ternary expression + +- id: expected_colon_after_if_question + msg: >- + expected ':' after '? ...' in ternary expression + +- id: expected_expr_after_if_colon + msg: >- + expected expression after '? ... :' in ternary expression + +- id: expected_type_after_is + msg: >- + expected type after 'is' + +- id: expected_type_after_as + msg: >- + expected type after 'as' + +- id: string_interpolation_extra + msg: >- + extra tokens after interpolated string expression + +- id: string_interpolation_list_changing + msg: >- + interpolating multiple values will not form a tuple in Swift 5 + +- id: string_interpolation_list_insert_parens + msg: >- + insert parentheses to keep current behavior + +- id: string_interpolation_label_changing + msg: >- + labeled interpolations will not be ignored in Swift 5 + +- id: string_interpolation_remove_label + msg: >- + remove %0 label to keep current behavior + +- id: expr_keypath_expected_lparen + msg: >- + expected '(' following '#keyPath' + +- id: expr_keypath_expected_property_or_type + msg: >- + expected property or type name within '#keyPath(...)' + +- id: expr_keypath_expected_rparen + msg: >- + expected ')' to complete '#keyPath' expression + +- id: expr_keypath_expected_expr + msg: >- + expected expression path in Swift key path + +- id: expr_selector_expected_lparen + msg: >- + expected '(' following '#selector' + +- id: expr_selector_expected_method_expr + msg: >- + expected expression naming a method within '#selector(...)' + +- id: expr_selector_expected_property_expr + msg: >- + expected expression naming a property within '#selector(...)' + +- id: expr_selector_expected_rparen + msg: >- + expected ')' to complete '#selector' expression + +- id: expr_dynamictype_deprecated + msg: >- + '.dynamicType' is deprecated. Use 'type(of: ...)' instead + +- id: pound_assert_disabled + msg: >- + #assert is an experimental feature that is currently disabled + +- id: pound_assert_expected_lparen + msg: >- + expected '(' in #assert directive + +- id: pound_assert_expected_rparen + msg: >- + expected ')' in #assert directive + +- id: pound_assert_expected_expression + msg: >- + expected a condition expression + +- id: pound_assert_expected_string_literal + msg: >- + expected a string literal + +- id: replace_equal_with_colon_for_value + msg: >- + '=' has been replaced with ':' in attribute arguments + +- id: expected_attribute_name + msg: >- + expected an attribute name + +- id: unknown_attribute + msg: >- + unknown attribute '%0' + +- id: unexpected_lparen_in_attribute + msg: >- + unexpected '(' in attribute '%0' + +- id: duplicate_attribute + msg: >- + duplicate %select{attribute|modifier}0 + +- id: previous_attribute + msg: >- + %select{attribute|modifier}0 already specified here + +- id: mutually_exclusive_attrs + msg: >- + '%0' contradicts previous %select{attribute|modifier}2 '%1' + +- id: invalid_infix_on_func + msg: >- + 'infix' modifier is not required or allowed on func declarations + +- id: expected_in_attribute_list + msg: >- + expected ']' or ',' in attribute list + +- id: type_attribute_applied_to_decl + msg: >- + attribute can only be applied to types, not declarations + +- id: decl_attribute_applied_to_type + msg: >- + attribute can only be applied to declarations, not types + +- id: attr_expected_lparen + msg: >- + expected '(' in '%0' %select{attribute|modifier}1 + +- id: attr_expected_rparen + msg: >- + expected ')' in '%0' %select{attribute|modifier}1 + +- id: attr_expected_comma + msg: >- + expected ',' in '%0' %select{attribute|modifier}1 + +- id: attr_expected_string_literal + msg: >- + expected string literal in '%0' attribute + +- id: attr_missing_label + msg: >- + missing label '%0:' in '@%1' attribute + +- id: attr_expected_label + msg: >- + expected label '%0:' in '@%1' attribute + +- id: alignment_must_be_positive_integer + msg: >- + alignment value must be a positive integer literal + +- id: swift_native_objc_runtime_base_must_be_identifier + msg: >- + @_swift_native_objc_runtime_base class name must be an identifier + +- id: objc_runtime_name_must_be_identifier + msg: >- + @_objcRuntimeName name must be an identifier + +- id: attr_only_at_non_local_scope + msg: >- + attribute '%0' can only be used in a non-local scope + +- id: projection_value_property_not_identifier + msg: >- + @_projectedValueProperty name must be an identifier + +- id: attr_access_expected_set + msg: >- + expected 'set' as subject of '%0' modifier + +- id: attr_access_expected_spi_name + msg: >- + expected an SPI identifier as subject of the '@_spi' attribute + +- id: attr_renamed + msg: >- + '@%0' has been renamed to '@%1' + +- id: attr_renamed_warning + msg: >- + '@%0' has been renamed to '@%1' + +- id: attr_name_close_match + msg: >- + no attribute named '@%0'; did you mean '@%1'? + +- id: attr_unsupported_on_target + msg: >- + attribute '%0' is unsupported on target '%1' + +- id: attr_availability_platform + msg: >- + expected platform name or '*' for '%0' attribute + +- id: attr_availability_unavailable_deprecated + msg: >- + '%0' attribute cannot be both unconditionally 'unavailable' and + 'deprecated' + +- id: attr_availability_invalid_duplicate + msg: >- + '%0' argument has already been specified + +- id: attr_availability_unknown_platform + msg: >- + unknown platform '%0' for attribute '%1' + +- id: attr_availability_invalid_renamed + msg: >- + 'renamed' argument of '%0' attribute must be an operator, identifier, or + full function name, optionally prefixed by a type name + +- id: attr_availability_expected_option + msg: >- + expected '%0' option such as 'unavailable', 'introduced', 'deprecated', + 'obsoleted', 'message', or 'renamed' + +- id: attr_availability_expected_equal + msg: >- + expected ':' after '%1' in '%0' attribute + +- id: attr_availability_expected_version + msg: >- + expected version number in '%0' attribute + +- id: attr_availability_platform_agnostic_expected_option + msg: >- + expected 'introduced', 'deprecated', or 'obsoleted' in '%0' attribute for + platform '%1' + +- id: attr_availability_platform_agnostic_expected_deprecated_version + msg: >- + expected version number with 'deprecated' in '%0' attribute for platform + '%1' + +- id: attr_availability_platform_agnostic_infeasible_option + msg: >- + '%0' cannot be used in '%1' attribute for platform '%2' + +- id: attr_availability_nonspecific_platform_unexpected_version + msg: >- + unexpected version number in '%0' attribute for non-specific platform '*' + +- id: originally_defined_in_missing_rparen + msg: >- + expected ')' in @_originallyDefinedIn argument list + +- id: originally_defined_in_unrecognized_platform + msg: >- + unrecognized platform name in @_originallyDefinedIn argument list + +- id: originally_defined_in_unrecognized_property + msg: >- + unrecognized property in @_originallyDefinedIn argument list + +- id: originally_defined_in_need_original_module_name + msg: >- + expected 'module: "original"' in the first argument to + @_originallyDefinedIn + +- id: originally_defined_in_need_nonempty_module_name + msg: >- + original module name cannot be empty in @_originallyDefinedIn + +- id: originally_defined_in_need_platform_version + msg: >- + expected at least one platform version in @_originallyDefinedIn + +- id: originally_defined_in_major_minor_only + msg: >- + @_originallyDefinedIn only uses major and minor version number + +- id: originally_defined_in_missing_platform_name + msg: >- + * as platform name has no effect + +- id: convention_attribute_expected_lparen + msg: >- + expected '(' after 'convention' attribute + +- id: convention_attribute_expected_name + msg: >- + expected convention name identifier in 'convention' attribute + +- id: convention_attribute_expected_rparen + msg: >- + expected ')' after convention name for 'convention' attribute + +- id: convention_attribute_ctype_expected_label + msg: >- + expected 'cType' label in 'convention' attribute + +- id: convention_attribute_ctype_expected_colon + msg: >- + expected ':' after 'cType' for 'convention' attribute + +- id: convention_attribute_ctype_expected_string + msg: >- + expected string literal containing clang type for 'cType' in 'convention' + attribute + +- id: convention_attribute_witness_method_expected_colon + msg: >- + expected ':' after 'witness_method' for 'convention' attribute + +- id: convention_attribute_witness_method_expected_protocol + msg: >- + expected protocol name in 'witness_method' 'convention' attribute + +- id: attr_objc_missing_colon + msg: >- + missing ':' after selector piece in @objc attribute + +- id: attr_objc_expected_rparen + msg: >- + expected ')' after name for @objc + +- id: attr_objc_empty_name + msg: >- + expected name within parentheses of @objc attribute + +- id: attr_dynamic_replacement_expected_rparen + msg: >- + expected ')' after function name for @_dynamicReplacement + +- id: attr_dynamic_replacement_expected_function + msg: >- + expected a function name in @_dynamicReplacement(for:) + +- id: attr_dynamic_replacement_expected_for + msg: >- + expected 'for' in '_dynamicReplacement' attribute + +- id: attr_dynamic_replacement_expected_colon + msg: >- + expected ':' after @_dynamicReplacement(for + +- id: attr_type_eraser_expected_type_name + msg: >- + expected a type name in @_typeEraser() + +- id: attr_type_eraser_expected_rparen + msg: >- + expected ')' after type name for @_typeEraser + +- id: attr_private_import_expected_rparen + msg: >- + expected ')' after function name for @_private + +- id: attr_private_import_expected_sourcefile + msg: >- + expected 'sourceFile' in '_private' attribute + +- id: attr_private_import_expected_sourcefile_name + msg: >- + expected a source file name in @_private(sourceFile:) + +- id: attr_private_import_expected_colon + msg: >- + expected ':' after @_private(sourceFile + +- id: opened_attribute_expected_lparen + msg: >- + expected '(' after 'opened' attribute + +- id: opened_attribute_id_value + msg: >- + known id for 'opened' attribute must be a UUID string + +- id: opened_attribute_expected_rparen + msg: >- + expected ')' after id value for 'opened' attribute + +- id: optimization_attribute_expect_option + msg: >- + expected '%0' option such as '%1' + +- id: optimization_attribute_unknown_option + msg: >- + unknown option '%0' for attribute '%1' + +- id: effects_attribute_expect_option + msg: >- + expected '%0' option (readnone, readonly, readwrite) + +- id: effects_attribute_unknown_option + msg: >- + unknown option '%0' for attribute '%1' + +- id: attr_unowned_invalid_specifier + msg: >- + expected 'safe' or 'unsafe' + +- id: attr_unowned_expected_rparen + msg: >- + expected ')' after specifier for 'unowned' + +- id: attr_warn_unused_result_removed + msg: >- + 'warn_unused_result' attribute behavior is now the default + +- id: attr_warn_unused_result_expected_rparen + msg: >- + expected ')' after 'warn_unused_result' attribute + +- id: attr_specialize_missing_colon + msg: >- + missing ':' after %0 in '_specialize' attribute + +- id: attr_specialize_missing_comma + msg: >- + missing ',' in '_specialize' attribute + +- id: attr_specialize_unknown_parameter_name + msg: >- + unknown parameter %0 in '_specialize attribute' + +- id: attr_specialize_expected_bool_value + msg: >- + expected a boolean true or false value in '_specialize' attribute + +- id: attr_specialize_export_true_no_op + msg: >- + 'exported: true' has no effect in '_specialize' attribute + +- id: attr_specialize_missing_parameter_label_or_where_clause + msg: >- + expected a parameter label or a where clause in '_specialize' attribute + +- id: attr_specialize_parameter_already_defined + msg: >- + parameter '%0' was already defined in '_specialize' attribute + +- id: attr_specialize_expected_partial_or_full + msg: >- + expected 'partial' or 'full' as values of the 'kind' parameter in + '_specialize' attribute + +- id: attr_implements_expected_member_name + msg: >- + expected a member name as second parameter in '_implements' attribute + +- id: attr_differentiable_expected_parameter_list + msg: >- + expected a list of parameters to differentiate with respect to + +- id: attr_differentiable_use_wrt_not_withrespectto + msg: >- + use 'wrt:' to specify parameters to differentiate with respect to + +- id: attr_differentiable_expected_label + msg: >- + expected 'wrt:' or 'where' in '@differentiable' attribute + +- id: attr_differentiable_unexpected_argument + msg: >- + unexpected argument '%0' in '@differentiable' attribute + +- id: expected_colon_after_label + msg: >- + expected a colon ':' after '%0' + +- id: diff_params_clause_expected_parameter + msg: >- + expected a parameter, which can be a function parameter name, parameter + index, or 'self' + +- id: diff_params_clause_expected_parameter_unnamed + msg: >- + expected a parameter, which can be a function parameter index or 'self' + +- id: autodiff_attr_expected_original_decl_name + msg: >- + expected an original function name + +- id: sil_autodiff_expected_lsquare + msg: >- + expected '[' to start the %0 + +- id: sil_autodiff_expected_rsquare + msg: >- + expected ']' to complete the %0 + +- id: sil_autodiff_expected_index_list + msg: >- + expected a space-separated list of indices, e.g. '0 1' + +- id: sil_autodiff_expected_index_list_label + msg: >- + expected label '%0' in index list + +- id: sil_autodiff_expected_parameter_index + msg: >- + expected the index of a parameter to differentiate with respect to + +- id: sil_autodiff_expected_result_index + msg: >- + expected the index of a result to differentiate from + +- id: sil_inst_autodiff_operand_list_expected_lbrace + msg: >- + expected '{' to start a derivative function list + +- id: sil_inst_autodiff_operand_list_expected_comma + msg: >- + expected ',' between operands in a derivative function list + +- id: sil_inst_autodiff_operand_list_expected_rbrace + msg: >- + expected '}' to start a derivative function list + +- id: sil_inst_autodiff_expected_differentiable_extractee_kind + msg: >- + expected an extractee kind attribute, which can be one of '[original]', + '[jvp]', and '[vjp]' + +- id: sil_inst_autodiff_expected_linear_extractee_kind + msg: >- + expected an extractee kind attribute, which can be one of '[original]' + and '[transpose]' + +- id: sil_inst_autodiff_expected_function_type_operand + msg: >- + expected an operand of a function type + +- id: sil_inst_autodiff_expected_differentiability_witness_kind + msg: >- + expected a differentiability witness kind, which can be one of '[jvp]', + '[vjp]', or '[transpose]' + +- id: sil_inst_autodiff_invalid_witness_generic_signature + msg: >- + expected witness_generic signature '%0' does not have same generic + parameters as original function generic signature '%1' + +- id: expected_rangle_generics_param + msg: >- + expected '>' to complete generic parameter list + +- id: expected_generics_parameter_name + msg: >- + expected an identifier to name generic parameter + +- id: unexpected_class_constraint + msg: >- + 'class' constraint can only appear on protocol declarations + +- id: suggest_anyobject + msg: >- + did you mean to write an 'AnyObject' constraint? + +- id: expected_generics_type_restriction + msg: >- + expected a class type or protocol-constrained type restricting %0 + +- id: requires_single_equal + msg: >- + use '==' for same-type requirements rather than '=' + +- id: requires_comma + msg: >- + expected ',' to separate the requirements of this 'where' clause + +- id: expected_requirement_delim + msg: >- + expected ':' or '==' to indicate a conformance or same-type requirement + +- id: redundant_class_requirement + msg: >- + redundant 'class' requirement + +- id: late_class_requirement + msg: >- + 'class' must come first in the requirement list + +- id: where_inside_brackets + msg: >- + 'where' clause next to generic parameters is obsolete, must be written + following the declaration's type + +- id: unsupported_conditional_compilation_binary_expression + msg: >- + expected '&&' or '||' expression + +- id: unsupported_conditional_compilation_unary_expression + msg: >- + expected unary '!' expression + +- id: unsupported_platform_condition_expression + msg: >- + unexpected platform condition (expected 'os', 'arch', or 'swift') + +- id: platform_condition_expected_one_argument + msg: >- + expected only one argument to platform condition + +- id: unsupported_platform_runtime_condition_argument + msg: >- + unexpected argument for the '_runtime' condition; expected '_Native' or + '_ObjC' + +- id: unsupported_platform_condition_argument + msg: >- + unexpected platform condition argument: expected %0 + +- id: unsupported_conditional_compilation_expression_type + msg: >- + invalid conditional compilation expression + +- id: unsupported_conditional_compilation_integer + msg: >- + '%0' is not a valid conditional compilation expression, use '%1' + +- id: version_component_not_number + msg: >- + version component contains non-numeric characters + +- id: compiler_version_too_many_components + msg: >- + compiler version must not have more than five components + +- id: unused_compiler_version_component + msg: >- + the second version component is not used for comparison + +- id: empty_version_component + msg: >- + found empty version component + +- id: compiler_version_component_out_of_range + msg: >- + compiler version component out of range: must be in [0, %0] + +- id: empty_version_string + msg: >- + version requirement is empty + +- id: unknown_platform_condition_argument + msg: >- + unknown %0 for build configuration '%1' + +- id: renamed_platform_condition_argument + msg: >- + '%0' has been renamed to '%1' + +- id: likely_simulator_platform_condition + msg: >- + platform condition appears to be testing for simulator environment; use + 'targetEnvironment(simulator)' instead + +- id: avail_query_expected_condition + msg: >- + expected availability condition + +- id: avail_query_expected_platform_name + msg: >- + expected platform name + +- id: avail_query_expected_version_number + msg: >- + expected version number + +- id: avail_query_expected_rparen + msg: >- + expected ')' in availability query + +- id: avail_query_unrecognized_platform_name + msg: >- + unrecognized platform name %0 + +- id: avail_query_disallowed_operator + msg: >- + '%0' cannot be used in an availability condition + +- id: avail_query_argument_and_shorthand_mix_not_allowed + msg: >- + '%0' can't be combined with shorthand specification '%1' + +- id: avail_query_meant_introduced + msg: >- + did you mean to specify an introduction version? + +- id: avail_query_version_comparison_not_needed + msg: >- + version comparison not needed + +- id: availability_query_wildcard_required + msg: >- + must handle potential future platforms with '*' + +- id: availability_must_occur_alone + msg: >- + '%0' version-availability must be specified alone + +- id: pound_available_swift_not_allowed + msg: >- + Swift language version checks not allowed in #available(...) + +- id: pound_available_package_description_not_allowed + msg: >- + PackageDescription version checks not allowed in #available(...) + +- id: availability_query_repeated_platform + msg: >- + version for '%0' already specified + +- id: unknown_syntax_entity + msg: >- + unknown %0 syntax exists in the source + +- id: expected_argument_label_followed_by_closure_literal + msg: >- + expected an argument label followed by a closure literal + +- id: expected_closure_literal + msg: >- + expected a closure literal + +- id: expected_multiple_closures_block_rbrace + msg: >- + expected '}' at the end of a trailing closures block + +- id: decl_declared_here + msg: >- + %0 declared here + +- id: kind_declared_here + msg: >- + %0 declared here + +- id: implicit_member_declared_here + msg: >- + %1 '%0' is implicitly declared + +- id: extended_type_declared_here + msg: >- + extended type declared here + +- id: opaque_return_type_declared_here + msg: >- + opaque return type declared here + +- id: ambiguous_member_overload_set + msg: >- + ambiguous reference to member %0 + +- id: ambiguous_reference_to_decl + msg: >- + ambiguous reference to %0 %1 + +- id: no_overloads_match_exactly_in_call + msg: >- + no exact matches in %select{reference|call}0 to %1 %select{%3|}2 + +- id: candidate_partial_match + msg: >- + candidate has partially matching parameter list %0 + +- id: could_not_find_value_subscript + msg: >- + value of type %0 has no subscripts + +- id: could_not_find_tuple_member + msg: >- + value of tuple type %0 has no member %1 + +- id: could_not_find_value_member + msg: >- + value of type %0 has no member %1 + +- id: could_not_find_value_member_corrected + msg: >- + value of type %0 has no member %1; did you mean %2? + +- id: could_not_find_value_dynamic_member_corrected + msg: >- + value of type %0 has no dynamic member %2 using key path from root type + %1; did you mean %3? + +- id: could_not_find_value_dynamic_member + msg: >- + value of type %0 has no dynamic member %2 using key path from root type + %1 + +- id: cannot_infer_contextual_keypath_type_specify_root + msg: >- + cannot infer key path type from context; consider explicitly specifying a + root type + +- id: cannot_infer_keypath_root_anykeypath_context + msg: >- + 'AnyKeyPath' does not provide enough context for root type to be + inferred; consider explicitly specifying a root type + +- id: could_not_find_type_member + msg: >- + type %0 has no member %1 + +- id: could_not_find_type_member_corrected + msg: >- + type %0 has no member %1; did you mean %2? + +- id: could_not_find_subscript_member_did_you_mean + msg: >- + value of type %0 has no property or method named 'subscript'; did you + mean to use the subscript operator? + +- id: could_not_find_enum_case + msg: >- + enum type %0 has no case %1; did you mean %2? + +- id: did_you_mean_raw_type + msg: >- + did you mean to specify a raw type on the enum declaration? + +- id: did_you_mean_generic_param_as_conformance + msg: >- + did you mean to declare %0 as a protocol conformance for %1? + +- id: any_as_anyobject_fixit + msg: >- + cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more + specific type to access members + +- id: expected_argument_in_contextual_member + msg: >- + member %0 expects argument of type %1 + +- id: expected_parens_in_contextual_member + msg: >- + member %0 is a function; did you mean to call it? + +- id: expected_result_in_contextual_member + msg: >- + member %0 in %2 produces result of type %1, but context expects %2 + +- id: unexpected_arguments_in_enum_case + msg: >- + enum case %0 has no associated values + +- id: could_not_use_type_member_on_instance + msg: >- + static member %1 cannot be used on instance of type %0 + +- id: could_not_use_enum_element_on_instance + msg: >- + enum case %0 cannot be used as an instance member + +- id: could_not_use_type_member_on_protocol_metatype + msg: >- + static member %1 cannot be used on protocol metatype %0 + +- id: could_not_use_instance_member_on_type + msg: >- + instance member %1%select{| of type %2}3 + cannot be used on%select{| instance of nested}3 type %0 + +- id: could_not_use_member_on_existential + msg: >- + member %1 cannot be used on value of protocol type %0; use a generic + constraint instead + +- id: candidate_inaccessible + msg: >- + %0 is inaccessible due to + '%select{private|fileprivate|internal|@_spi|@_spi}1' protection level + +- id: note_candidate_inaccessible + msg: >- + %0 is inaccessible due to + '%select{private|fileprivate|internal|@_spi|@_spi}1' protection level + +- id: init_candidate_inaccessible + msg: >- + %0 initializer is inaccessible due to + '%select{private|fileprivate|internal|@_spi|@_spi}1' protection level + +- id: cannot_pass_rvalue_mutating_subelement + msg: >- + cannot use mutating member on immutable value: %0 + +- id: cannot_pass_rvalue_mutating + msg: >- + cannot use mutating member on immutable value of type %0 + +- id: cannot_pass_rvalue_mutating_getter_subelement + msg: >- + cannot use mutating getter on immutable value: %0 + +- id: cannot_pass_rvalue_mutating_getter + msg: >- + cannot use mutating getter on immutable value of type %0 + +- id: expression_too_complex + msg: >- + the compiler is unable to type-check this expression in reasonable time; + try breaking up the expression into distinct sub-expressions + +- id: value_type_comparison_with_nil_illegal_did_you_mean + msg: >- + value of type %0 cannot be compared by reference; did you mean to compare + by value? + +- id: value_type_comparison_with_nil_illegal + msg: >- + type %0 is not optional, value can never be nil + +- id: cannot_match_expr_pattern_with_value + msg: >- + expression pattern of type %0 cannot match values of type %1 + +- id: cannot_match_expr_tuple_pattern_with_nontuple_value + msg: >- + tuple pattern cannot match values of non-tuple type %0 + +- id: cannot_match_unresolved_expr_pattern_with_value + msg: >- + pattern cannot match values of type %0 + +- id: cannot_reference_compare_types + msg: >- + cannot check reference equality of functions; operands here have types %1 + and %2 + +- id: cannot_apply_binop_to_args + msg: >- + binary operator '%0' cannot be applied to operands of type %1 and %2 + +- id: cannot_apply_binop_to_same_args + msg: >- + binary operator '%0' cannot be applied to two %1 operands + +- id: cannot_apply_unop_to_arg + msg: >- + unary operator '%0' cannot be applied to an operand of type %1 + +- id: cannot_apply_lvalue_unop_to_subelement + msg: >- + cannot pass immutable value to mutating operator: %0 + +- id: cannot_apply_lvalue_unop_to_rvalue + msg: >- + cannot pass immutable value of type %0 to mutating operator + +- id: cannot_apply_lvalue_binop_to_subelement + msg: >- + left side of mutating operator isn't mutable: %0 + +- id: cannot_apply_lvalue_binop_to_rvalue + msg: >- + left side of mutating operator has immutable type %0 + +- id: cannot_subscript_base + msg: >- + cannot subscript a value of type %0 + +- id: cannot_subscript_ambiguous_base + msg: >- + cannot subscript a value of incorrect or ambiguous type + +- id: cannot_subscript_nil_literal + msg: >- + cannot subscript a nil literal value + +- id: conditional_cast_from_nil + msg: >- + nil literal cannot be the source of a conditional cast + +- id: cannot_pass_rvalue_inout_subelement + msg: >- + cannot pass immutable value as inout argument: %0 + +- id: cannot_pass_rvalue_inout_converted + msg: >- + inout argument could be set to a value with a type other than %0; use a + value declared as type %1 instead + +- id: inout_change_var_type_if_possible + msg: >- + change variable type to %1 if it doesn't need to be declared as %0 + +- id: cannot_pass_rvalue_inout + msg: >- + cannot pass immutable value of type %0 as inout argument + +- id: cannot_provide_default_value_inout + msg: >- + cannot provide default value to inout parameter %0 + +- id: cannot_call_with_params + msg: >- + cannot invoke %select{|initializer for type }2'%0' with an argument list + of type '%1' + +- id: cannot_call_non_function_value + msg: >- + cannot call value of non-function type %0 + +- id: no_candidates_match_result_type + msg: >- + no '%0' candidates produce the expected contextual result type %1 + +- id: no_candidates_match_argument_type + msg: >- + no '%0' candidates produce the expected type %1 for parameter #%2 + +- id: cannot_infer_closure_parameter_type + msg: >- + unable to infer type of a closure parameter %0 in the current context + +- id: cannot_infer_closure_type + msg: >- + unable to infer closure type in the current context + +- id: cannot_infer_closure_result_type + msg: >- + unable to infer%select{ complex|}0 closure return type; add explicit type + to disambiguate + +- id: incorrect_explicit_closure_result + msg: >- + declared closure result %0 is incompatible with contextual type %1 + +- id: suggest_expected_match + msg: >- + %select{expected an argument list|produces result}0 of type '%1' + +- id: suggest_partial_overloads + msg: >- + overloads for '%1' exist with these %select{partially matching parameter + lists|result types}0: %2 + +- id: no_binary_op_overload_for_enum_with_payload + msg: >- + binary operator '%0' cannot be synthesized for enums with associated + values + +- id: cannot_convert_initializer_value + msg: >- + cannot convert value of type %0 to specified type %1 + +- id: cannot_convert_initializer_value_protocol + msg: >- + value of type %0 does not conform to specified type %1 + +- id: cannot_convert_initializer_value_anyobject + msg: >- + value of type %0 expected to be instance of class or class-constrained + type + +- id: cannot_convert_initializer_value_nil + msg: >- + 'nil' cannot initialize specified type %0 + +- id: cannot_convert_to_return_type + msg: >- + cannot convert return expression of type %0 to return type %1 + +- id: cannot_convert_to_return_type_protocol + msg: >- + return expression of type %0 does not conform to %1 + +- id: cannot_convert_return_type_to_anyobject + msg: >- + return expression of type %0 expected to be an instance of a class or + class-constrained type + +- id: cannot_convert_to_return_type_nil + msg: >- + 'nil' is incompatible with return type %0 + +- id: cannot_convert_thrown_type + msg: >- + thrown expression type %0 does not conform to 'Error' + +- id: cannot_throw_error_code + msg: >- + thrown error code type %0 does not conform to 'Error'; construct an %1 + instance + +- id: bad_yield_count + msg: >- + expected %0 yield value(s) + +- id: cannot_throw_nil + msg: >- + cannot infer concrete Error for thrown 'nil' value + +- id: cannot_convert_raw_initializer_value + msg: >- + cannot convert value of type %0 to raw type %1 + +- id: cannot_convert_raw_initializer_value_nil + msg: >- + cannot convert 'nil' to raw type %0 + +- id: cannot_convert_default_arg_value + msg: >- + default argument value of type %0 cannot be converted to type %1 + +- id: cannot_convert_default_arg_value_protocol + msg: >- + default argument value of type %0 does not conform to %1 + +- id: cannot_convert_default_arg_value_nil + msg: >- + nil default argument value cannot be converted to type %0 + +- id: cannot_convert_argument_value + msg: >- + cannot convert value of type %0 to expected argument type %1 + +- id: candidate_has_invalid_argument_at_position + msg: >- + candidate expects %select{|in-out }2value of type %0 for parameter #%1 + +- id: cannot_convert_array_to_variadic + msg: >- + cannot pass array of type %0 as variadic arguments of type %1 + +- id: candidate_would_match_array_to_variadic + msg: >- + candidate would match if array elements were passed as variadic arguments + of type %0 + +- id: suggest_pass_elements_directly + msg: >- + remove brackets to pass array elements directly + +- id: cannot_convert_argument_value_generic + msg: >- + cannot convert value of type %0 (%1) to expected argument type %2 (%3) + +- id: conflicting_arguments_for_generic_parameter + msg: >- + conflicting arguments to generic parameter %0 (%1) + +- id: cannot_pass_type_to_non_ephemeral + msg: >- + cannot pass %0 to parameter; argument %1 must be a pointer that outlives + the call%select{| to %3}2 + +- id: cannot_pass_type_to_non_ephemeral_warning + msg: >- + passing %0 to parameter, but argument %1 should be a pointer that + outlives the call%select{| to %3}2 + +- id: cannot_use_inout_non_ephemeral + msg: >- + cannot use inout expression here; argument %0 must be a pointer that + outlives the call%select{| to %2}1 + +- id: cannot_use_inout_non_ephemeral_warning + msg: >- + inout expression creates a temporary pointer, but argument %0 should be a + pointer that outlives the call%select{| to %2}1 + +- id: cannot_construct_dangling_pointer + msg: >- + initialization of %0 results in a dangling %select{|buffer }1pointer + +- id: cannot_construct_dangling_pointer_warning + msg: >- + initialization of %0 results in a dangling %select{|buffer }1pointer + +- id: ephemeral_pointer_argument_conversion_note + msg: >- + implicit argument conversion from %0 to %1 produces a pointer valid only + for the duration of the call%select{| to %3}2 + +- id: ephemeral_use_with_unsafe_pointer + msg: >- + use 'withUnsafe%select{Bytes|MutableBytes|Pointer|MutablePointer}0' in + order to explicitly convert argument to %select{buffer |buffer ||}0pointer + valid for a defined scope + +- id: ephemeral_use_string_with_c_string + msg: >- + use the 'withCString' method on String in order to explicitly convert + argument to pointer valid for a defined scope + +- id: ephemeral_use_array_with_unsafe_buffer + msg: >- + use the + 'withUnsafe%select{Bytes|MutableBytes|BufferPointer|MutableBufferPointer}0' + method on Array in order to explicitly convert argument to buffer pointer valid + for a defined scope + +- id: candidate_performs_illegal_ephemeral_conv + msg: >- + candidate expects pointer that outlives the call for parameter #%0 + +- id: cannot_convert_argument_value_protocol + msg: >- + argument type %0 does not conform to expected type %1 + +- id: cannot_convert_argument_value_anyobject + msg: >- + argument type %0 expected to be an instance of a class or + class-constrained type + +- id: cannot_convert_argument_value_nil + msg: >- + 'nil' is not compatible with expected argument type %0 + +- id: cannot_convert_condition_value + msg: >- + cannot convert value of type %0 to expected condition type %1 + +- id: cannot_convert_condition_value_nil + msg: >- + 'nil' is not compatible with expected condition type %0 + +- id: cannot_yield_rvalue_by_reference_same_type + msg: >- + cannot yield immutable value of type %0 as an inout yield + +- id: cannot_yield_rvalue_by_reference + msg: >- + cannot yield immutable value of type %0 as an inout yield of type %1 + +- id: cannot_yield_wrong_type_by_reference + msg: >- + cannot yield reference to storage of type %0 as an inout yield of type %1 + +- id: cannot_convert_yield_value + msg: >- + cannot convert value of type %0 to expected yield type %1 + +- id: cannot_convert_yield_value_protocol + msg: >- + yielded type %0 does not conform to expected type %1 + +- id: cannot_convert_yield_value_nil + msg: >- + nil is not compatible with expected yield type %0 + +- id: cannot_convert_closure_result + msg: >- + cannot convert value of type %0 to closure result type %1 + +- id: cannot_convert_closure_result_protocol + msg: >- + result value of type %0 does not conform to closure result type %1 + +- id: cannot_convert_closure_result_nil + msg: >- + 'nil' is not compatible with closure result type %0 + +- id: cannot_convert_parent_type + msg: >- + cannot convert parent type %0 to expected type %1 + +- id: generic_argument_mismatch + msg: >- + arguments to generic parameter %0 (%1 and %2) are expected to be equal + +- id: destructor_not_accessible + msg: >- + deinitializers cannot be accessed + +- id: cannot_convert_array_element + msg: >- + cannot convert value of type %0 to expected element type %1 + +- id: cannot_convert_array_element_protocol + msg: >- + value of type %0 does not conform to expected element type %1 + +- id: cannot_convert_array_element_nil + msg: >- + 'nil' is not compatible with expected element type %0 + +- id: cannot_convert_dict_key + msg: >- + cannot convert value of type %0 to expected dictionary key type %1 + +- id: cannot_convert_dict_key_protocol + msg: >- + value of type %0 does not conform to expected dictionary key type %1 + +- id: cannot_convert_dict_key_nil + msg: >- + 'nil' is not compatible with expected dictionary key type %0 + +- id: cannot_convert_dict_value + msg: >- + cannot convert value of type %0 to expected dictionary value type %1 + +- id: cannot_convert_dict_value_protocol + msg: >- + value of type %0 does not conform to expected dictionary value type %1 + +- id: cannot_convert_dict_value_nil + msg: >- + 'nil' is not compatible with expected dictionary value type %0 + +- id: cannot_convert_coerce + msg: >- + cannot convert value of type %0 to type %1 in coercion + +- id: cannot_convert_coerce_protocol + msg: >- + value of type %0 does not conform to %1 in coercion + +- id: cannot_convert_coerce_nil + msg: >- + 'nil' is not compatible with type %0 in coercion + +- id: cannot_convert_assign + msg: >- + cannot assign value of type %0 to type %1 + +- id: assign_protocol_conformance_fix_it + msg: >- + add missing conformance to %0 to %1 %2 + +- id: cannot_convert_assign_protocol + msg: >- + value of type %0 does not conform to %1 in assignment + +- id: cannot_convert_assign_anyobject + msg: >- + value of type %0 expected to be an instance of a class or + class-constrained type in assignment + +- id: cannot_convert_assign_nil + msg: >- + 'nil' cannot be assigned to type %0 + +- id: cannot_convert_subscript_assign + msg: >- + cannot assign value of type %0 to subscript of type %1 + +- id: cannot_convert_subscript_assign_protocol + msg: >- + value of type %0 does not conform to %1 in subscript assignment + +- id: cannot_convert_subscript_assign_nil + msg: >- + 'nil' cannot be assigned to subscript of type %0 + +- id: cannot_convert_candidate_result_to_contextual_type + msg: >- + %0 produces %1, not the expected contextual result type %2 + +- id: cannot_convert_sequence_element_value + msg: >- + cannot convert sequence element type %0 to expected type %1 + +- id: cannot_convert_sequence_element_protocol + msg: >- + sequence element type %0 does not conform to expected protocol %1 + +- id: throws_functiontype_mismatch + msg: >- + invalid conversion from throwing function of type %0 to non-throwing + function type %1 + +- id: expr_keypath_no_objc_runtime + msg: >- + '#keyPath' can only be used with the Objective-C runtime + +- id: expression_unused_keypath_result + msg: >- + result of key path is unused + +- id: expr_keypath_non_objc_property + msg: >- + argument of '#keyPath' refers to non-'@objc' property %0 + +- id: expr_keypath_swift3_objc_inference + msg: >- + argument of '#keyPath' refers to property %0 in %1 that depends on + '@objc' inference deprecated in Swift 4 + +- id: expr_keypath_type_of_property + msg: >- + cannot refer to type member %0 within instance of type %1 + +- id: expr_keypath_generic_type + msg: >- + key path cannot refer to generic type %0 + +- id: expr_keypath_not_property + msg: >- + %select{key path|dynamic key path member lookup}2 cannot refer to %0 %1 + +- id: expr_keypath_mutating_getter + msg: >- + %select{key path|dynamic key path member lookup}1 cannot refer to %0, + which has a mutating getter + +- id: expr_keypath_static_member + msg: >- + %select{key path|dynamic key path member lookup}1 cannot refer to static + member %0 + +- id: expr_keypath_enum_case + msg: >- + %select{key path|dynamic key path member lookup}1 cannot refer to enum + case %0 + +- id: expr_keypath_empty + msg: >- + empty key path does not refer to a property + +- id: expr_unsupported_objc_key_path_component + msg: >- + an Objective-C key path cannot contain + %select{BAD|subscript|BAD|BAD|optional-forcing|optional-chaining|BAD} + components + +- id: expr_unsupported_objc_key_path_compound_name + msg: >- + an Objective-C key path cannot reference a declaration with a compound name + +- id: expr_keypath_no_keypath_type + msg: >- + broken standard library: no 'KeyPath' type found + +- id: expr_swift_keypath_invalid_component + msg: >- + invalid component of Swift key path + +- id: expr_swift_keypath_not_starting_with_type + msg: >- + a Swift key path must begin with a type + +- id: expr_swift_keypath_not_starting_with_dot + msg: >- + a Swift key path with contextual root must begin with a leading dot + +- id: expr_smart_keypath_value_covert_to_contextual_type + msg: >- + key path value type %0 cannot be converted to contextual type %1 + +- id: expr_swift_keypath_empty + msg: >- + key path must have at least one component + +- id: expr_string_interpolation_outside_string + msg: >- + string interpolation can only appear inside a string literal + +- id: expr_keypath_subscript_index_not_hashable + msg: >- + subscript index of type %0 in a key path must be Hashable + +- id: expr_smart_keypath_application_type_mismatch + msg: >- + key path of type %0 cannot be applied to a base of type %1 + +- id: expr_keypath_root_type_mismatch + msg: >- + key path with root type %0 cannot be applied to a base of type %1 + +- id: expr_swift_keypath_anyobject_root + msg: >- + the root type of a Swift key path cannot be 'AnyObject' + +- id: expr_keypath_multiparam_func_conversion + msg: >- + cannot convert key path into a multi-argument function type %0 + +- id: expr_deprecated_writable_keypath + msg: >- + forming a writable keypath to property %0 that is read-only in this + context is deprecated and will be removed in a future release + +- id: expr_selector_no_objc_runtime + msg: >- + '#selector' can only be used with the Objective-C runtime + +- id: expr_selector_module_missing + msg: >- + import the 'ObjectiveC' module to use '#selector' + +- id: expr_selector_no_declaration + msg: >- + argument of '#selector' does not refer to an '@objc' method, property, or + initializer + +- id: expr_selector_not_method + msg: >- + argument of '#selector' cannot refer to %select{local|global}0 function %1 + +- id: expr_selector_expected_property + msg: >- + cannot reference %1 %2 as a property; remove '%select{getter|setter}0:' + +- id: expr_selector_not_property + msg: >- + argument of '#selector' cannot refer to %select{variable|parameter}0 %1 + +- id: expr_selector_expected_method + msg: >- + use 'getter:'%select{| or 'setter:'}0 to refer to the Objective-C + getter%select{| or setter}0 of property %1%select{|, respectively}0 + +- id: expr_selector_add_modifier + msg: >- + add '%select{getter|setter}0:' to reference the Objective-C + %select{getter|setter}0 for %1 + +- id: expr_selector_property_not_settable + msg: >- + argument of '#selector(setter:)' refers to non-settable %0 %1 + +- id: expr_selector_property_setter_inaccessible + msg: >- + setter of %0 %1 is inaccessible + +- id: expr_selector_cannot_be_used + msg: >- + cannot use %0 as a selector because protocol %1 is not exposed to + Objective-C + +- id: expr_selector_not_objc + msg: >- + argument of '#selector' refers to %0 %1 that is not exposed to Objective-C + +- id: make_decl_objc + msg: >- + add '@objc' to expose this %0 to Objective-C + +- id: expr_selector_swift3_objc_inference + msg: >- + argument of '#selector' refers to %0 %1 in %2 that depends on '@objc' + inference deprecated in Swift 4 + +- id: selector_literal_invalid + msg: >- + string literal is not a valid Objective-C selector + +- id: selector_literal_undeclared + msg: >- + no method declared with Objective-C selector %0 + +- id: selector_literal_deprecated + msg: >- + use of string literal for Objective-C selectors is deprecated; use + '#selector' or explicitly construct a 'Selector' + +- id: selector_literal_deprecated_suggest + msg: >- + use of string literal for Objective-C selectors is deprecated; use + '#selector' instead + +- id: selector_construction_suggest + msg: >- + use '#selector' instead of explicitly constructing a 'Selector' + +- id: selector_construction_suppress_warning + msg: >- + wrap the selector name in parentheses to suppress this warning + +- id: cannot_return_value_from_void_func + msg: >- + unexpected non-void return value in void function + +- id: add_return_type_note + msg: >- + did you mean to add a return type? + +- id: sema_no_import + msg: >- + no such module '%0' + +- id: sema_no_import_target + msg: >- + could not find module '%0' for target '%1'; found: %2 + +- id: sema_no_import_repl + msg: >- + no such module '%0' + +- id: sema_no_import_no_sdk + msg: >- + did you forget to set an SDK using -sdk or SDKROOT? + +- id: sema_no_import_no_sdk_xcrun + msg: >- + use "xcrun swiftc" to select the default macOS SDK installed with Xcode + +- id: sema_import_current_module + msg: >- + this file is part of module %0; ignoring import + +- id: sema_import_current_module_with_file + msg: >- + file '%0' is part of module %1; ignoring import + +- id: sema_opening_import + msg: >- + opening import file for module %0: %1 + +- id: serialization_load_failed + msg: >- + failed to load module '%0' + +- id: module_interface_build_failed + msg: >- + failed to build module '%0' from its module interface; %select{the + compiler that produced it, '%2', may have used features that aren't + supported by this compiler, '%3'|it may have been damaged + or it may have triggered a bug in the Swift compiler when it was produced}1 + +- id: serialization_malformed_module + msg: >- + malformed compiled module: %0 + +- id: serialization_module_too_new + msg: >- + compiled module was created by a newer version of the compiler: %0 + +- id: serialization_module_language_version_mismatch + msg: >- + module compiled with Swift %0 cannot be imported by the Swift %1 + compiler: %2 + +- id: serialization_module_too_old + msg: >- + compiled module was created by an older version of the compiler; rebuild + %0 and try again: %1 + +- id: serialization_missing_single_dependency + msg: >- + missing required module '%0' + +- id: serialization_missing_dependencies + msg: >- + missing required modules: %0 + +- id: serialization_circular_dependency + msg: >- + circular dependency between modules '%0' and %1 + +- id: serialization_missing_underlying_module + msg: >- + cannot load underlying module for %0 + +- id: serialization_name_mismatch + msg: >- + cannot load module '%0' as '%1' + +- id: serialization_name_mismatch_repl + msg: >- + cannot load module '%0' as '%1' + +- id: serialization_target_incompatible + msg: >- + module %0 was created for incompatible target %1: %2 + +- id: serialization_target_incompatible_repl + msg: >- + module %0 was created for incompatible target %1: %2 + +- id: serialization_target_too_new + msg: >- + compiling for %0 %1, but module %2 has a minimum deployment target of %0 + %3: %4 + +- id: serialization_target_too_new_repl + msg: >- + compiling for %0 %1, but module %2 has a minimum deployment target of %0 + %3: %4 + +- id: serialization_fatal + msg: >- + fatal error encountered while reading from module '%0'; please file a bug + report with your project and the crash log + +- id: serialization_misc_version + msg: >- + module '%0' full misc version is '%1' + +- id: serialization_compatibility_version_mismatch + msg: >- + compiling as Swift %0, with '%1' built as Swift %2 (this is supported but + may expose additional compiler issues) + +- id: reserved_member_name + msg: >- + type member must not be named %0, since it would conflict with the + 'foo.%1' expression + +- id: invalid_redecl + msg: >- + invalid redeclaration of %0 + +- id: invalid_redecl_init + msg: >- + invalid redeclaration of synthesized %select{|memberwise }1%0 + +- id: invalid_redecl_implicit + msg: >- + invalid redeclaration of synthesized %select{%0|implementation for + protocol requirement}1 %2 + +- id: invalid_redecl_swift5_warning + msg: >- + redeclaration of %0 is deprecated and will be an error in Swift 5 + +- id: invalid_redecl_prev + msg: >- + %0 previously declared here + +- id: invalid_redecl_implicit_wrapper + msg: >- + %0 synthesized for property wrapper %select{projected value|backing + storage}1 + +- id: ambiguous_type_base + msg: >- + %0 is ambiguous for type lookup in this context + +- id: invalid_member_type + msg: >- + %0 is not a member type of %1 + +- id: invalid_member_type_suggest + msg: >- + %0 does not have a member type named %1; did you mean %2? + +- id: invalid_member_reference + msg: >- + %0 %1 is not a member type of %2 + +- id: ambiguous_member_type + msg: >- + ambiguous type name %0 in %1 + +- id: no_module_type + msg: >- + no type named %0 in module %1 + +- id: ambiguous_module_type + msg: >- + ambiguous type name %0 in module %1 + +- id: use_nonmatching_operator + msg: >- + %0 is not a %select{binary|prefix unary|postfix unary}1 operator + +- id: unsupported_recursion_in_associated_type_reference + msg: >- + unsupported recursion for reference to %select{associated type|type + alias}0 %1 of type %2 + +- id: broken_associated_type_witness + msg: >- + reference to invalid %select{associated type|type alias}0 %1 of type %2 + +- id: unspaced_binary_operator_fixit + msg: >- + missing whitespace between %0 and %1 operators + +- id: unspaced_binary_operator + msg: >- + ambiguous missing whitespace between unary and binary operators + +- id: unspaced_binary_operators_candidate + msg: >- + could be %select{binary|postfix}2 %0 and %select{prefix|binary}2 %1 + +- id: unspaced_unary_operator + msg: >- + unary operators must not be juxtaposed; parenthesize inner expression + +- id: cannot_find_in_scope + msg: >- + cannot %select{find|find operator}1 %0 in scope + +- id: cannot_find_in_scope_corrected + msg: >- + cannot %select{find|find operator}1 %0 in scope; did you mean '%2'? + +- id: confusable_character + msg: >- + %select{identifier|operator}0 '%1' contains possibly confused characters; + did you mean to use '%2'? + +- id: cannot_find_type_in_scope + msg: >- + cannot find type %0 in scope + +- id: cannot_find_type_in_scope_did_you_mean + msg: >- + cannot find type %0 in scope; did you mean to use '%1'? + +- id: note_typo_candidate_implicit_member + msg: >- + did you mean the implicitly-synthesized %1 '%0'? + +- id: note_remapped_type + msg: >- + did you mean to use '%0'? + +- id: note_module_as_type + msg: >- + cannot use module %0 as a type + +- id: use_unknown_object_literal_protocol + msg: >- + cannot deduce protocol for %0 literal + +- id: object_literal_default_type_missing + msg: >- + could not infer type of %0 literal + +- id: object_literal_resolve_import + msg: >- + import %0 to use '%1' as the default %2 literal type + +- id: use_local_before_declaration + msg: >- + use of local variable %0 before its declaration + +- id: unsupported_existential_type + msg: >- + protocol %0 can only be used as a generic constraint because it has Self + or associated type requirements + +- id: decl_does_not_exist_in_module + msg: >- + %select{%error|type|struct|class|enum|protocol|variable|function}0 %1 + does not exist in module %2 + +- id: imported_decl_is_wrong_kind + msg: >- + %0 was imported as '%1', but is %select{%error|a type|a struct|a class|an + enum|a protocol|a variable|a function}2 + +- id: imported_decl_is_wrong_kind_typealias + msg: >- + %0 %1 cannot be imported as '%2' + +- id: ambiguous_decl_in_module + msg: >- + ambiguous name %0 in module %1 + +- id: module_not_testable + msg: >- + module %0 was not compiled for testing + +- id: module_not_compiled_for_private_import + msg: >- + module %0 was not compiled for private import + +- id: import_implementation_cannot_be_exported + msg: >- + module %0 cannot be both exported and implementation-only + +- id: module_not_compiled_with_library_evolution + msg: >- + module %0 was not compiled with library evolution support; using it means + binary compatibility for %1 can't be guaranteed + +- id: cross_import_added + msg: >- + import of %0 and %1 triggered a cross-import of %2 + +- id: ambiguous_operator_decls + msg: >- + ambiguous operator declarations found for operator + +- id: found_this_operator_decl + msg: >- + found this matching operator declaration + +- id: operator_redeclared + msg: >- + operator redeclared + +- id: previous_operator_decl + msg: >- + previous operator declaration here + +- id: declared_operator_without_operator_decl + msg: >- + operator implementation without matching operator declaration + +- id: declared_unary_op_without_attribute + msg: >- + unary operator implementation must have a 'prefix' or 'postfix' modifier + +- id: unary_op_missing_prepos_attribute + msg: >- + %select{prefix|postfix}0 unary operator missing + '%select{prefix|postfix}0' modifier + +- id: unary_operator_declaration_here + msg: >- + %select{prefix|postfix}0 operator found here + +- id: invalid_arg_count_for_operator + msg: >- + operators must have one or two arguments + +- id: operator_in_local_scope + msg: >- + operator functions can only be declared at global or in type scope + +- id: nonstatic_operator_in_nominal + msg: >- + operator %0 declared in type %1 must be 'static' + +- id: nonstatic_operator_in_extension + msg: >- + operator %0 declared in extension%select{| of %2}1 must be 'static' + +- id: nonfinal_operator_in_class + msg: >- + operator %0 declared in non-final class %1 must be 'final' + +- id: operator_in_unrelated_type + msg: >- + member operator %2%select{| of protocol %0}1 must have at least one + argument of type %select{%0|'Self'}1 + +- id: ambiguous_precedence_groups + msg: >- + multiple precedence groups found + +- id: found_this_precedence_group + msg: >- + found this matching precedence group + +- id: unknown_precedence_group + msg: >- + unknown precedence group %0 + +- id: precedence_group_cycle + msg: >- + cycle in '%select{lowerThan|higherThan}0' relation + +- id: higher_than_precedence_group_cycle + msg: >- + cycle in higherThan relation: %0 + +- id: precedence_group_lower_within_module + msg: >- + precedence group cannot be given lower precedence than group in same + module; make the other precedence group higher than this one instead + +- id: precedence_group_redeclared + msg: >- + precedence group redeclared + +- id: previous_precedence_group_decl + msg: >- + previous precedence group declaration here + +- id: circular_reference_through_precedence_group + msg: >- + through reference to precedence group %0 here + +- id: tuple_types_not_convertible_nelts + msg: >- + %0 is not convertible to %1, tuples have a different number of elements + +- id: tuple_types_not_convertible + msg: >- + tuple type %0 is not convertible to tuple type %1 + +- id: invalid_force_unwrap + msg: >- + cannot force unwrap value of non-optional type %0 + +- id: invalid_optional_chain + msg: >- + cannot use optional chaining on non-optional value of type %0 + +- id: if_expr_cases_mismatch + msg: >- + result values in '? :' expression have mismatching types %0 and %1 + +- id: did_not_call_function_value + msg: >- + function value was used as a property; add () to call it + +- id: did_not_call_function + msg: >- + function %0 was used as a property; add () to call it + +- id: did_not_call_method + msg: >- + method %0 was used as a property; add () to call it + +- id: init_not_instance_member_use_assignment + msg: >- + 'init' is a member of the type; use assignment to initalize the value + instead + +- id: init_not_instance_member + msg: >- + 'init' is a member of the type; use 'type(of: ...)' to initialize a new + object of the same dynamic type + +- id: super_initializer_not_in_initializer + msg: >- + 'super.init' cannot be called outside of an initializer + +- id: isa_is_always_true + msg: >- + '%0' test is always true + +- id: isa_is_foreign_check + msg: >- + 'is' test is always true because %0 is a Core Foundation type + +- id: conditional_downcast_coercion + msg: >- + conditional cast from %0 to %1 always succeeds + +- id: literal_conditional_downcast_to_coercion + msg: >- + conditional downcast from literal to %0 always fails; consider using 'as' + coercion + +- id: forced_downcast_noop + msg: >- + forced cast of %0 to same type has no effect + +- id: forced_downcast_coercion + msg: >- + forced cast from %0 to %1 always succeeds; did you mean to use 'as'? + +- id: downcast_same_type + msg: >- + forced cast from %0 to %1 %select{only unwraps optionals|only unwraps and + bridges}3; did you mean to use '%2'%select{| with 'as'}3? + +- id: conditional_downcast_same_type + msg: >- + conditional downcast from %0 to %1 %select{does nothing|is equivalent to + an implicit conversion to an optional %1|is a bridging conversion; + did you mean to use 'as'?}2 + +- id: is_expr_same_type + msg: >- + checking a value with optional type %0 against dynamic type %1 succeeds + whenever the value is non-nil; did you mean to use '!= nil'? + +- id: downcast_to_unrelated + msg: >- + cast from %0 to unrelated type %1 always fails + +- id: downcast_to_unrelated_fixit + msg: >- + did you mean to call %0 with '()'? + +- id: downcast_to_more_optional + msg: >- + cannot downcast from %0 to a more optional type %1 + +- id: optional_chain_noop + msg: >- + optional chain has no effect, expression already produces %0 + +- id: optional_chain_isnt_chaining + msg: >- + '?' must be followed by a call, member lookup, or subscript + +- id: pattern_in_expr + msg: >- + %0 cannot appear in an expression + +- id: note_call_to_operator + msg: >- + in call to operator %0 + +- id: note_call_to_func + msg: >- + in call to function %0 + +- id: note_call_to_subscript + msg: >- + in call to %0 + +- id: note_call_to_initializer + msg: >- + in call to initializer + +- id: note_init_parameter + msg: >- + in initialization of parameter %0 + +- id: missing_nullary_call + msg: >- + function produces expected type %0; did you mean to call it with '()'? + +- id: optional_not_unwrapped + msg: >- + value of optional type %0 must be unwrapped to a value of type %1 + +- id: unwrap_with_default_value + msg: >- + coalesce using '??' to provide a default when the optional value contains + 'nil' + +- id: unwrap_with_force_value + msg: >- + force-unwrap using '!' to abort execution if the optional value contains + 'nil' + +- id: unwrap_iuo_initializer + msg: >- + value inferred to be type %0 when initialized with an implicitly + unwrapped value + +- id: unwrap_with_guard + msg: >- + short-circuit using 'guard' to exit this function early if the optional + value contains 'nil' + +- id: optional_base_not_unwrapped + msg: >- + value of optional type %0 must be unwrapped to refer to member %1 of + wrapped base type %2 + +- id: optional_base_chain + msg: >- + chain the optional using '?' to access member %0 only for non-'nil' base + values + +- id: optional_base_remove_optional_for_keypath_root + msg: >- + use unwrapped type %0 as key path root + +- id: missing_unwrap_optional_try + msg: >- + value of optional type %0 not unwrapped; did you mean to use 'try!' or + chain with '?'? + +- id: missing_forced_downcast + msg: >- + %0 is not convertible to %1; did you mean to use 'as!' to force downcast? + +- id: coercion_may_fail_warning + msg: >- + coercion from %0 to %1 may fail; use 'as?' or 'as!' instead + +- id: missing_explicit_conversion + msg: >- + %0 is not implicitly convertible to %1; did you mean to use 'as' to + explicitly convert? + +- id: missing_address_of + msg: >- + passing value of type %0 to an inout parameter requires explicit '&' + +- id: missing_address_of_yield + msg: >- + yielding mutable value of type %0 requires explicit '&' + +- id: extraneous_address_of + msg: >- + use of extraneous '&' + +- id: extra_address_of + msg: >- + '&' used with non-inout argument of type %0 + +- id: extra_address_of_unsafepointer + msg: >- + '&' is not allowed passing array value as %0 argument + +- id: cannot_pass_inout_arg_to_subscript + msg: >- + cannot pass an inout argument to a subscript; use + 'withUnsafeMutablePointer' to explicitly convert argument to a pointer + +- id: incorrect_property_wrapper_reference + msg: >- + cannot convert value %0 of type %1 to expected type %2, use + %select{wrapper|wrapped value}3 instead + +- id: incorrect_property_wrapper_reference_member + msg: >- + referencing %0 %1 requires %select{wrapper|wrapped value of type}2 %3 + +- id: missing_init_on_metatype_initialization + msg: >- + initializing from a metatype value must reference 'init' explicitly + +- id: extra_argument_labels + msg: >- + extraneous argument label%select{|s}0 '%1' in %select{call|subscript}2 + +- id: missing_argument_labels + msg: >- + missing argument label%select{|s}0 '%1' in %select{call|subscript}2 + +- id: wrong_argument_labels + msg: >- + incorrect argument label%select{|s}0 in %select{call|subscript}3 (have + '%1', expected '%2') + +- id: argument_out_of_order_named_named + msg: >- + argument %0 must precede argument %1 + +- id: argument_out_of_order_named_unnamed + msg: >- + argument %0 must precede unnamed argument #%1 + +- id: argument_out_of_order_unnamed_named + msg: >- + unnamed argument #%0 must precede argument %1 + +- id: argument_out_of_order_unnamed_unnamed + msg: >- + unnamed argument #%0 must precede unnamed argument #%1 + +- id: argument_out_of_order_binary_op + msg: >- + operator argument #%0 must precede operator argument #%1 + +- id: candidate_expected_different_labels + msg: >- + incorrect labels for candidate (have: '%0', expected: '%1') + +- id: member_shadows_function + msg: >- + use of %0 refers to %1 rather than %2 %3 + +- id: member_shadows_global_function + msg: >- + use of %0 refers to %1 rather than %2 %3 in module %4 + +- id: instance_member_use_on_type + msg: >- + instance member %1 cannot be used on type %0; did you mean to use a value + of this type instead? + +- id: instance_member_in_initializer + msg: >- + cannot use instance member %0 within property initializer; property + initializers run before 'self' is available + +- id: instance_member_in_default_parameter + msg: >- + cannot use instance member %0 as a default parameter + +- id: missing_argument_named + msg: >- + missing argument for parameter %0 in call + +- id: missing_argument_positional + msg: >- + missing argument for parameter #%0 in call + +- id: missing_arguments_in_call + msg: >- + missing arguments for parameters %0 in call + +- id: extra_argument_named + msg: >- + extra argument %0 in call + +- id: extra_argument_positional + msg: >- + extra argument in call + +- id: extra_arguments_in_call + msg: >- + extra arguments at positions %0 in call + +- id: extra_argument_to_nullary_call + msg: >- + argument passed to call that takes no arguments + +- id: extra_trailing_closure_in_call + msg: >- + extra trailing closure passed in call + +- id: trailing_closure_bad_param + msg: >- + trailing closure passed to parameter of type %0 that does not accept a + closure + +- id: candidate_with_extraneous_args + msg: >- + candidate %0 requires %1 argument%s1, but %2 %select{were|was}3 + %select{provided|used in closure body}4 + +- id: no_accessible_initializers + msg: >- + %0 cannot be constructed because it has no accessible initializers + +- id: non_nominal_no_initializers + msg: >- + non-nominal type %0 does not support explicit initialization + +- id: unbound_generic_parameter + msg: >- + generic parameter %0 could not be inferred + +- id: unbound_generic_parameter_cast + msg: >- + generic parameter %0 could not be inferred in cast to %1 + +- id: archetype_declared_in_type + msg: >- + %0 declared as parameter to type %1 + +- id: unbound_generic_parameter_explicit_fix + msg: >- + explicitly specify the generic arguments to fix this issue + +- id: invalid_dynamic_callable_type + msg: >- + @dynamicCallable attribute requires %0 to have either a valid + 'dynamicallyCall(withArguments:)' method or + 'dynamicallyCall(withKeywordArguments:)' method + +- id: missing_dynamic_callable_kwargs_method + msg: >- + @dynamicCallable type %0 cannot be applied with keyword arguments; + missing 'dynamicCall(withKeywordArguments:)' method + +- id: invalid_dynamic_member_lookup_type + msg: >- + @dynamicMemberLookup attribute requires %0 to have a + 'subscript(dynamicMember:)' method that accepts either + 'ExpressibleByStringLiteral' or a key path + +- id: invalid_dynamic_member_subscript + msg: >- + add an explicit argument label to this subscript to satisfy the + @dynamicMemberLookup requirement + +- id: string_index_not_integer + msg: >- + String must not be indexed with %0, it has variable size elements + +- id: string_index_not_integer_note + msg: >- + consider using an existing high level algorithm, + str.startIndex.advanced(by: n), or a projection like str.utf8 + +- id: invalid_c_function_pointer_conversion_expr + msg: >- + a C function pointer can only be formed from a reference to a 'func' or a + literal closure + +- id: c_function_pointer_from_method + msg: >- + a C function pointer cannot be formed from a method + +- id: c_function_pointer_from_generic_function + msg: >- + a C function pointer cannot be formed from a reference to a generic + function + +- id: unsupported_linear_to_differentiable_conversion + msg: >- + conversion from '@differentiable(linear)' to '@differentiable' is not yet + supported + +- id: invalid_autoclosure_forwarding + msg: >- + add () to forward @autoclosure parameter + +- id: invalid_differentiable_function_conversion_expr + msg: >- + a '@differentiable%select{|(linear)}0' function can only be formed from a + reference to a 'func' or 'init' or a literal closure + +- id: invalid_differentiable_function_conversion_parameter + msg: >- + did you mean to take a '%0' closure? + +- id: invalid_autoclosure_pointer_conversion + msg: >- + cannot perform pointer conversion of value of type %0 to autoclosure + result type %1 + +- id: missing_initializer_def + msg: >- + initializer requires a body + +- id: pound_warning + msg: >- + %0 + +- id: pound_error + msg: >- + %0 + +- id: operator_not_func + msg: >- + operators must be declared with 'func' + +- id: redefining_builtin_operator + msg: >- + cannot declare a custom %0 '%1' operator + +- id: attribute_requires_operator_identifier + msg: >- + '%0' requires a function with an operator identifier + +- id: attribute_requires_single_argument + msg: >- + '%0' requires a function with one argument + +- id: nominal_type_not_attribute + msg: >- + %0 %1 cannot be used as an attribute + +- id: mutating_invalid_global_scope + msg: >- + %0 is only valid on methods + +- id: mutating_invalid_classes + msg: >- + %0 isn't valid on methods in classes or class-bound protocols + +- id: functions_mutating_and_not + msg: >- + method must not be declared both %0 and %1 + +- id: static_functions_not_mutating + msg: >- + static functions must not be declared mutating + +- id: modify_mutatingness_differs_from_setter + msg: >- + 'modify' accessor cannot be %0 when the setter is %1 + +- id: transparent_in_protocols_not_supported + msg: >- + '@_transparent' attribute is not supported on declarations within + protocols + +- id: transparent_in_classes_not_supported + msg: >- + '@_transparent' attribute is not supported on declarations within classes + +- id: invalid_iboutlet + msg: >- + only instance properties can be declared @IBOutlet + +- id: iboutlet_nonobjc_class + msg: >- + @IBOutlet property cannot %select{have|be an array of}0 non-'@objc' class + type %1 + +- id: iboutlet_nonobjc_protocol + msg: >- + @IBOutlet property cannot %select{have|be an array of}0 non-'@objc' + protocol type %1 + +- id: iboutlet_nonobject_type + msg: >- + @IBOutlet property cannot %select{have|be an array of}0 non-object type %1 + +- id: iboutlet_only_mutable + msg: >- + @IBOutlet attribute requires property to be mutable + +- id: iboutlet_non_optional + msg: >- + @IBOutlet property has non-optional type %0 + +- id: note_make_optional + msg: >- + add '?' to form the optional type %0 + +- id: note_make_implicitly_unwrapped_optional + msg: >- + add '!' to form an implicitly unwrapped optional + +- id: invalid_ibdesignable_extension + msg: >- + @IBDesignable can only be applied to classes and extensions of classes + +- id: invalid_ibinspectable + msg: >- + only instance properties can be declared @%0 + +- id: invalid_ibaction_decl + msg: >- + only instance methods can be declared @%0 + +- id: invalid_ibaction_result + msg: >- + methods declared @%0 must %select{|not }1return a value + +- id: invalid_ibaction_argument_count + msg: >- + @%0 methods must have %1 to %2 arguments + +- id: invalid_ibaction_argument_count_exact + msg: >- + @%0 methods must have %2 argument%s2 + +- id: invalid_ibaction_argument_count_max + msg: >- + @%0 methods must have at most %2 argument%s2 + +- id: ibsegueaction_objc_method_family + msg: >- + @%0 method cannot have selector %1 because it has special memory + management behavior + +- id: fixit_rename_in_swift + msg: >- + change Swift name to %0 + +- id: fixit_rename_in_objc + msg: >- + change Objective-C selector to %0 + +- id: no_objc_tagged_pointer_not_class_protocol + msg: >- + @unsafe_no_objc_tagged_pointer can only be applied to class protocols + +- id: swift_native_objc_runtime_base_not_on_root_class + msg: >- + @_swift_native_objc_runtime_base_not_on_root_class can only be applied to + root classes + +- id: cdecl_not_at_top_level + msg: >- + @_cdecl can only be applied to global functions + +- id: cdecl_empty_name + msg: >- + @_cdecl symbol name cannot be empty + +- id: cdecl_throws + msg: >- + raising errors from @_cdecl functions is not supported + +- id: attr_methods_only + msg: >- + only methods can be declared %0 + +- id: access_control_in_protocol + msg: >- + %0 modifier cannot be used in protocols + +- id: access_control_in_protocol_detail + msg: >- + protocol requirements implicitly have the same access as the protocol + itself + +- id: access_control_setter + msg: >- + '%select{private|fileprivate|internal|public|open}0(set)' modifier can + only be applied to variables and subscripts + +- id: access_control_setter_read_only + msg: >- + '%select{private|fileprivate|internal|public|%error}0(set)' modifier + cannot be applied to %select{constants|read-only variables|read-only + properties|read-only subscripts}1 + +- id: access_control_setter_more + msg: >- + %select{private|fileprivate|internal|public|%error}0 + %select{variable|property|subscript}1 cannot have %select{%error|a + fileprivate|an internal|a public|an open}2 setter + +- id: access_control_setter_redundant + msg: >- + '%select{private|fileprivate|internal|public|open}0(set)' modifier is + redundant for + %select{a private|a fileprivate|an internal|a public|an open}2 %1 + +- id: access_control_ext_member_more + msg: >- + '%select{%error|fileprivate|internal|public|open}0' modifier conflicts + with extension's default access of + '%select{private|fileprivate|internal|public|%error}1' + +- id: access_control_ext_member_redundant + msg: >- + '%select{%error|fileprivate|internal|public|%error}0' modifier is + redundant for %1 declared in %select{a private (equivalent to fileprivate)|a + fileprivate|an internal|a public|%error}2 extension + +- id: access_control_ext_requirement_member_more + msg: >- + cannot declare %select{%error|a fileprivate|an internal|a public|an + open}0 %1 in an extension with + %select{private|fileprivate|internal|public|%error}2 requirements + +- id: access_control_extension_more + msg: >- + extension of %select{private|fileprivate|internal|%error|%error}0 %1 + cannot be declared %select{%error|fileprivate|internal|public|%error}2 + +- id: access_control_extension_open + msg: >- + extensions cannot use 'open' as their default access; use 'public' + +- id: access_control_open_bad_decl + msg: >- + only classes and overridable class members can be declared 'open'; use + 'public' + +- id: invalid_decl_attribute + msg: >- + '%0' attribute cannot be applied to this declaration + +- id: invalid_decl_modifier + msg: >- + %0 modifier cannot be applied to this declaration + +- id: attribute_does_not_apply_to_type + msg: >- + attribute does not apply to type + +- id: optional_attribute_non_protocol + msg: >- + 'optional' can only be applied to protocol members + +- id: optional_attribute_non_objc_protocol + msg: >- + 'optional' can only be applied to members of an @objc protocol + +- id: optional_attribute_missing_explicit_objc + msg: >- + 'optional' requirements are an Objective-C compatibility feature; add + '@objc' + +- id: objcmembers_attribute_nonclass + msg: >- + '@objcMembers' attribute can only be applied to a class + +- id: optional_attribute_initializer + msg: >- + 'optional' cannot be applied to an initializer + +- id: unavailable_method_non_objc_protocol + msg: >- + protocol members can only be marked unavailable in an @objc protocol + +- id: missing_in_class_init_1 + msg: >- + stored property %0 requires an initial value%select{| or should be + @NSManaged}1 + +- id: missing_in_class_init_2 + msg: >- + stored properties %0 and %1 require initial values%select{| or should be + @NSManaged}2 + +- id: missing_in_class_init_3plus + msg: >- + stored properties %0, %1, %select{and %2|%2, and others}3 require initial + values%select{| or should be @NSManaged}4 + +- id: requires_stored_property_inits_here + msg: >- + %select{superclass|class}1 %0 requires all stored properties to have + initial values%select{| or use @NSManaged}2 + +- id: class_without_init + msg: >- + class %0 has no initializers + +- id: note_no_in_class_init_1 + msg: >- + stored property %0 without initial value prevents synthesized + initializers + +- id: note_no_in_class_init_2 + msg: >- + stored properties %0 and %1 without initial values prevent synthesized + initializers + +- id: note_no_in_class_init_3plus + msg: >- + stored properties %0, %1, %select{and %2|%2, and others}3 without initial + values prevent synthesized initializers + +- id: missing_unimplemented_init_runtime + msg: >- + standard library error: missing _unimplementedInitializer + +- id: missing_undefined_runtime + msg: >- + standard library error: missing _undefined + +- id: expr_dynamic_lookup_swift3_objc_inference + msg: >- + reference to %0 %1 of %2 depends on '@objc' inference deprecated in Swift 4 + +- id: inherited_default_value_not_in_designated_constructor + msg: >- + default value inheritance via 'super' is only valid on the parameters of + designated initializers + +- id: inherited_default_value_used_in_non_overriding_constructor + msg: >- + default value inheritance via 'super' can only be used when overriding a + designated initializer + +- id: corresponding_param_not_defaulted + msg: >- + default value inheritance via 'super' requires that the corresponding + parameter of the overridden designated initializer has a default value + +- id: inherited_default_param_here + msg: >- + corresponding parameter declared here + +- id: option_set_zero_constant + msg: >- + static property %0 produces an empty option set + +- id: option_set_empty_set_init + msg: >- + use [] to silence this warning + +- id: originally_defined_in_dupe_platform + msg: >- + duplicate version number for platform %0 + +- id: originally_definedin_topleve_decl + msg: >- + @%0 is only applicable to top-level decl + +- id: originally_definedin_need_available + msg: >- + need @available attribute for @%0 + +- id: originally_definedin_must_after_available_version + msg: >- + moved version from @%0 must after introduced OS version + +- id: alignment_not_power_of_two + msg: >- + alignment value must be a power of two + +- id: indirect_case_without_payload + msg: >- + enum case %0 without associated value cannot be 'indirect' + +- id: indirect_case_in_indirect_enum + msg: >- + enum case in 'indirect' enum cannot also be 'indirect' + +- id: enum_frozen_nonpublic + msg: >- + %0 has no effect on non-public enums + +- id: getset_init + msg: >- + variable with getter/setter cannot have an initial value + +- id: unimplemented_static_var + msg: >- + %select{ERROR|static|class}1 stored properties not supported%select{ in + this context| in generic types| in classes| + in protocol extensions}0%select{|; did you mean 'static'?}2 + +- id: observingprop_requires_initializer + msg: >- + non-member observing properties require an initializer + +- id: global_requires_initializer + msg: >- + global '%select{var|let}0' declaration requires an initializer + expression%select{ or getter/setter specifier|}0 + +- id: static_requires_initializer + msg: >- + %select{ERROR|'static var'|'class var'|}0 declaration requires an + initializer expression or getter/setter specifier + +- id: pattern_type_access + msg: >- + %select{%select{variable|constant}0|property}1 %select{must be declared + %select{%select{private|fileprivate|internal|%error|%error}3|private or + fileprivate}4|cannot be declared %select{in this + context|fileprivate|internal|public|open}3}2 because its type uses %select{a + private|a fileprivate|an internal|%error|%error}5 type + +- id: pattern_type_access_warn + msg: >- + %select{%select{variable|constant}0|property}1 %select{should be declared + %select{private|fileprivate|internal|%error|%error}5|should not be declared + %select{in this context|fileprivate|internal|public|open}3}2 because its + type uses %select{a private|a fileprivate|an internal|%error|%error}5 type + +- id: pattern_type_access_inferred + msg: >- + %select{%select{variable|constant}0|property}1 %select{must be declared + %select{%select{private|fileprivate|internal|%error|%error}3|private or + fileprivate}4|cannot be declared %select{in this + context|fileprivate|internal|public|open}3}2 because its type %6 + uses %select{a private|a fileprivate|an internal|%error|%error}5 type + +- id: pattern_type_access_inferred_warn + msg: >- + %select{%select{variable|constant}0|property}1 %select{should be declared + %select{private|fileprivate|internal|%error|%error}5|should not be declared + %select{in this context|fileprivate|internal|public|open}3}2 because its + type %6 uses + %select{a private|a fileprivate|an internal|%error|%error}5 type + +- id: pattern_type_not_usable_from_inline + msg: >- + type referenced from a '@usableFromInline' + %select{%select{variable|constant}0|property}1 must be '@usableFromInline' + or public + +- id: pattern_type_not_usable_from_inline_warn + msg: >- + type referenced from a '@usableFromInline' + %select{%select{variable|constant}0|property}1 should be '@usableFromInline' + or public + +- id: pattern_type_not_usable_from_inline_frozen + msg: >- + type referenced from a stored property in a '@frozen' struct must be + '@usableFromInline' or public + +- id: pattern_type_not_usable_from_inline_inferred + msg: >- + type referenced from a '@usableFromInline' + %select{%select{variable|constant}0|property}1 with inferred type %2 must be + '@usableFromInline' or public + +- id: pattern_type_not_usable_from_inline_inferred_warn + msg: >- + type referenced from a '@usableFromInline' + %select{%select{variable|constant}0|property}1 with inferred type %2 should + be '@usableFromInline' or public + +- id: pattern_type_not_usable_from_inline_inferred_frozen + msg: >- + type referenced from a stored property with inferred type %2 in a + '@frozen' struct must be '@usableFromInline' or public + +- id: pattern_binds_no_variables + msg: >- + %select{property|global variable}0 declaration does not bind any + variables + +- id: variable_bound_by_no_pattern + msg: >- + variable %0 is not bound by any pattern + +- id: optional_ambiguous_case_ref + msg: >- + assuming you mean '%0.%2'; did you mean '%1.%2' instead? + +- id: optional_fixit_ambiguous_case_ref + msg: >- + explicitly specify 'Optional' to silence this warning + +- id: optional_fixit_ambiguous_case_ref_switch + msg: >- + use 'nil' to silence this warning + +- id: type_fixit_optional_ambiguous_case_ref + msg: >- + use '%0.%1' instead + +- id: type_fixit_optional_ambiguous_case_ref_switch + msg: >- + use '%0' instead + +- id: nscoding_unstable_mangled_name + msg: >- + %select{private|fileprivate|nested|local}0 class %1 has an unstable name + when archiving via 'NSCoding' + +- id: unstable_mangled_name_add_objc_new + msg: >- + for new classes, use '@objc' to specify a unique, prefixed Objective-C + runtime name + +- id: unstable_mangled_name_add_objc + msg: >- + for compatibility with existing archives, use '@objc' to record the Swift + 3 runtime name + +- id: unsupported_type_nested_in_generic_function + msg: >- + type %0 cannot be nested in generic function %1 + +- id: unsupported_type_nested_in_generic_closure + msg: >- + type %0 cannot be nested in closure in generic context + +- id: unsupported_type_nested_in_protocol + msg: >- + type %0 cannot be nested in protocol %1 + +- id: unsupported_type_nested_in_protocol_extension + msg: >- + type %0 cannot be nested in protocol extension of %1 + +- id: unsupported_nested_protocol + msg: >- + protocol %0 cannot be nested inside another declaration + +- id: where_nongeneric_ctx + msg: >- + 'where' clause on non-generic member declaration requires a generic + context + +- id: where_nongeneric_toplevel + msg: >- + 'where' clause cannot be applied to a non-generic top-level declaration + +- id: type_alias_underlying_type_access + msg: >- + type alias %select{must be declared + %select{%select{private|fileprivate|internal|%error|%error}1|private or + fileprivate}3|cannot be declared %select{in this + context|fileprivate|internal|public|open}1}0 because its underlying type + uses %select{a private|a fileprivate|an internal|%error|%error}2 type + +- id: type_alias_underlying_type_access_warn + msg: >- + type alias %select{should be declared + %select{private|fileprivate|internal|%error|%error}1|should not be declared + %select{in this context|fileprivate|internal|public|open}1}0 because its + underlying type uses + %select{a private|a fileprivate|an internal|%error|%error}2 type + +- id: type_alias_underlying_type_not_usable_from_inline + msg: >- + type referenced from the underlying type of a '@usableFromInline' type + alias must be '@usableFromInline' or public + +- id: type_alias_underlying_type_not_usable_from_inline_warn + msg: >- + type referenced from the underlying type of a '@usableFromInline' type + alias should be '@usableFromInline' or public + +- id: subscript_type_access + msg: >- + subscript %select{must be declared + %select{private|fileprivate|internal|%error|%error}1|cannot be declared + %select{in this context|fileprivate|internal|public|open}1}0 because its + %select{index|element type}3 uses %select{a private|a fileprivate|an + internal|%error|%error}2 type + +- id: subscript_type_access_warn + msg: >- + subscript %select{should be declared + %select{private|fileprivate|internal|%error|%error}1|should not be declared + %select{in this context|fileprivate|internal|public|open}1}0 because its + %select{index|element type}3 uses %select{a private|a fileprivate|an + internal|%error|%error}2 type + +- id: subscript_type_usable_from_inline + msg: >- + %select{index type|element type}0 of a '@usableFromInline' subscript must + be '@usableFromInline' or public + +- id: subscript_type_usable_from_inline_warn + msg: >- + %select{index type|element type}0 of a '@usableFromInline' subscript + should be '@usableFromInline' or public + +- id: function_type_access + msg: >- + %select{function|method|initializer}4 %select{must be declared + %select{%select{private|fileprivate|internal|%error|%error}1|private or + fileprivate}2|cannot be declared %select{in this + context|fileprivate|internal|public|open}1}0 because its + %select{parameter|result}5 uses %select{a private|a fileprivate|an internal|an + '@_spi'|an '@_spi'}3 type + +- id: function_type_spi + msg: >- + %select{function|method|initializer}0 cannot be declared '@_spi' because + its %select{parameter|result}1 uses %select{a private|a fileprivate|an + internal|a public|an open}2 type%select{| that is not '@_spi'}3 + +- id: function_type_access_warn + msg: >- + %select{function|method|initializer}4 %select{should be declared + %select{private|fileprivate|internal|%error|%error}1|should not be declared + %select{in this context|fileprivate|internal|public|open}1}0 because its + %select{parameter|result}5 uses %select{a private|a fileprivate|an + internal|%error|%error}3 type + +- id: function_type_usable_from_inline + msg: >- + the %select{parameter|result}1 of a '@usableFromInline' + %select{function|method|initializer}0 must be '@usableFromInline' or public + +- id: function_type_usable_from_inline_warn + msg: >- + the %select{parameter|result}1 of a '@usableFromInline' + %select{function|method|initializer}0 should be '@usableFromInline' + or public + +- id: spi_attribute_on_non_public + msg: >- + %select{private|fileprivate|internal|%error|%error}0 %1 cannot be + declared '@_spi' because only public and open declarations can be '@_spi' + +- id: spi_attribute_on_protocol_requirement + msg: >- + protocol requirement %0 cannot be declared '@_spi' without a default + implementation in a protocol extension + +- id: spi_attribute_on_frozen_stored_properties + msg: >- + stored property %0 cannot be declared '@_spi' in a '@frozen' struct + +- id: opaque_type_invalid_constraint + msg: >- + an 'opaque' type must specify only 'Any', 'AnyObject', protocols, and/or + a base class + +- id: inferred_opaque_type + msg: >- + property definition has inferred type %0, involving the 'some' return + type of another declaration + +- id: non_nominal_extension + msg: >- + non-nominal type %0 cannot be extended + +- id: composition_in_extended_type + msg: >- + extending a protocol composition is not supported; extending %0 instead + +- id: composition_in_extended_type_alternative + msg: >- + did you mean to extend the most specific type %0 instead? + +- id: extension_access_with_conformances + msg: >- + %0 modifier cannot be used with extensions that declare protocol + conformances + +- id: extension_metatype + msg: >- + cannot extend a metatype %0 + +- id: extension_specialization + msg: >- + constrained extension must be declared on the unspecialized generic type + %0 with constraints specified by a 'where' clause + +- id: extension_stored_property + msg: >- + extensions must not contain stored properties + +- id: extension_stored_property_fixit + msg: >- + Remove '=' to make %0 a computed property + +- id: extension_nongeneric_trailing_where + msg: >- + trailing 'where' clause for extension of non-generic type %0 + +- id: extension_protocol_inheritance + msg: >- + extension of protocol %0 cannot have an inheritance clause + +- id: objc_generic_extension_using_type_parameter + msg: >- + extension of a generic Objective-C class cannot access the class's + generic parameters at runtime + +- id: objc_generic_extension_using_type_parameter_here + msg: >- + generic parameter used here + +- id: objc_generic_extension_using_type_parameter_try_objc + msg: >- + add '@objc' to allow uses of 'self' within the function body + +- id: invalid_nominal_extension + msg: >- + extension of type %0 must be declared as an extension of %1 + +- id: invalid_nominal_extension_rewrite + msg: >- + did you mean to extend %0 instead? + +- id: type_does_not_conform + msg: >- + type %0 does not conform to protocol %1 + +- id: cannot_use_nil_with_this_type + msg: >- + 'nil' cannot be used in context expecting type %0 + +- id: type_cannot_conform_to_nsobject + msg: >- + cannot declare conformance to 'NSObjectProtocol' in Swift; %0 should + inherit 'NSObject' instead + +- id: use_of_equal_instead_of_equality + msg: >- + use of '=' in a boolean context, did you mean '=='? + +- id: type_cannot_conform + msg: >- + %select{type %1|protocol %1 as a type}0 cannot conform to + %select{%3|the protocol itself}2; + only concrete types such as structs, enums and classes + can conform to protocols + +- id: required_by_opaque_return + msg: >- + required by opaque return type of %0 %1 + +- id: required_by_decl + msg: >- + required by %0 %1 where %2 = %3 + +- id: required_by_decl_ref + msg: >- + required by referencing %0 %1 on %2 where %3 = %4 + +- id: protocol_does_not_conform_static + msg: >- + %0 cannot be used as a type conforming to protocol %1 because %1 has + static requirements + +- id: protocol_derivation_is_broken + msg: >- + protocol %0 is broken; cannot derive conformance for type %1 + +- id: type_does_not_inherit + msg: >- + %0 requires that %1 inherit from %2 + +- id: type_does_not_inherit_or_conform_requirement + msg: >- + requirement specified as %0 : %1%2 + +- id: types_not_equal + msg: >- + %0 requires the types %1 and %2 be equivalent + +- id: type_does_not_conform_owner + msg: >- + %0 requires that %1 conform to %2 + +- id: type_does_not_conform_in_decl_ref + msg: >- + referencing %0 %1 on %2 requires that %3 conform to %4 + +- id: type_does_not_conform_anyobject_in_decl_ref + msg: >- + referencing %0 %1 on %2 requires that %3 be a class type + +- id: type_does_not_conform_decl_owner + msg: >- + %0 %1 requires that %2 conform to %3 + +- id: type_does_not_conform_anyobject_decl_owner + msg: >- + %0 %1 requires that %2 be a class type + +- id: type_does_not_conform_in_opaque_return + msg: >- + return type of %0 %1 requires that %2 + %select{conform to %3|be a class type}4 + +- id: types_not_equal_decl + msg: >- + %0 %1 requires the types %2 and %3 be equivalent + +- id: types_not_equal_in_decl_ref + msg: >- + referencing %0 %1 on %2 requires the types %3 and %4 be equivalent + +- id: types_not_inherited_decl + msg: >- + %0 %1 requires that %2 inherit from %3 + +- id: types_not_inherited_in_decl_ref + msg: >- + referencing %0 %1 on %2 requires that %3 inherit from %4 + +- id: where_requirement_failure_one_subst + msg: >- + where %0 = %1 + +- id: where_requirement_failure_both_subst + msg: >- + where %0 = %1, %2 = %3 + +- id: requirement_implied_by_conditional_conformance + msg: >- + requirement from conditional conformance of %0 to %1 + +- id: wrapped_type_satisfies_requirement + msg: >- + wrapped type %0 satisfies this requirement; did you mean to unwrap? + +- id: candidate_types_conformance_requirement + msg: >- + candidate requires that %0 conform to %1 + (requirement specified as %2 == %3%4) + +- id: candidate_types_equal_requirement + msg: >- + candidate requires that the types %0 and %1 be equivalent (requirement + specified as %2 == %3%4) + +- id: candidate_types_inheritance_requirement + msg: >- + candidate requires that %1 inherit from %2 + (requirement specified as %2 : %3%4) + +- id: types_not_equal_requirement + msg: >- + requirement specified as %0 == %1%2 + +- id: type_is_not_a_class + msg: >- + %0 requires that %1 be a class type + +- id: anyobject_requirement + msg: >- + requirement specified as %0 : 'AnyObject'%2 + +- id: non_class_cannot_conform_to_class_protocol + msg: >- + non-class type %0 cannot conform to class protocol %1 + +- id: cf_class_cannot_conform_to_objc_protocol + msg: >- + Core Foundation class %0 cannot conform to @objc protocol %1 because Core + Foundation types are not classes in Objective-C + +- id: objc_runtime_visible_cannot_conform_to_objc_protocol + msg: >- + class %0 cannot conform to @objc protocol %1 because the class is only + visible via the Objective-C runtime + +- id: objc_generics_cannot_conditionally_conform + msg: >- + type %0 cannot conditionally conform to protocol %1 because the type uses + the Objective-C generics model + +- id: objc_protocol_cannot_have_conditional_conformance + msg: >- + type %0 cannot conditionally conform to @objc protocol %1 because + Objective-C does not support conditional conformances + +- id: objc_protocol_in_generic_extension + msg: >- + conformance of %select{class from generic context|generic class}0 %1 to + @objc protocol %2 cannot be in an extension + +- id: conditional_conformances_cannot_imply_conformances + msg: >- + conditional conformance of type %0 to protocol %1 does not imply + conformance to inherited protocol %2 + +- id: note_explicitly_state_conditional_conformance_different + msg: >- + did you mean to explicitly state the conformance with different bounds? + +- id: note_explicitly_state_conditional_conformance_relaxed + msg: >- + did you mean to explicitly state the conformance with relaxed bounds? + +- id: note_explicitly_state_conditional_conformance_same + msg: >- + did you mean to explicitly state the conformance with the same bounds? + +- id: note_explicitly_state_conditional_conformance_noneditor + msg: >- + did you mean to explicitly state the conformance like '%0where ...'? + +- id: protocol_has_missing_requirements + msg: >- + type %0 cannot conform to protocol %1 because it has requirements that + cannot be satisfied + +- id: protocol_has_missing_requirements_versioned + msg: >- + type %0 cannot conform to protocol %1 (compiled with Swift %2) because it + has requirements that could not be loaded in Swift %3 + +- id: requirement_restricts_self + msg: >- + %0 requirement %1 cannot add constraint '%2%select{:|:| ==|:}3 %4' on 'Self' + +- id: witness_argument_name_mismatch + msg: >- + %0 %1 has different argument labels from those required by protocol %2 (%3) + +- id: witness_initializer_not_required + msg: >- + initializer requirement %0 can only be satisfied by a 'required' + initializer in%select{| the definition of}1 non-final class %2 + +- id: witness_initializer_failability + msg: >- + non-failable initializer requirement %0%select{| in Objective-C + protocol}1 cannot be satisfied by a + failable initializer ('init%select{?|!}1') + +- id: witness_self_non_subtype + msg: >- + protocol %0 requirement %1 cannot be satisfied by a non-final class (%2) + because it uses 'Self' in a non-parameter, non-result type position + +- id: witness_self_same_type + msg: >- + %0 %1 in non-final class %2 cannot be used to satisfy requirement %3 %4 + (in protocol %5) due to same-type requirement involving 'Self' + +- id: witness_self_weaken_same_type + msg: >- + consider weakening the same-type requirement %0 == %1 to a superclass + requirement + +- id: witness_requires_dynamic_self + msg: >- + method %0 in non-final class %1 must return 'Self' to conform to protocol %2 + +- id: witness_requires_class_implementation + msg: >- + method %0 in non-final class %1 cannot be implemented in a protocol + extension because it returns 'Self' and has associated type requirements + +- id: witness_not_accessible_proto + msg: >- + %select{initializer %1|method %1|%select{|setter for }2property + %1|subscript%select{| setter}2}0 must be declared + %select{%error|fileprivate|internal|public|%error}3 because it matches a + requirement in %select{private|fileprivate|internal|public|%error}4 + protocol %5 + +- id: witness_not_accessible_type + msg: >- + %select{initializer %1|method %1|%select{|setter for }2property + %1|subscript%select{| setter}2}0 must be as accessible as its enclosing type + because it matches a requirement in protocol %5 + +- id: type_witness_not_accessible_proto + msg: >- + %0 %1 must be declared + %select{%error|fileprivate|internal|public|%error}2 because it matches a + requirement in %select{%error|fileprivate|internal|public|%error}2 + protocol %3 + +- id: type_witness_not_accessible_type + msg: >- + %0 %1 must be as accessible as its enclosing type because it matches a + requirement in protocol %3 + +- id: witness_not_usable_from_inline + msg: >- + %0 %1 must be declared '@usableFromInline' because it matches a + requirement in protocol %2 + +- id: witness_not_usable_from_inline_warn + msg: >- + %0 %1 should be declared '@usableFromInline' because it matches a + requirement in protocol %2 + +- id: type_witness_objc_generic_parameter + msg: >- + type %0 involving Objective-C type parameter%select{| %1}2 cannot be used + for associated type %3 of protocol %4 + +- id: witness_fix_access + msg: >- + mark the %0 as '%select{%error|fileprivate|internal|public|%error}1' to + satisfy the requirement + +- id: witness_move_to_another_extension + msg: >- + move the %0 to another extension where it can be declared + '%select{%error|%error|internal|public|%error}1' to satisfy the requirement + +- id: assoc_type_default_conformance_failed + msg: >- + default type %0 for associated type %1 does not satisfy constraint %2: %3 + +- id: assoc_type_default_here + msg: >- + associated type %0 has default type %1 written here + +- id: protocol_access + msg: >- + %select{protocol must be declared + %select{%select{private|fileprivate|internal|%error|%error}1|private or + fileprivate}4 because + %select{it refines|its 'where' clause uses}2|%select{in + this context|fileprivate|internal|public|%error}1 %select{protocol cannot + refine|protocol's 'where' clause cannot use}2}0 %select{a private|a + fileprivate|an internal|%error|%error}3 %5 + +- id: protocol_access_warn + msg: >- + %select{protocol should be declared + %select{private|fileprivate|internal|%error|%error}1 because %select{it + refines|its 'where' clause uses}2|%select{in this + context|fileprivate|internal|public|%error}1 %select{protocol should not + refine|protocol's 'where' clause should not use}2}0 %select{a private|a + fileprivate|an internal|%error|%error}3 %5 + +- id: protocol_usable_from_inline + msg: >- + protocol %select{refined|used}0 by '@usableFromInline' protocol must be + '@usableForInline' or public + +- id: protocol_usable_from_inline_warn + msg: >- + protocol %select{refined|used}0 by '@usableFromInline' protocol should be + '@usableForInline' or public + +- id: protocol_property_must_be_computed_var + msg: >- + protocols cannot require properties to be immutable; declare read-only + properties by using 'var' with a '{ get }' specifier + +- id: protocol_property_must_be_computed + msg: >- + property in protocol must have explicit { get } or { get set } specifier + +- id: inherited_protocol_does_not_conform + msg: >- + type %0 does not conform to inherited protocol %1 + +- id: no_witnesses + msg: >- + protocol requires %select{initializer %1|function %1|property + %1|subscript}0 with type %2%select{|; do you want to add a stub?}3 + +- id: missing_witnesses_general + msg: >- + do you want to add protocol stubs? + +- id: ambiguous_witnesses + msg: >- + multiple matching %select{initializers named %1|functions named + %1|properties named %1|subscript operators}0 with type %2 + +- id: ambiguous_witnesses_wrong_name + msg: >- + multiple matching %select{initializers named %1|functions named + %1|properties named %1|subscript operators}0 with type %2 + +- id: no_witnesses_type + msg: >- + protocol requires nested type %0; do you want to add it? + +- id: default_associated_type_req_fail + msg: >- + default type %0 for associated type %1 (from protocol %2) does not + %select{inherit from|conform to}4 %3 + +- id: associated_type_access + msg: >- + associated type in %select{a private|a fileprivate|an internal|a + public|%error}0 protocol uses %select{a private|a fileprivate|an + internal|%error|%error}1 type in its + %select{default definition|requirement}2 + +- id: associated_type_access_warn + msg: >- + associated type in %select{a private|a fileprivate|an internal|a + public|%error}0 protocol uses %select{a private|a fileprivate|an + internal|%error|%error}1 type in its + %select{default definition|requirement}2 + +- id: associated_type_not_usable_from_inline + msg: >- + type referenced from a %select{default definition|requirement}0 of an + associated type in a '@usableFromInline' + protocol must be '@usableFromInline' or public + +- id: associated_type_not_usable_from_inline_warn + msg: >- + type referenced from a %select{default definition|requirement}0 of an + associated type in a '@usableFromInline' + protocol should be '@usableFromInline' or public + +- id: bad_associated_type_deduction + msg: >- + unable to infer associated type %0 for protocol %1 + +- id: associated_type_deduction_witness_failed + msg: >- + candidate would match and infer %0 = %1 if %1 %select{inherited + from|conformed to}3 %2 + +- id: associated_type_witness_conform_impossible + msg: >- + candidate can not infer %0 = %1 because %1 is not a nominal type and so + can't conform to %2 + +- id: associated_type_witness_inherit_impossible + msg: >- + candidate can not infer %0 = %1 because %1 is not a class type and so + can't inherit from %2 + +- id: ambiguous_associated_type_deduction + msg: >- + ambiguous inference of associated type %0: %1 vs. %2 + +- id: associated_type_deduction_witness + msg: >- + matching requirement %0 to this declaration inferred associated type to %1 + +- id: associated_type_deduction_default + msg: >- + using associated type default %0 + +- id: ambiguous_witnesses_type + msg: >- + multiple matching types named %0 + +- id: protocol_witness_exact_match + msg: >- + candidate exactly matches%0 + +- id: protocol_witness_renamed + msg: >- + rename to %0 to satisfy this requirement%1 + +- id: protocol_witness_kind_conflict + msg: >- + candidate is not %select{an initializer|a function|a variable|a subscript}0 + +- id: protocol_witness_type_conflict + msg: >- + candidate has non-matching type %0%1 + +- id: protocol_witness_missing_requirement + msg: >- + candidate would match if %0 %select{conformed to|subclassed|was the same + type as}2 %1 + +- id: protocol_witness_optionality_conflict + msg: >- + candidate %select{type has|result type has|parameter type has|parameter + types have|result and parameter types have}0 incorrect optionality%1 + +- id: err_protocol_witness_optionality + msg: >- + %select{type|result|parameter|parameters|result and parameters}0 of %1 + %select{has|has|has|have|have|}0 + different optionality than required by protocol %2 + +- id: warn_protocol_witness_optionality + msg: >- + %select{type|result|parameter|parameters|result and parameters}0 of %1 + %select{has|has|has|have|have|}0 different optionality than expected by + protocol %2 + +- id: protocol_witness_static_conflict + msg: >- + candidate operates on %select{a type|an instance}0, not %select{an + instance|a type}0 as required + +- id: protocol_witness_prefix_postfix_conflict + msg: >- + candidate is %select{|prefix, |postfix, }1not %select{prefix|postfix}0 as + required + +- id: protocol_witness_mutation_modifier_conflict + msg: >- + candidate is marked %0 but protocol does not allow it + +- id: protocol_witness_settable_conflict + msg: >- + candidate is not settable, but protocol requires it + +- id: protocol_witness_rethrows_conflict + msg: >- + candidate is not 'rethrows', but protocol requires it + +- id: protocol_witness_throws_conflict + msg: >- + candidate throws, but protocol does not allow it + +- id: protocol_witness_not_objc + msg: >- + candidate is explicitly '@nonobjc' + +- id: protocol_witness_enum_case_payload + msg: >- + candidate is an enum case with associated values, but protocol does not + allow it + +- id: protocol_witness_type + msg: >- + possibly intended match + +- id: protocol_witness_nonconform_type + msg: >- + possibly intended match %0 does not %select{inherit from|conform to}2 %1 + +- id: protocol_witness_circularity + msg: >- + candidate references itself + +- id: protocol_conformance_here + msg: >- + %select{|class }0%1 declares conformance to protocol %2 here + +- id: declared_protocol_conformance_here + msg: >- + %select{%0 inherits conformance to protocol %2 from superclass|%0 + declares conformance to protocol %2|%0 implicitly conforms to protocol %2 + (via conformance to %3)|%0 implicitly conforms to protocol %2}1 here + +- id: witness_unavailable + msg: >- + unavailable %0 %1 was used to satisfy a requirement of protocol %2 + +- id: redundant_conformance + msg: >- + redundant conformance of %0 to protocol %1 + +- id: redundant_conformance_conditional + msg: >- + conflicting conformance of %0 to protocol %1; there cannot be more than + one conformance, even with different conditional bounds + +- id: redundant_conformance_adhoc + msg: >- + conformance of %0 to protocol %1 was already stated in + %select{the protocol's|the type's}2 module %3 + +- id: redundant_conformance_adhoc_conditional + msg: >- + conformance of %0 to protocol %1 conflicts with that stated in + %select{the protocol's|the type's}2 module %3 and will be ignored; + there cannot be more than one conformance, + even with different conditional bounds + +- id: redundant_conformance_witness_ignored + msg: >- + %0 %1 will not be used to satisfy the conformance to %2 + +- id: req_near_match + msg: >- + %0 %1 nearly matches %select{defaulted|optional}2 requirement %3 of + protocol %4 + +- id: optional_req_nonobjc_near_match_add_objc + msg: >- + add '@objc' to provide an Objective-C entrypoint + +- id: req_near_match_move + msg: >- + move %0 to %select{an|another}1 extension to silence this warning + +- id: req_near_match_nonobjc + msg: >- + add '@nonobjc' to silence this %select{warning|error}0 + +- id: req_near_match_access + msg: >- + make %0 %select{ERROR|private|private|non-public|non-public}1 to silence + this warning + +- id: missing_append_interpolation + msg: >- + type conforming to 'StringInterpolationProtocol' does not implement a + valid 'appendInterpolation' method + +- id: append_interpolation_static + msg: >- + 'appendInterpolation' method will never be used because it is static + +- id: append_interpolation_void_or_discardable + msg: >- + 'appendInterpolation' method does not return 'Void' or have a discardable + result + +- id: append_interpolation_access_control + msg: >- + 'appendInterpolation' method is + %select{private|fileprivate|internal|public|open}0, but %1 is + %select{private|fileprivate|internal|public|open}2 + +- id: assoc_type_outside_of_protocol + msg: >- + associated type %0 can only be used with a concrete type or generic + parameter base + +- id: typealias_outside_of_protocol + msg: >- + type alias %0 can only be used with a concrete type or generic parameter + base + +- id: objc_protocol_inherits_non_objc_protocol + msg: >- + @objc protocol %0 cannot refine non-@objc protocol %1 + +- id: protocol_where_clause_self_requirement + msg: >- + constraint with subject type of 'Self' is not supported; consider adding + requirement to protocol inheritance clause instead + +- id: invalid_protocol_composition_member + msg: >- + non-protocol, non-class type %0 cannot be used within a + protocol-constrained type + +- id: protocol_composition_one_class + msg: >- + protocol-constrained type cannot contain class %0 because it already + contains class %1 + +- id: requires_conformance_nonprotocol + msg: >- + type %0 constrained to non-protocol, non-class type %1 + +- id: requires_conformance_nonprotocol_fixit + msg: >- + use '%0 == %1' to require '%0' to be '%1' + +- id: requires_not_suitable_archetype + msg: >- + type %0 in conformance requirement does not refer to a generic parameter + or associated type + +- id: requires_no_same_type_archetype + msg: >- + neither type in same-type constraint (%0 or %1) refers to a generic + parameter or associated type + +- id: requires_generic_params_made_equal + msg: >- + same-type requirement makes generic parameters %0 and %1 equivalent + +- id: requires_generic_param_made_equal_to_concrete + msg: >- + same-type requirement makes generic parameter %0 non-generic + +- id: recursive_decl_reference + msg: >- + %0 %1 references itself + +- id: recursive_same_type_constraint + msg: >- + same-type constraint %0 == %1 is recursive + +- id: recursive_superclass_constraint + msg: >- + superclass constraint %0 : %1 is recursive + +- id: requires_generic_param_same_type_does_not_conform + msg: >- + same-type constraint type %0 does not conform to required protocol %1 + +- id: requires_same_concrete_type + msg: >- + generic signature requires types %0 and %1 to be the same + +- id: redundant_conformance_constraint + msg: >- + redundant conformance constraint %0: %1 + +- id: redundant_conformance_here + msg: >- + conformance constraint %1: %2 %select{written here|implied here|inferred + from type here}0 + +- id: unsupported_recursive_requirements + msg: >- + requirement involves recursion that is not currently supported + +- id: same_type_conflict + msg: >- + %select{generic parameter |protocol |}0%1 cannot be equal to both %2 and %3 + +- id: redundant_same_type_to_concrete + msg: >- + redundant same-type constraint %0 == %1 + +- id: same_type_redundancy_here + msg: >- + same-type constraint %1 == %2 %select{written here|implied here|inferred + from type here}0 + +- id: requires_superclass_conflict + msg: >- + %select{generic parameter %1 cannot|protocol %1 cannot require 'Self' + to|%1 cannot}0 be a subclass of both %2 and %3 + +- id: redundant_superclass_constraint + msg: >- + redundant superclass constraint %0 : %1 + +- id: superclass_redundancy_here + msg: >- + superclass constraint %1 : %2 %select{written here|implied here|inferred + from type here}0 + +- id: conflicting_layout_constraints + msg: >- + %select{generic parameter |protocol |}0%1 has conflicting constraints %2 + and %3 + +- id: redundant_layout_constraint + msg: >- + redundant constraint %0 : %1 + +- id: previous_layout_constraint + msg: >- + constraint %1 : %2 %select{written here|implied here|inferred from type + here}0 + +- id: redundant_same_type_constraint + msg: >- + redundant same-type constraint %0 == %1 + +- id: previous_same_type_constraint + msg: >- + previous same-type constraint %1 == %2 %select{written here|implied + here|inferred from type here}0 + +- id: inherited_associated_type_redecl + msg: >- + redeclaration of associated type %0 from protocol %1 is better expressed + as a 'where' clause on the protocol + +- id: typealias_override_associated_type + msg: >- + typealias overriding associated type %0 from protocol %1 is better + expressed as same-type constraint on the protocol + +- id: associated_type_override_typealias + msg: >- + associated type %0 is redundant with type %0 declared in inherited %1 %2 + +- id: associated_type_objc + msg: >- + associated type %0 cannot be declared inside '@objc' protocol %1 + +- id: generic_param_access + msg: >- + %0 %select{must be declared + %select{%select{private|fileprivate|internal|%error|%error}3|private or + fileprivate}4|cannot be declared %select{in this + context|fileprivate|internal|public|open}2}1 because its generic + %select{parameter|requirement}5 uses %select{a private|a fileprivate|an + internal|an '@_spi'|an '@_spi'}3 type + +- id: generic_param_access_warn + msg: >- + %0 %select{should be declared + %select{private|fileprivate|internal|%error|%error}3|should not be declared + %select{in this context|fileprivate|internal|public|open}2}1 because its generic + %select{parameter|requirement}5 uses %select{a private|a fileprivate|an + internal|an '@_spi'|an '@_spi'}3 type + +- id: generic_param_usable_from_inline + msg: >- + type referenced from a generic %select{parameter|requirement}1 of a + '@usableFromInline' %0 must be '@usableFromInline' or public + +- id: generic_param_usable_from_inline_warn + msg: >- + type referenced from a generic %select{parameter|requirement}1 of a + '@usableFromInline' %0 should be '@usableFromInline' or public + +- id: override_multiple_decls_base + msg: >- + declaration %0 cannot override more than one superclass declaration + +- id: override_multiple_decls_arg_mismatch + msg: >- + declaration %0 has different argument labels from any potential overrides + +- id: overridden_near_match_here + msg: >- + potential overridden %0 %1 here + +- id: override_decl_extension + msg: >- + overriding %select{|non-@objc }0declarations %select{in extensions|from + extensions}0 is not supported + +- id: overridden_here + msg: >- + overridden declaration is here + +- id: overridden_here_can_be_objc + msg: >- + add '@objc' to make this declaration overridable + +- id: missing_override + msg: >- + overriding declaration requires an 'override' keyword + +- id: missing_override_warn + msg: >- + implicit override should be marked with 'override' or suppressed with + '@_nonoverride' + +- id: multiple_override + msg: >- + %0 has already been overridden + +- id: multiple_override_prev + msg: >- + %0 previously overridden here + +- id: override_unavailable + msg: >- + cannot override %0 which has been marked unavailable%select{|: %1}1 + +- id: override_less_available + msg: >- + overriding %0 must be as available as declaration it overrides + +- id: override_accessor_less_available + msg: >- + overriding %0 for %1 must be as available as declaration it overrides + +- id: override_let_property + msg: >- + cannot override immutable 'let' property %0 with the getter of a 'var' + +- id: override_not_accessible + msg: >- + %select{|setter of }0overriding %1 must be as accessible as %select{its + enclosing type|the declaration it overrides}2 + +- id: override_of_non_open + msg: >- + overriding non-open %0 outside of its defining module + +- id: method_does_not_override + msg: >- + method does not override any method from its superclass + +- id: property_does_not_override + msg: >- + property does not override any property from its superclass + +- id: subscript_does_not_override + msg: >- + subscript does not override any subscript from its superclass + +- id: initializer_does_not_override + msg: >- + initializer does not override a designated initializer from its + superclass + +- id: failable_initializer_override + msg: >- + failable initializer %0 cannot override a non-failable initializer + +- id: nonfailable_initializer_override_here + msg: >- + non-failable initializer %0 overridden here + +- id: property_override_here + msg: >- + attempt to override property here + +- id: subscript_override_here + msg: >- + attempt to override subscript here + +- id: convenience_init_override_here + msg: >- + attempt to override convenience initializer here + +- id: override_type_mismatch_with_fixits + msg: >- + type does not match superclass %0 with type %1 + +- id: override_type_mismatch_with_fixits_init + msg: >- + type does not match superclass initializer with %select{no + arguments|argument %1|arguments %1}0 + +- id: override_nonclass_decl + msg: >- + 'override' can only be specified on class members + +- id: nonoverride_wrong_decl_context + msg: >- + '@_nonoverride' can only be specified on class or protocol members + +- id: nonoverride_and_override_attr + msg: >- + 'override' cannot be combined with '@_nonoverride' + +- id: override_property_type_mismatch + msg: >- + property %0 with type %1 cannot override a property with type %2 + +- id: override_with_stored_property + msg: >- + cannot override with a stored property %0 + +- id: override_with_stored_property_warn + msg: >- + cannot override with a stored property %0 + +- id: observing_readonly_property + msg: >- + cannot observe read-only property %0; it can't change + +- id: override_mutable_with_readonly_property + msg: >- + cannot override mutable property with read-only property %0 + +- id: override_argument_name_mismatch + msg: >- + argument labels for %select{method|initializer}0 %1 do not match those of + overridden %select{method|initializer}0 %2 + +- id: override_ownership_mismatch + msg: >- + cannot override %0 property with %1 property + +- id: override_dynamic_self_mismatch + msg: >- + cannot override a Self return type with a non-Self return type + +- id: override_class_declaration_in_extension + msg: >- + cannot override a non-dynamic class declaration from an extension + +- id: override_throws + msg: >- + cannot override non-throwing %select{method|initializer}0 with throwing + %select{method|initializer}0 + +- id: override_throws_objc + msg: >- + overriding a throwing @objc %select{method|initializer}0 with a + non-throwing %select{method|initializer}0 is not supported + +- id: satisfy_throws_objc + msg: >- + satisfying a throwing @objc %select{method|initializer}0 with a + non-throwing %select{method|initializer}0 is not supported + +- id: override_optional_mismatch + msg: >- + cannot override %0 %select{parameter|index}1 of type %2 with non-optional + type %3 + +- id: override_optional_result_mismatch + msg: >- + cannot override %0 %select{result|element}1 type %2 with optional type %3 + +- id: override_unnecessary_IUO + msg: >- + overriding %0 parameter of type %1 with implicitly unwrapped optional + type %2 + +- id: override_unnecessary_result_IUO + msg: >- + overriding %0 optional result type %1 with implicitly unwrapped optional + type %2 + +- id: override_unnecessary_IUO_remove + msg: >- + remove '!' to make the parameter required + +- id: override_unnecessary_IUO_use_strict + msg: >- + use '?' to make the result optional + +- id: override_unnecessary_IUO_silence + msg: >- + add parentheses to silence this warning + +- id: override_mutable_covariant_property + msg: >- + cannot override mutable property %0 of type %1 with covariant type %2 + +- id: override_mutable_covariant_subscript + msg: >- + cannot override mutable subscript of type %0 with covariant type %1 + +- id: static_decl_already_final + msg: >- + static declarations are already final + +- id: open_decl_cannot_be_final + msg: >- + %0 cannot be declared both 'final' and 'open' + +- id: implicitly_final_cannot_be_open + msg: >- + %select{'let' properties|members of 'final' classes|static declarations}0 + are implicitly 'final'; use 'public' instead of 'open' + +- id: implicitly_final_cannot_be_open_swift4 + msg: >- + %select{'let' properties|members of 'final' classes|static declarations}0 + are implicitly 'final'; use 'public' instead of 'open' + +- id: override_swift3_objc_inference + msg: >- + override of %0 %1 from extension of %2 depends on deprecated inference of + '@objc' + +- id: override_method_different_generic_sig + msg: >- + overridden method %0 has generic signature %1 which is incompatible with + base method's generic signature %2; expected generic signature to be %3 + +- id: duplicate_inheritance + msg: >- + duplicate inheritance from %0 + +- id: duplicate_anyobject_class_inheritance + msg: >- + redundant inheritance from 'AnyObject' and Swift 3 'class' keyword + +- id: inheritance_from_protocol_with_superclass + msg: >- + inheritance from class-constrained protocol composition type %0 + +- id: multiple_inheritance + msg: >- + multiple inheritance from classes %0 and %1 + +- id: inheritance_from_non_protocol_or_class + msg: >- + inheritance from non-protocol, non-class type %0 + +- id: inheritance_from_non_protocol + msg: >- + inheritance from non-protocol type %0 + +- id: superclass_not_first + msg: >- + superclass %0 must appear first in the inheritance clause + +- id: superclass_not_open + msg: >- + cannot inherit from non-open class %0 outside of its defining module + +- id: superclass_here + msg: >- + superclass is declared here + +- id: superclass_of_open_not_open + msg: >- + superclass %0 of open class must be open + +- id: inheritance_from_final_class + msg: >- + inheritance from a final class %0 + +- id: inheritance_from_unspecialized_objc_generic_class + msg: >- + inheritance from a generic Objective-C class %0 must bind type parameters + of %0 to specific concrete types + +- id: inheritance_from_class_with_missing_vtable_entries + msg: >- + cannot inherit from class %0 because it has overridable members that + could not be loaded + +- id: inheritance_from_class_with_missing_vtable_entries_versioned + msg: >- + cannot inherit from class %0 (compiled with Swift %1) because it has + overridable members that could not be loaded in Swift %2 + +- id: inheritance_from_cf_class + msg: >- + cannot inherit from Core Foundation type %0 + +- id: inheritance_from_objc_runtime_visible_class + msg: >- + cannot inherit from class %0 because it is only visible via the + Objective-C runtime + +- id: enum_case_access + msg: >- + enum case in %select{a private|a fileprivate|an internal|a + public|%error}0 enum uses %select{a private|a fileprivate|an + internal|%error|%error}1 type + +- id: enum_case_access_warn + msg: >- + enum case in %select{a private|a fileprivate|an internal|a + public|%error}0 enum uses %select{a private|a fileprivate|an + internal|%error|%error}1 type + +- id: enum_case_usable_from_inline + msg: >- + type of enum case in '@usableFromInline' enum must be '@usableFromInline' + or public + +- id: enum_case_usable_from_inline_warn + msg: >- + type of enum case in '@usableFromInline' enum should be + '@usableFromInline' or public + +- id: enum_stored_property + msg: >- + enums must not contain stored properties + +- id: multiple_enum_raw_types + msg: >- + multiple enum raw types %0 and %1 + +- id: raw_type_not_first + msg: >- + raw type %0 must appear first in the enum inheritance clause + +- id: raw_type_not_literal_convertible + msg: >- + raw type %0 is not expressible by a string, integer, or floating-point + literal + +- id: enum_raw_type_not_equatable + msg: >- + RawRepresentable conformance cannot be synthesized because raw type %0 is + not Equatable + +- id: enum_raw_type_nonconforming_and_nonsynthable + msg: >- + %0 declares raw type %1, but does not conform to RawRepresentable and + conformance could not be synthesized + +- id: enum_declares_rawrep_with_raw_type + msg: >- + %0 declares raw type %1, which implies RawRepresentable + +- id: enum_raw_type_access + msg: >- + enum %select{must be declared + %select{%select{private|fileprivate|internal|%error|%error}1|private or + fileprivate}3|cannot be declared %select{in this + context|fileprivate|internal|public|open}1}0 because its raw type uses + %select{a private|a fileprivate|an internal|%error|%error}2 type + +- id: enum_raw_type_access_warn + msg: >- + enum %select{should be declared + %select{private|fileprivate|internal|%error|%error}1|should not be declared + %select{in this context|fileprivate|internal|public|open}1}0 because its raw + type uses %select{a private|a fileprivate|an internal|%error|%error}2 type + +- id: enum_raw_type_not_usable_from_inline + msg: >- + type referenced from the raw type of a '@usableFromInline' enum must be + '@usableFromInline' or public + +- id: enum_raw_type_not_usable_from_inline_warn + msg: >- + type referenced from the raw type of a '@usableFromInline' enum should be + '@usableFromInline' or public + +- id: empty_enum_raw_type + msg: >- + an enum with no cases cannot declare a raw type + +- id: enum_raw_value_without_raw_type + msg: >- + enum case cannot have a raw value if the enum does not have a raw type + +- id: enum_with_raw_type_case_with_argument + msg: >- + enum with raw type cannot have cases with arguments + +- id: enum_raw_type_here + msg: >- + declared raw type %0 here + +- id: objc_enum_no_raw_type + msg: >- + '@objc' enum must declare an integer raw type + +- id: objc_enum_raw_type_not_integer + msg: >- + '@objc' enum raw type %0 is not an integer type + +- id: enum_non_integer_raw_value_auto_increment + msg: >- + enum case must declare a raw value when the preceding raw value is not an + integer + +- id: enum_non_integer_convertible_raw_type_no_value + msg: >- + enum cases require explicit raw values when the raw type is not + expressible by integer or string literal + +- id: enum_raw_value_not_unique + msg: >- + raw value for enum case is not unique + +- id: enum_raw_value_magic_literal + msg: >- + use of '%0' literal as raw value for enum case is not supported + +- id: enum_raw_value_used_here + msg: >- + raw value previously used here + +- id: enum_raw_value_incrementing_from_here + msg: >- + raw value auto-incremented from here + +- id: enum_raw_value_incrementing_from_zero + msg: >- + raw value implicitly auto-incremented from zero + +- id: construct_raw_representable_from_unwrapped_value + msg: >- + construct %0 from unwrapped %1 value + +- id: decl_from_hidden_module + msg: >- + cannot use %0 %1 %select{here|as property wrapper here|in an extension + with public or '@usableFromInline' members|in an extension with conditional + conformances}2; %select{%3 has been imported as implementation-only|it + is an SPI imported from %3|it is SPI}4 + +- id: conformance_from_implementation_only_module + msg: >- + cannot use conformance of %0 to %1 %select{here|as property wrapper + here|in an extension with public or '@usableFromInline' members|in + an extension with conditional conformances}2; + %3 has been imported as implementation-only + +- id: assoc_conformance_from_implementation_only_module + msg: >- + cannot use conformance of %0 to %1 in associated type %3 (inferred as + %4); %2 has been imported as implementation-only + +- id: unexportable_clang_function_type + msg: >- + cannot export the underlying C type of the function type %0; it may use + anonymous types or types defined outside of a module + +- id: warn_implementation_only_conflict + msg: >- + %0 inconsistently imported as implementation-only + +- id: implementation_only_conflict_here + msg: >- + imported as implementation-only here + +- id: implementation_only_decl_non_override + msg: >- + '@_implementationOnly' can only be used on overrides + +- id: implementation_only_override_changed_type + msg: >- + '@_implementationOnly' override must have the same type as the + declaration it overrides (%0) + +- id: implementation_only_override_without_attr + msg: >- + override of '@_implementationOnly' %0 should also be declared + '@_implementationOnly' + +- id: implementation_only_override_import_without_attr + msg: >- + override of %0 imported as implementation-only must be declared + '@_implementationOnly' + +- id: cannot_synthesize_init_in_extension_of_nonfinal + msg: >- + implementation of %0 for non-final class cannot be automatically + synthesized in extension because initializer requirement %1 can only be + satisfied by a 'required' initializer in the class definition + +- id: cannot_synthesize_in_crossfile_extension + msg: >- + implementation of %0 cannot be automatically synthesized in an extension + in a different file to the type + +- id: broken_additive_arithmetic_requirement + msg: >- + AdditiveArithmetic protocol is broken: unexpected requirement + +- id: broken_case_iterable_requirement + msg: >- + CaseIterable protocol is broken: unexpected requirement + +- id: broken_raw_representable_requirement + msg: >- + RawRepresentable protocol is broken: unexpected requirement + +- id: broken_comparable_requirement + msg: >- + Comparable protocol is broken: unexpected requirement + +- id: broken_equatable_requirement + msg: >- + Equatable protocol is broken: unexpected requirement + +- id: broken_hashable_requirement + msg: >- + Hashable protocol is broken: unexpected requirement + +- id: broken_hashable_no_hasher + msg: >- + Hashable protocol is broken: Hasher type not found + +- id: broken_errortype_requirement + msg: >- + Error protocol is broken: unexpected requirement + +- id: broken_int_hashable_conformance + msg: >- + Int type is broken: does not conform to Hashable + +- id: broken_int_integer_literal_convertible_conformance + msg: >- + Int type is broken: does not conform to ExpressibleByIntegerLiteral + +- id: no_less_than_overload_for_int + msg: >- + no overload of '<' for Int + +- id: no_equal_overload_for_int + msg: >- + no overload of '==' for Int + +- id: broken_coding_key_requirement + msg: >- + CodingKey protocol is broken: unexpected requirement + +- id: broken_encodable_requirement + msg: >- + Encodable protocol is broken: unexpected requirement + +- id: broken_decodable_requirement + msg: >- + Decodable protocol is broken: unexpected requirement + +- id: broken_differentiable_requirement + msg: >- + Differentiable protocol is broken: unexpected requirement + +- id: differentiable_nondiff_type_implicit_noderivative_fixit + msg: >- + stored property %0 has no derivative because %1 does not conform to + 'Differentiable'; add an explicit '@noDerivative' attribute%select{|, + or conform %2 to 'AdditiveArithmetic'}3 + +- id: differentiable_immutable_wrapper_implicit_noderivative_fixit + msg: >- + synthesis of the 'Differentiable.move(along:)' requirement for %1 + requires 'wrappedValue' in property wrapper %0 to be mutable; + add an explicit '@noDerivative' attribute%select{|, + or conform %1 to 'AdditiveArithmetic'}2 + +- id: differentiable_let_property_implicit_noderivative_fixit + msg: >- + synthesis of the 'Differentiable.move(along:)' requirement for %0 + requires all stored properties not marked with `@noDerivative` + to be mutable; use 'var' instead, or add an explicit + '@noDerivative' attribute%select{|, or conform %0 to 'AdditiveArithmetic'}1 + +- id: codable_extraneous_codingkey_case_here + msg: >- + CodingKey case %0 does not match any stored properties + +- id: codable_non_conforming_property_here + msg: >- + cannot automatically synthesize %0 because %1 does not conform to %0 + +- id: codable_non_decoded_property_here + msg: >- + cannot automatically synthesize %0 because %1 does not have a matching + CodingKey and does not have a default value + +- id: codable_codingkeys_type_is_not_an_enum_here + msg: >- + cannot automatically synthesize %0 because 'CodingKeys' is not an enum + +- id: codable_codingkeys_type_does_not_conform_here + msg: >- + cannot automatically synthesize %0 because 'CodingKeys' does not conform + to CodingKey + +- id: decodable_no_super_init_here + msg: >- + cannot automatically synthesize %0 because superclass does not have a + callable %1 + +- id: decodable_super_init_not_designated_here + msg: >- + cannot automatically synthesize %0 because implementation would need to + call %1, which is not designated + +- id: decodable_inaccessible_super_init_here + msg: >- + cannot automatically synthesize %0 because implementation would need to + call %1, which is inaccessible due to + '%select{private|fileprivate|internal|%error|%error}2' protection level + +- id: decodable_super_init_is_failable_here + msg: >- + cannot automatically synthesize %0 because implementation would need to + call %1, which is failable + +- id: decodable_suggest_overriding_init_here + msg: >- + did you mean to override 'init(from:)'? + +- id: codable_suggest_overriding_init_here + msg: >- + did you mean to override 'init(from:)' and 'encode(to:)'? + +- id: decodable_property_will_not_be_decoded + msg: >- + immutable property will not be decoded because it is declared with an + initial value which cannot be overwritten + +- id: decodable_property_init_or_codingkeys_implicit + msg: >- + set the initial value via the initializer or explicitly define a + CodingKeys enum %select{including|without}0 a %1 + case to silence this warning + +- id: decodable_property_init_or_codingkeys_explicit + msg: >- + set the initial value via the initializer or remove the %0 case from the + CodingKeys enum to silence this warning + +- id: decodable_make_property_mutable + msg: >- + make the property mutable instead + +- id: missing_member_type_conformance_prevents_synthesis + msg: >- + %select{associated value|stored property}0 type %1 does not conform to + protocol %2, preventing synthesized conformance of %3 to %2 + +- id: classes_automatic_protocol_synthesis + msg: >- + automatic synthesis of '%0' is not supported for classes + +- id: dynamic_self_non_method + msg: >- + %select{global|local}0 function cannot return 'Self' + +- id: dynamic_self_invalid + msg: >- + covariant 'Self' can only appear as the type of a property, subscript or + method result; did you mean '%0'? + +- id: dynamic_self_in_mutable_property + msg: >- + mutable property cannot have covariant 'Self' type + +- id: dynamic_self_in_stored_property + msg: >- + stored property cannot have covariant 'Self' type + +- id: dynamic_self_in_mutable_subscript + msg: >- + mutable subscript cannot have covariant 'Self' type + +- id: dynamic_self_invalid_property + msg: >- + covariant 'Self' can only appear at the top level of property type + +- id: dynamic_self_invalid_subscript + msg: >- + covariant 'Self' can only appear at the top level of subscript element + type + +- id: dynamic_self_invalid_method + msg: >- + covariant 'Self' can only appear at the top level of method result type + +- id: dynamic_self_stored_property_init + msg: >- + covariant 'Self' type cannot be referenced from a stored property + initializer + +- id: dynamic_self_default_arg + msg: >- + covariant 'Self' type cannot be referenced from a default argument + expression + +- id: attr_only_one_decl_kind + msg: >- + %0 may only be used on '%1' declarations + +- id: attr_not_on_variadic_parameters + msg: >- + '%0' must not be used on variadic parameters + +- id: attr_not_on_subscript_parameters + msg: >- + '%0' must not be used on subscript parameters + +- id: attr_ambiguous_reference_to_decl + msg: >- + ambiguous reference to %0 in '@%1' attribute + +- id: override_final + msg: >- + %0 overrides a 'final' %1 + +- id: override_static + msg: >- + cannot override %0 + +- id: member_cannot_be_final + msg: >- + only classes and class members may be marked with 'final' + +- id: final_not_allowed_here + msg: >- + 'final' may only be applied to classes, properties, methods, and subscripts + +- id: final_not_on_accessors + msg: >- + 'final' cannot be applied to accessors, it must be put on the + %select{var|let|subscript}0 + +- id: override_rethrows_with_non_rethrows + msg: >- + override of 'rethrows' %select{method|initializer}0 should also be + 'rethrows' + +- id: rethrows_without_throwing_parameter + msg: >- + 'rethrows' function must take a throwing function argument + +- id: autoclosure_function_type + msg: >- + @autoclosure attribute only applies to function types + +- id: invalid_autoclosure_and_convention_attributes + msg: >- + '@convention(%0)' attribute is not allowed on '@autoclosure' types + +- id: autoclosure_function_input_nonunit + msg: >- + argument type of @autoclosure parameter must be '()' + +- id: escaping_non_function_parameter + msg: >- + @escaping attribute may only be used in function parameter position + +- id: escaping_optional_type_argument + msg: >- + closure is already escaping in optional type argument + +- id: non_ephemeral_non_pointer_type + msg: >- + @_nonEphemeral attribute only applies to pointer types + +- id: attr_NSManaged_not_instance_member + msg: >- + @NSManaged only allowed on an instance property or method + +- id: attr_NSManaged_not_stored + msg: >- + @NSManaged not allowed on %select{computed|observing|addressed}0 properties + +- id: attr_NSManaged_let_property + msg: >- + @NSManaged not allowed on a 'let' property + +- id: attr_NSManaged_initial_value + msg: >- + @NSManaged property cannot have an initial value + +- id: attr_NSManaged_NSCopying + msg: >- + @NSManaged property cannot also be marked @NSCopying + +- id: attr_NSManaged_method_body + msg: >- + @NSManaged method cannot have a body; it must be provided at runtime + +- id: nscopying_only_on_class_properties + msg: >- + @NSCopying may only be used on properties in classes + +- id: nscopying_only_mutable + msg: >- + @NSCopying requires property to be mutable + +- id: nscopying_only_stored_property + msg: >- + @NSCopying is only valid on stored properties + +- id: nscopying_doesnt_conform + msg: >- + @NSCopying is only valid with types that conform to the NSCopying protocol + +- id: attr_ApplicationMain_not_ApplicationDelegate + msg: >- + %select{'UIApplicationMain'|'NSApplicationMain'|'main'}0 class must + conform to the %select{'UIApplicationDelegate'|'NSApplicationDelegate'}0 + protocol + +- id: attr_generic_ApplicationMain_not_supported + msg: >- + generic %select{'UIApplicationMain'|'NSApplicationMain'|'main'}0 + %select{classes|classes|types}0 are not supported + +- id: attr_ApplicationMain_multiple + msg: >- + %select{'UIApplicationMain'|'NSApplicationMain'|'main'}0 attribute can + only apply to one %select{class|class|type}0 in a module + +- id: attr_ApplicationMain_with_script + msg: >- + %select{'UIApplicationMain'|'NSApplicationMain'|'main'}0 attribute cannot + be used in a module that contains top-level code + +- id: attr_ApplicationMain_script_here + msg: >- + top-level code defined in this source file + +- id: attr_MainType_without_main + msg: >- + %0 is annotated with @main and must provide a main static function of + type () -> Void or () throws -> Void. + +- id: lazy_not_on_let + msg: >- + 'lazy' cannot be used on a let + +- id: lazy_not_on_computed + msg: >- + 'lazy' must not be used on a computed property + +- id: lazy_on_already_lazy_global + msg: >- + 'lazy' must not be used on an already-lazy global + +- id: lazy_not_in_protocol + msg: >- + 'lazy' isn't allowed on a protocol requirement + +- id: lazy_requires_initializer + msg: >- + lazy properties must have an initializer + +- id: lazy_requires_single_var + msg: >- + 'lazy' cannot destructure an initializer + +- id: lazy_must_be_property + msg: >- + lazy is only valid for members of a struct or class + +- id: lazy_not_strong + msg: >- + lazy properties cannot be %0 + +- id: attr_for_debugger_support_only + msg: >- + @LLDBDebuggerSupport may only be used when debugger support is on + +- id: implements_attr_protocol_lacks_member + msg: >- + protocol %0 has no member %1 + +- id: implements_attr_non_protocol_type + msg: >- + non-protocol type in @_implements attribute + +- id: implements_attr_protocol_not_conformed_to + msg: >- + containing type %0 does not conform to protocol %1 + +- id: differentiable_attr_no_vjp_or_jvp_when_linear + msg: >- + cannot specify 'vjp:' or 'jvp:' for linear functions; use '@transpose' + attribute for transpose registration instead + +- id: differentiable_attr_overload_not_found + msg: >- + %0 does not have expected type %1 + +- id: differentiable_attr_duplicate + msg: >- + duplicate '@differentiable' attribute with same parameters + +- id: differentiable_attr_duplicate_note + msg: >- + other attribute declared here + +- id: differentiable_attr_function_not_same_type_context + msg: >- + %0 is not defined in the current type context + +- id: differentiable_attr_derivative_not_function + msg: >- + registered derivative %0 must be a 'func' declaration + +- id: differentiable_attr_class_derivative_not_final + msg: >- + class member derivative must be final + +- id: differentiable_attr_invalid_access + msg: >- + derivative function %0 is required to either be public or + '@usableFromInline' because the original function %1 is public or + '@usableFromInline' + +- id: differentiable_attr_protocol_req_where_clause + msg: >- + '@differentiable' attribute on protocol requirement cannot specify + 'where' clause + +- id: differentiable_attr_class_member_dynamic_self_result_unsupported + msg: >- + '@differentiable' attribute cannot be declared on class members returning + 'Self' + +- id: differentiable_attr_nonfinal_class_init_unsupported + msg: >- + '@differentiable' attribute cannot be declared on 'init' in a non-final + class; consider making %0 final + +- id: differentiable_attr_empty_where_clause + msg: >- + empty 'where' clause in '@differentiable' attribute + +- id: differentiable_attr_where_clause_for_nongeneric_original + msg: >- + 'where' clause is valid only when original function is generic %0 + +- id: differentiable_attr_layout_req_unsupported + msg: >- + '@differentiable' attribute does not yet support layout requirements + +- id: overriding_decl_missing_differentiable_attr + msg: >- + overriding declaration is missing attribute '%0' + +- id: protocol_witness_missing_differentiable_attr + msg: >- + candidate is missing attribute '%0' + +- id: protocol_witness_missing_differentiable_attr_nonpublic_other_file + msg: >- + non-public %1 %2 must have explicit '%0' attribute to satisfy requirement + %3 %4 (in protocol %6) because it is declared in a different file than the + conformance of %5 to %6 + +- id: derivative_attr_expected_result_tuple + msg: >- + '@derivative(of:)' attribute requires function to return a two-element + tuple; first element must have label 'value:' and second element + must have label 'pullback:' or 'differential:' + +- id: derivative_attr_invalid_result_tuple_value_label + msg: >- + '@derivative(of:)' attribute requires function to return a two-element + tuple; first element must have label 'value:' + +- id: derivative_attr_invalid_result_tuple_func_label + msg: >- + '@derivative(of:)' attribute requires function to return a two-element + tuple; second element must have label 'pullback:' or 'differential:' + +- id: derivative_attr_result_value_not_differentiable + msg: >- + '@derivative(of:)' attribute requires function to return a two-element + tuple; first element type %0 must conform to 'Differentiable' + +- id: derivative_attr_result_func_type_mismatch + msg: >- + function result's %0 type does not match %1 + +- id: derivative_attr_result_func_type_mismatch_note + msg: >- + %0 does not have expected type %1 + +- id: derivative_attr_result_func_original_note + msg: >- + %0 defined here + +- id: derivative_attr_not_in_same_file_as_original + msg: >- + derivative not in the same file as the original function + +- id: derivative_attr_original_stored_property_unsupported + msg: >- + cannot register derivative for stored property %0 + +- id: derivative_attr_class_member_dynamic_self_result_unsupported + msg: >- + cannot register derivative for class member %0 returning 'Self' + +- id: derivative_attr_nonfinal_class_init_unsupported + msg: >- + cannot register derivative for 'init' in a non-final class; consider + making %0 final + +- id: derivative_attr_class_setter_unsupported + msg: >- + cannot yet register derivative for class property or subscript setters + +- id: derivative_attr_original_already_has_derivative + msg: >- + a derivative already exists for %0 + +- id: derivative_attr_duplicate_note + msg: >- + other attribute declared here + +- id: derivative_attr_access_level_mismatch + msg: >- + derivative function must have same access level as original function; + derivative function %2 is %select{private|fileprivate|internal|public|open}3, + but original function %0 is %select{private|fileprivate|internal|public|open}1 + +- id: derivative_attr_fix_access + msg: >- + mark the derivative function as + '%select{private|fileprivate|internal|@usableFromInline|@usableFromInline}0' + to match the original function + +- id: transpose_attr_invalid_linearity_parameter_or_result + msg: >- + cannot transpose with respect to original %select{result|parameter}1 '%0' + that does not conform to 'Differentiable' and satisfy '%0 == %0.TangentVector' + +- id: transpose_attr_overload_not_found + msg: >- + could not find function %0 with expected type %1 + +- id: transpose_attr_cannot_use_named_wrt_params + msg: >- + cannot use named 'wrt' parameters in '@transpose(of:)' attribute, found %0 + +- id: transpose_attr_wrt_self_must_be_static + msg: >- + the transpose of an instance method must be a 'static' method in the same + type when 'self' is a linearity parameter + +- id: transpose_attr_wrt_self_self_type_mismatch_note + msg: >- + the transpose is declared in %0 but the original function is declared in %1 + +- id: autodiff_attr_original_decl_invalid_kind + msg: >- + %0 is not a 'func', 'init', 'subscript', or 'var' computed property + declaration + +- id: autodiff_attr_accessor_not_found + msg: >- + %0 does not have a '%1' accessor + +- id: autodiff_attr_original_decl_none_valid_found + msg: >- + could not find function %0 with expected type %1 + +- id: autodiff_attr_original_decl_not_same_type_context + msg: >- + %0 is not defined in the current type context + +- id: autodiff_attr_original_void_result + msg: >- + cannot differentiate void function %0 + +- id: autodiff_attr_original_multiple_semantic_results + msg: >- + cannot differentiate functions with both an 'inout' parameter and a result + +- id: autodiff_attr_result_not_differentiable + msg: >- + can only differentiate functions with results that conform to + 'Differentiable', but %0 does not conform to 'Differentiable' + +- id: diff_function_no_parameters + msg: >- + %0 has no parameters to differentiate with respect to + +- id: diff_params_clause_param_name_unknown + msg: >- + unknown parameter name %0 + +- id: diff_params_clause_self_instance_method_only + msg: >- + 'self' parameter is only applicable to instance methods + +- id: diff_params_clause_self_must_be_first + msg: >- + 'self' parameter must come first in the parameter list + +- id: diff_params_clause_params_not_original_order + msg: >- + parameters must be specified in original order + +- id: diff_params_clause_param_index_out_of_range + msg: >- + parameter index is larger than total number of parameters + +- id: diff_params_clause_no_inferred_parameters + msg: >- + no differentiation parameters could be inferred; must differentiate with + respect to at least one parameter conforming to 'Differentiable' + +- id: diff_params_clause_cannot_diff_wrt_inout_parameter + msg: >- + cannot differentiate with respect to 'inout' parameter (%0) + +- id: diff_params_clause_param_not_differentiable + msg: >- + can only differentiate with respect to parameters that conform to + 'Differentiable', but %0 does not conform to 'Differentiable' + +- id: found_candidate + msg: >- + found this candidate + +- id: found_candidate_type + msg: >- + found candidate with type %0 + +- id: no_MaxBuiltinFloatType_found + msg: >- + standard library error: _MaxBuiltinFloatType is not properly defined + +- id: no_member_of_module + msg: >- + module %0 has no member named %1 + +- id: super_with_no_base_class + msg: >- + 'super' members cannot be referenced in a root class + +- id: bad_init_ref_base + msg: >- + 'init' can only refer to the initializers of 'self'%select{| or 'super'}0 + +- id: init_delegation_outside_initializer + msg: >- + initializer delegation can only occur within an initializer + +- id: init_delegates_and_chains + msg: >- + initializer cannot both delegate ('self.init') and chain to a superclass + initializer ('super.init') + +- id: init_delegation_or_chain + msg: >- + previous %select{delegation|chaining}0 call is here + +- id: delegating_convenience_super_init + msg: >- + convenience initializer for %0 must delegate (with 'self.init') rather + than chaining to a superclass initializer (with 'super.init') + +- id: delegating_designated_init + msg: >- + designated initializer for %0 cannot delegate (with 'self.init'); did you + mean this to be a convenience initializer? + +- id: delegating_designated_init_in_extension + msg: >- + designated initializer for %0 cannot delegate (with 'self.init') + +- id: delegation_here + msg: >- + delegation occurs here + +- id: chain_convenience_init + msg: >- + must call a designated initializer of the superclass %0 + +- id: delegate_chain_nonoptional_to_optional + msg: >- + a non-failable initializer cannot %select{delegate|chain}0 to failable + initializer %1 written with 'init?' + +- id: init_force_unwrap + msg: >- + force potentially-failing result with '!' + +- id: init_propagate_failure + msg: >- + propagate the failure with 'init?' + +- id: delegate_chain_nonoptional_to_optional_try + msg: >- + a non-failable initializer cannot use 'try?' to %select{delegate|chain}0 + to another initializer + +- id: init_delegate_force_try + msg: >- + force potentially-failing result with 'try!' + +- id: init_delegation_nested + msg: >- + %select{initializer delegation ('self.init')|initializer chaining + ('super.init')}0 cannot be nested in another %select{expression|statement}1 + +- id: convenience_init_here + msg: >- + convenience initializer is declared here + +- id: designated_init_in_extension + msg: >- + designated initializer cannot be declared in an extension of %0; did you + mean this to be a convenience initializer? + +- id: cfclass_designated_init_in_extension + msg: >- + designated initializer cannot be declared in an extension of %0 + +- id: enumstruct_convenience_init + msg: >- + delegating initializers in %0 are not marked with 'convenience' + +- id: nonclass_convenience_init + msg: >- + convenience initializer not allowed in non-class type %0 + +- id: cfclass_convenience_init + msg: >- + convenience initializers are not supported in extensions of CF types + +- id: dynamic_construct_class + msg: >- + constructing an object of class type %0 with a metatype value must use a + 'required' initializer + +- id: note_nonrequired_initializer + msg: >- + selected %select{non-required|implicit}0 initializer %1 + +- id: construct_protocol_value + msg: >- + value of type %0 is a protocol; it cannot be instantiated + +- id: construct_protocol_by_name + msg: >- + protocol type %0 cannot be instantiated + +- id: unknown_binop + msg: >- + operator is not a known binary operator + +- id: non_associative_adjacent_operators + msg: >- + adjacent operators are in non-associative precedence group %0 + +- id: unordered_adjacent_operators + msg: >- + adjacent operators are in unordered precedence groups %0 and %1 + +- id: missing_builtin_precedence_group + msg: >- + broken standard library: missing builtin precedence group %0 + +- id: try_rhs + msg: >- + '%select{try|try!|try?}0' cannot appear to the right of a non-assignment + operator + +- id: try_if_rhs_noncovering + msg: >- + '%select{try|try!|try?}0' following conditional operator does not cover + everything to its right + +- id: try_assign_rhs_noncovering + msg: >- + '%select{try|try!|try?}0' following assignment operator does not cover + everything to its right + +- id: broken_bool + msg: >- + type 'Bool' is broken + +- id: inject_forced_downcast + msg: >- + treating a forced downcast to %0 as optional will never produce 'nil' + +- id: forced_to_conditional_downcast + msg: >- + use 'as?' to perform a conditional downcast to %0 + +- id: silence_inject_forced_downcast + msg: >- + add parentheses around the cast to silence this warning + +- id: conditional_downcast_foreign + msg: >- + conditional downcast to CoreFoundation type %0 will always succeed + +- id: note_explicitly_compare_cftypeid + msg: >- + did you mean to explicitly compare the CFTypeIDs of %0 and %1? + +- id: optional_used_as_boolean + msg: >- + optional type %0 cannot be used as a boolean; test for '%select{!|=}1= + nil' instead + +- id: integer_used_as_boolean + msg: >- + type %0 cannot be used as a boolean; test for '%select{!|=}1= 0' instead + +- id: interpolation_missing_proto + msg: >- + string interpolation requires the protocol + 'ExpressibleByStringInterpolation' to be defined + +- id: interpolation_broken_proto + msg: >- + protocol 'ExpressibleByStringInterpolation' is broken + +- id: object_literal_broken_proto + msg: >- + object literal protocol is broken + +- id: discard_expr_outside_of_assignment + msg: >- + '_' can only appear in a pattern or on the left side of an assignment + +- id: discard_expr_void_result_redundant + msg: >- + using '_' to ignore the result of a Void-returning function is redundant + +- id: collection_literal_heterogeneous + msg: >- + heterogeneous collection literal could only be inferred to %0; add + explicit type annotation if this is intentional + +- id: collection_literal_empty + msg: >- + empty collection literal requires an explicit type + +- id: unresolved_member_no_inference + msg: >- + reference to member %0 cannot be resolved without a contextual type + +- id: cannot_infer_base_of_unresolved_member + msg: >- + cannot infer contextual base in reference to member %0 + +- id: unresolved_nil_literal + msg: >- + 'nil' requires a contextual type + +- id: cannot_force_unwrap_nil_literal + msg: >- + 'nil' literal cannot be force unwrapped + +- id: type_of_expression_is_ambiguous + msg: >- + type of expression is ambiguous without more context + +- id: failed_to_produce_diagnostic + msg: >- + failed to produce diagnostic for expression; please file a bug report + +- id: missing_protocol + msg: >- + missing protocol %0 + +- id: nil_literal_broken_proto + msg: >- + protocol 'ExpressibleByNilLiteral' is broken + +- id: builtin_integer_literal_broken_proto + msg: >- + protocol '_ExpressibleByBuiltinIntegerLiteral' is broken + +- id: integer_literal_broken_proto + msg: >- + protocol 'ExpressibleByIntegerLiteral' is broken + +- id: builtin_float_literal_broken_proto + msg: >- + protocol '_ExpressibleByBuiltinFloatLiteral' is broken + +- id: float_literal_broken_proto + msg: >- + protocol 'ExpressibleByFloatLiteral' is broken + +- id: builtin_boolean_literal_broken_proto + msg: >- + protocol '_ExpressibleByBuiltinBooleanLiteral' is broken + +- id: boolean_literal_broken_proto + msg: >- + protocol 'ExpressibleByBooleanLiteral' is broken + +- id: builtin_unicode_scalar_literal_broken_proto + msg: >- + protocol '_ExpressibleByBuiltinUnicodeScalarLiteral' is broken + +- id: unicode_scalar_literal_broken_proto + msg: >- + protocol 'ExpressibleByUnicodeScalarLiteral' is broken + +- id: builtin_extended_grapheme_cluster_literal_broken_proto + msg: >- + protocol '_ExpressibleByBuiltinExtendedGraphemeClusterLiteral' is broken + +- id: extended_grapheme_cluster_literal_broken_proto + msg: >- + protocol 'ExpressibleByExtendedGraphemeClusterLiteral' is broken + +- id: builtin_string_literal_broken_proto + msg: >- + protocol '_ExpressibleByBuiltinStringLiteral' is broken + +- id: string_literal_broken_proto + msg: >- + protocol 'ExpressibleByStringLiteral' is broken + +- id: should_use_dictionary_literal + msg: >- + dictionary of type %0 cannot be %select{used|initialized}1 with array + literal + +- id: meant_dictionary_lit + msg: >- + did you mean to use a dictionary literal instead? + +- id: should_use_empty_dictionary_literal + msg: >- + use [:] to get an empty dictionary literal + +- id: type_is_not_dictionary + msg: >- + contextual type %0 cannot be used with dictionary literal + +- id: cannot_explicitly_specialize_generic_function + msg: >- + cannot explicitly specialize a generic function + +- id: not_a_generic_definition + msg: >- + cannot specialize a non-generic definition + +- id: not_a_generic_type + msg: >- + cannot specialize non-generic type %0 + +- id: type_parameter_count_mismatch + msg: >- + generic type %0 specialized with %select{too many|too few}3 type + parameters (got %2, but expected %1) + +- id: generic_type_requires_arguments + msg: >- + reference to generic type %0 requires arguments in <...> + +- id: descriptive_generic_type_declared_here + msg: >- + %0 declared here + +- id: use_of_void_pointer + msg: >- + Unsafe%0Pointer has been replaced by Unsafe%0RawPointer + +- id: ambiguous_decl_ref + msg: >- + ambiguous use of %0 + +- id: ambiguous_operator_ref + msg: >- + ambiguous use of operator %0 + +- id: ambiguous_because_of_trailing_closure + msg: >- + %select{use an explicit argument label instead of a trailing + closure|avoid using a trailing closure}0 to call %1 + +- id: partial_application_of_function_invalid + msg: >- + partial application of %select{'mutating' method|'super.init' initializer + chain|'self.init' initializer delegation|'super' instance method with + metatype base}0 is not allowed + +- id: partial_application_of_function_invalid_swift4 + msg: >- + partial application of %select{'mutating' method|'super.init' initializer + chain|'self.init' initializer delegation|'super' instance method with + metatype base}0 is not allowed; calling the function has undefined + behavior and will be an error in future Swift versions + +- id: self_assignment_var + msg: >- + assigning a variable to itself + +- id: self_assignment_prop + msg: >- + assigning a property to itself + +- id: property_use_in_closure_without_explicit_self + msg: >- + reference to property %0 in closure requires explicit use of 'self' to + make capture semantics explicit + +- id: method_call_in_closure_without_explicit_self + msg: >- + call to method %0 in closure requires explicit use of 'self' to make + capture semantics explicit + +- id: note_capture_self_explicitly + msg: >- + capture 'self' explicitly to enable implicit 'self' in this closure + +- id: note_reference_self_explicitly + msg: >- + reference 'self.' explicitly + +- id: note_other_self_capture + msg: >- + variable other than 'self' captured here under the name 'self' does not + enable implicit 'self' + +- id: note_self_captured_weakly + msg: >- + weak capture of 'self' here does not enable implicit 'self' + +- id: implicit_use_of_self_in_closure + msg: >- + implicit use of 'self' in closure; use 'self.' to make capture semantics + explicit + +- id: recursive_accessor_reference + msg: >- + attempting to %select{access|modify}1 %0 within its own + %select{getter|setter}1 + +- id: recursive_accessor_reference_silence + msg: >- + access 'self' explicitly to silence this warning + +- id: store_in_willset + msg: >- + attempting to store to property %0 within its own willSet, which is about + to be overwritten by the new value + +- id: value_of_module_type + msg: >- + expected module member name after module name + +- id: value_of_metatype_type + msg: >- + expected member name or constructor call after type name + +- id: add_parens_to_type + msg: >- + add arguments after the type to construct a value of the type + +- id: add_self_to_type + msg: >- + use '.self' to reference the type object + +- id: warn_unqualified_access + msg: >- + use of %0 treated as a reference to %1 in %2 %3 + +- id: fix_unqualified_access_member + msg: >- + use 'self.' to silence this warning + +- id: fix_unqualified_access_top_level + msg: >- + use '%0' to reference the %1 + +- id: fix_unqualified_access_top_level_multi + msg: >- + use '%0' to reference the %1 in module %2 + +- id: warn_deprecated_conditional_conformance_outer_access + msg: >- + use of %0 as reference to %1 in %2 %3 will change in future versions of + Swift to reference %4 in %5 %6 which comes via a conditional conformance + +- id: fix_deprecated_conditional_conformance_outer_access + msg: >- + use '%0' to continue to reference the %1 + +- id: unsupported_special_decl_ref + msg: >- + referencing %0 as a function value is not implemented + +- id: bitcasting_away_noescape + msg: >- + 'unsafeBitCast' from non-escaping function type %0 to escaping function + type %1 is undefined; use 'withoutActuallyEscaping' to temporarily escape a + function + +- id: bitcasting_to_change_function_rep + msg: >- + 'unsafeBitCast' from function type %0 to %1 changes @convention and is + undefined; use an implicit conversion to change conventions + +- id: bitcasting_to_downcast + msg: >- + 'unsafeBitCast' from %0 to %1 can be replaced with 'unsafeDowncast' + +- id: bitcasting_is_no_op + msg: >- + 'unsafeBitCast' from %0 to %1 is unnecessary and can be removed + +- id: bitcasting_to_change_pointer_kind + msg: >- + 'unsafeBitCast' from %0 to %1 can be replaced with %2 initializer + +- id: bitcasting_to_change_pointee_type + msg: >- + 'unsafeBitCast' from %0 to %1 changes pointee type and may lead to + undefined behavior; use the 'withMemoryRebound' method on %0 + to rebind the type of memory + +- id: bitcasting_to_give_type_to_raw_pointer + msg: >- + 'unsafeBitCast' from %0 to %1 gives a type to a raw pointer and may lead + to undefined behavior + +- id: bitcast_assume_memory_rebound + msg: >- + use the 'assumingMemoryBound' method if the pointer is known to point to + an existing value or array of type %0 in memory + +- id: bitcast_bind_memory + msg: >- + use the 'bindMemory' method to assign type %0 to uninitialized raw memory + +- id: bitcasting_for_number_bit_pattern_init + msg: >- + 'unsafeBitCast' from %0 to %1 can be replaced with 'bitPattern:' + initializer on %1 + +- id: bitcasting_for_number_bit_pattern_property + msg: >- + 'unsafeBitCast' from %0 to %1 can be replaced with 'bitPattern' property + on %0 + +- id: bitcasting_to_change_from_unsized_to_sized_int + msg: >- + 'unsafeBitCast' from %0 to %1 can be replaced with %1 initializer + +- id: use_of_qq_on_non_optional_value + msg: >- + left side of nil coalescing operator '??' has non-optional type %0, so + the right side is never used + +- id: nonoptional_compare_to_nil + msg: >- + comparing non-optional value of type %0 to 'nil' always returns + %select{false|true}1 + +- id: optional_check_nonoptional + msg: >- + non-optional expression of type %0 used in a check for optionals + +- id: optional_check_promotion + msg: >- + explicitly specified type %0 adds an additional level of optional to the + initializer, making the optional check always succeed + +- id: optional_pattern_match_promotion + msg: >- + pattern match introduces an implicit promotion from %0 to %1 + +- id: optional_to_any_coercion + msg: >- + expression implicitly coerced from %0 to %1 + +- id: iuo_to_any_coercion + msg: >- + coercion of implicitly unwrappable value of type %0 to %1 does not unwrap + optional + +- id: iuo_to_any_coercion_note + msg: >- + implicitly unwrapped %0 %1 declared here + +- id: iuo_to_any_coercion_note_func_result + msg: >- + %0 %1 with implicitly unwrapped result type is declared here + +- id: default_optional_to_any + msg: >- + provide a default value to avoid this warning + +- id: force_optional_to_any + msg: >- + force-unwrap the value to avoid this warning + +- id: silence_optional_to_any + msg: >- + explicitly cast to %0 with '%1' to silence this warning + +- id: debug_description_in_string_interpolation_segment + msg: >- + string interpolation produces a debug description for %select{an + optional|a function}0 value; did you mean to make this explicit? + +- id: silence_debug_description_in_interpolation_segment_call + msg: >- + use 'String(describing:)' to silence this warning + +- id: noescape_parameter + msg: >- + parameter %0 is implicitly non-escaping + +- id: generic_parameters_always_escaping + msg: >- + generic parameters are always considered '@escaping' + +- id: passing_noescape_to_escaping + msg: >- + passing non-escaping parameter %0 to function expecting an @escaping closure + +- id: converting_noespace_param_to_generic_type + msg: >- + converting non-escaping parameter %0 to generic parameter %1 may allow it + to escape + +- id: assigning_noescape_to_escaping + msg: >- + assigning non-escaping parameter %0 to an @escaping closure + +- id: general_noescape_to_escaping + msg: >- + using non-escaping parameter %0 in a context expecting an @escaping closure + +- id: converting_noescape_to_type + msg: >- + converting non-escaping value to %0 may allow it to escape + +- id: capture_across_type_decl + msg: >- + %0 declaration cannot close over value %1 defined in outer scope + +- id: jump_out_of_defer + msg: >- + '%0' cannot transfer control out of a defer statement + +- id: defer_stmt_at_block_end + msg: >- + 'defer' statement at end of scope always executes immediately; replace + with 'do' statement to silence this warning + +- id: return_invalid_outside_func + msg: >- + return invalid outside of a func + +- id: return_expr_missing + msg: >- + non-void function should return a value + +- id: return_non_failable_init + msg: >- + only a failable initializer can return 'nil' + +- id: make_init_failable + msg: >- + use 'init?' to make the initializer %0 failable + +- id: return_init_non_nil + msg: >- + 'nil' is the only return value permitted in an initializer + +- id: if_always_true + msg: >- + 'if' condition is always true + +- id: while_always_true + msg: >- + 'while' condition is always true + +- id: guard_always_succeeds + msg: >- + 'guard' condition is always true, body is unreachable + +- id: expression_unused_closure + msg: >- + closure expression is unused + +- id: expression_unused_function + msg: >- + expression resolves to an unused function + +- id: expression_unused_lvalue + msg: >- + expression resolves to an unused %select{variable|property|subscript}0 + +- id: expression_unused_result_call + msg: >- + result of call to %0 is unused + +- id: expression_unused_result_operator + msg: >- + result of operator %0 is unused + +- id: expression_unused_result_unknown + msg: >- + result of call to %select{function|closure}0 returning %1 is unused + +- id: expression_unused_result + msg: >- + expression of type %0 is unused + +- id: expression_unused_init_result + msg: >- + result of %0 initializer is unused + +- id: expression_unused_optional_try + msg: >- + result of 'try?' is unused + +- id: expression_unused_selector_result + msg: >- + result of '#selector' is unused + +- id: expression_unused_literal + msg: >- + %0 literal is unused + +- id: assignment_lhs_not_lvalue + msg: >- + cannot assign to immutable expression of type %0 + +- id: assignment_lhs_is_apply_expression + msg: >- + expression is not assignable: %0 + +- id: assignment_lhs_is_immutable_variable + msg: >- + cannot assign to value: %0 + +- id: assignment_lhs_is_immutable_property + msg: >- + cannot assign to property: %0 + +- id: assignment_subscript_has_immutable_base + msg: >- + cannot assign through subscript: %0 + +- id: assignment_dynamic_property_has_immutable_base + msg: >- + cannot assign through dynamic lookup property: %0 + +- id: assignment_bang_has_immutable_subcomponent + msg: >- + cannot assign through '!': %0 + +- id: candidate_is_not_assignable + msg: >- + candidate is not assignable: %0 %1 + +- id: change_to_mutating + msg: >- + mark %select{method|accessor}0 'mutating' to make 'self' mutable + +- id: masked_mutable_property + msg: >- + add explicit '%0' to refer to mutable %1 of %2 + +- id: assignment_let_property_delegating_init + msg: >- + 'let' property %0 may not be initialized directly; use "self.init(...)" + or "self = ..." instead + +- id: label_shadowed + msg: >- + label %0 cannot be reused on an inner statement + +- id: break_outside_loop + msg: >- + 'break' is only allowed inside a loop, if, do, or switch + +- id: unlabeled_break_outside_loop + msg: >- + unlabeled 'break' is only allowed inside a loop or switch, a labeled + break is required to exit an if or do + +- id: continue_outside_loop + msg: >- + 'continue' is only allowed inside a loop + +- id: continue_not_in_this_stmt + msg: >- + 'continue' cannot be used with %0 statements + +- id: unresolved_label + msg: >- + cannot find label %0 in scope + +- id: unresolved_label_corrected + msg: >- + cannot find label %0 in scope; did you mean %1? + +- id: foreach_sequence_does_not_conform_to_expected_protocol + msg: >- + for-in loop requires %0 to conform to %1%select{|; did you mean to unwrap + optional?}2 + +- id: no_match_operator + msg: >- + no binary '~=' operator available for 'switch' statement + +- id: fallthrough_outside_switch + msg: >- + 'fallthrough' is only allowed inside a switch + +- id: fallthrough_from_last_case + msg: >- + 'fallthrough' without a following 'case' or 'default' block + +- id: fallthrough_into_case_with_var_binding + msg: >- + 'fallthrough' from a case which doesn't bind variable %0 + +- id: unnecessary_cast_over_optionset + msg: >- + unnecessary cast over raw value of %0 + +- id: mutability_mismatch_multiple_pattern_list + msg: >- + '%select{var|let}0' pattern binding must match previous + '%select{var|let}1' pattern binding + +- id: type_mismatch_multiple_pattern_list + msg: >- + pattern variable bound to type %0, expected type %1 + +- id: type_mismatch_fallthrough_pattern_list + msg: >- + pattern variable bound to type %0, fallthrough case bound to type %1 + +- id: unknown_case_must_be_catchall + msg: >- + '@unknown' is only supported for catch-all cases ("case _") + +- id: unknown_case_where_clause + msg: >- + 'where' cannot be used with '@unknown' + +- id: unknown_case_multiple_patterns + msg: >- + '@unknown' cannot be applied to multiple patterns + +- id: unknown_case_must_be_last + msg: >- + '@unknown' can only be applied to the last case in a switch + +- id: where_on_one_item + msg: >- + 'where' only applies to the second pattern match in this case + +- id: add_where_newline + msg: >- + disambiguate by adding a line break between them if this is desired + +- id: duplicate_where + msg: >- + duplicate the 'where' on both patterns to check both patterns + +- id: trailing_closure_requires_parens + msg: >- + trailing closure in this context is confusable with the body of the + statement; pass as a parenthesized argument to silence this warning + +- id: opaque_type_var_no_init + msg: >- + property declares an opaque return type, but has no initializer + expression from which to infer an underlying type + +- id: opaque_type_no_underlying_type_candidates + msg: >- + function declares an opaque return type, but has no return statements in + its body from which to infer an underlying type + +- id: opaque_type_mismatched_underlying_type_candidates + msg: >- + function declares an opaque return type, but the return statements in its + body do not have matching underlying types + +- id: opaque_type_underlying_type_candidate_here + msg: >- + return statement has underlying type %0 + +- id: opaque_type_self_referential_underlying_type + msg: >- + function opaque return type was inferred as %0, which defines the opaque + type in terms of itself + +- id: opaque_type_var_no_underlying_type + msg: >- + property declares an opaque return type, but cannot infer the underlying + type from its initializer expression + +- id: cannot_infer_type_for_pattern + msg: >- + type annotation missing in pattern + +- id: refutable_pattern_requires_initializer + msg: >- + pattern matching requires an initializer value to match against + +- id: var_pattern_didnt_bind_variables + msg: >- + '%0' pattern has no effect; sub-pattern didn't bind any variables + +- id: iflet_pattern_matching + msg: >- + pattern matching in a condition requires the 'case' keyword + +- id: iflet_implicitly_unwraps + msg: >- + pattern matching in a condition implicitly unwraps optionals + +- id: type_pattern_missing_is + msg: >- + 'is' keyword required to pattern match against type name + +- id: pattern_type_mismatch_context + msg: >- + type annotation does not match contextual type %0 + +- id: tuple_pattern_in_non_tuple_context + msg: >- + tuple pattern cannot match values of the non-tuple type %0 + +- id: found_one_pattern_for_several_associated_values + msg: >- + enum case '%0' has %1 associated values; matching them as a tuple is + deprecated + +- id: converting_tuple_into_several_associated_values + msg: >- + enum case '%0' has %1 associated values + +- id: converting_several_associated_values_into_tuple + msg: >- + enum case '%0' has one associated value that is a tuple of %1 elements + +- id: closure_argument_list_tuple + msg: >- + contextual closure type %0 expects %1 argument%s1, but %2 + %select{were|was}3 used in closure body + +- id: closure_argument_list_missing + msg: >- + contextual type for closure argument list expects %0 argument%s0, which + cannot be implicitly ignored + +- id: closure_tuple_parameter_destructuring + msg: >- + closure tuple parameter %0 does not support destructuring + +- id: closure_tuple_parameter_destructuring_implicit + msg: >- + closure tuple parameter %0 does not support destructuring with implicit + parameters + +- id: single_tuple_parameter_mismatch_special + msg: >- + %0 expects a single parameter of type %1%2 + +- id: single_tuple_parameter_mismatch_normal + msg: >- + %0 %1 expects a single parameter of type %2%3 + +- id: cannot_convert_single_tuple_into_multiple_arguments + msg: >- + %0 %select{%1 |}2expects %3 separate arguments%select{|; remove extra + parentheses to change tuple into separate arguments}4 + +- id: enum_element_pattern_assoc_values_mismatch + msg: >- + pattern with associated values does not match enum case %0 + +- id: enum_element_pattern_assoc_values_remove + msg: >- + remove associated values to make the pattern match + +- id: tuple_pattern_length_mismatch + msg: >- + tuple pattern has the wrong length for tuple type %0 + +- id: tuple_pattern_label_mismatch + msg: >- + tuple pattern element label %0 must be %1 + +- id: enum_element_pattern_member_not_found + msg: >- + enum case %0 not found in type %1 + +- id: optional_element_pattern_not_valid_type + msg: >- + '?' pattern cannot match values of type %0 + +- id: condition_optional_element_pattern_not_valid_type + msg: >- + initializer for conditional binding must have Optional type, not %0 + +- id: enum_element_pattern_not_member_of_enum + msg: >- + enum case %0 is not a member of type %1 + +- id: ambiguous_enum_pattern_type + msg: >- + generic enum type %0 is ambiguous without explicit generic parameters + when matching value of type %1 + +- id: type_inferred_to_undesirable_type + msg: >- + %select{variable|constant}2 %0 inferred to have type %1, which may be + unexpected + +- id: type_inferred_to_uninhabited_type + msg: >- + %select{variable|constant}2 %0 inferred to have type %1, which is an enum + with no cases + +- id: type_inferred_to_uninhabited_tuple_type + msg: >- + %select{variable|constant}2 %0 inferred to have type %1, which contains + an enum with no cases + +- id: add_explicit_type_annotation_to_silence + msg: >- + add an explicit type annotation to silence this warning + +- id: unowned_assignment_immediate_deallocation + msg: >- + instance will be immediately deallocated because + %select{variable|property}2 %0 is %1 + +- id: unowned_assignment_requires_strong + msg: >- + a strong reference is required to prevent the instance from being + deallocated + +- id: isa_collection_downcast_pattern_value_unimplemented + msg: >- + collection downcast in cast pattern is not implemented; use an explicit + downcast to %0 instead + +- id: try_unhandled + msg: >- + errors thrown from here are not handled + +- id: throwing_call_unhandled + msg: >- + call can throw, but the error is not handled + +- id: tryless_throwing_call_unhandled + msg: >- + call can throw, but it is not marked with 'try' and the error is not handled + +- id: throw_in_nonthrowing_function + msg: >- + error is not handled because the enclosing function is not declared 'throws' + +- id: throwing_call_in_rethrows_function + msg: >- + call can throw, but the error is not handled; a function declared + 'rethrows' may only throw if its parameter does + +- id: tryless_throwing_call_in_rethrows_function + msg: >- + call can throw, but it is not marked with 'try' and the error is not + handled; a function declared 'rethrows' may only throw if its parameter does + +- id: throw_in_rethrows_function + msg: >- + a function declared 'rethrows' may only throw if its parameter does + +- id: because_rethrows_argument_throws + msg: >- + call is to 'rethrows' function, but argument function can throw + +- id: because_rethrows_default_argument_throws + msg: >- + call is to 'rethrows' function, but a defaulted argument function can throw + +- id: throwing_call_in_nonthrowing_autoclosure + msg: >- + call can throw, but it is executed in a non-throwing autoclosure + +- id: tryless_throwing_call_in_nonthrowing_autoclosure + msg: >- + call can throw, but it is not marked with 'try' and it is executed in a + non-throwing autoclosure + +- id: throw_in_nonthrowing_autoclosure + msg: >- + error is not handled because it is thrown in a non-throwing autoclosure + +- id: try_unhandled_in_nonexhaustive_catch + msg: >- + errors thrown from here are not handled because the enclosing catch is + not exhaustive + +- id: throwing_call_in_nonexhaustive_catch + msg: >- + call can throw, but the enclosing catch is not exhaustive + +- id: tryless_throwing_call_in_nonexhaustive_catch + msg: >- + call can throw, but it is not marked with 'try' and the enclosing catch + is not exhaustive + +- id: throw_in_nonexhaustive_catch + msg: >- + error is not handled because the enclosing catch is not exhaustive + +- id: throwing_call_in_illegal_context + msg: >- + call can throw, but errors cannot be thrown out of %0 + +- id: throw_in_illegal_context + msg: >- + errors cannot be thrown out of %0 + +- id: throwing_operator_without_try + msg: >- + operator can throw but expression is not marked with 'try' + +- id: throwing_interpolation_without_try + msg: >- + interpolation can throw but is not marked with 'try' + +- id: throwing_call_without_try + msg: >- + call can throw but is not marked with 'try' + +- id: note_forgot_try + msg: >- + did you mean to use 'try'? + +- id: note_error_to_optional + msg: >- + did you mean to handle error as optional value? + +- id: note_disable_error_propagation + msg: >- + did you mean to disable error propagation? + +- id: no_throw_in_try + msg: >- + no calls to throwing functions occur within 'try' expression + +- id: no_throw_in_do_with_catch + msg: >- + 'catch' block is unreachable because no errors are thrown in 'do' block + +- id: unsupported_recursive_struct + msg: >- + value type %0 cannot have a stored property that recursively contains it + +- id: enum_non_well_founded + msg: >- + enum containing only recursive cases is impossible to instantiate + +- id: recursive_enum_not_indirect + msg: >- + recursive enum %0 is not marked 'indirect' + +- id: unsupported_infinitely_sized_type + msg: >- + value type %0 has infinite size + +- id: note_type_cycle_starts_here + msg: >- + cycle beginning here: %0 + +- id: note_recursive_enum_case_here + msg: >- + recursive case here + +- id: sugar_type_not_found + msg: >- + broken standard library: cannot find + %select{Array|Optional|ImplicitlyUnwrappedOptional|Dictionary|Error}0 type + +- id: optional_intrinsics_not_found + msg: >- + broken standard library: cannot find intrinsic operations on Optional + +- id: pointer_argument_intrinsics_not_found + msg: >- + broken standard library: cannot find intrinsic operations on + UnsafeMutablePointer + +- id: array_literal_intrinsics_not_found + msg: >- + broken standard library: cannot find intrinsic operations on Array + +- id: class_super_access + msg: >- + class %select{must be declared + %select{%select{private|fileprivate|internal|%error|%error}1|private or + fileprivate}3|cannot be declared %select{in this + context|fileprivate|internal|public|open}1}0 because its superclass + %select{is %select{private|fileprivate|internal|'@_spi'|'@_spi'}2|uses + %select{a private|a fileprivate|an internal|an '@_spi'|an '@_spi'}2 + type as a generic parameter}4 + +- id: class_super_access_warn + msg: >- + class %select{should be declared + %select{private|fileprivate|internal|%error|%error}1|should not be declared + %select{in this context|fileprivate|internal|public|open}1}0 because its + superclass %select{is + %select{private|fileprivate|internal|'@_spi'|'@_spi'}2|uses + %select{a private|a + fileprivate|an internal|an '@_spi'|an '@_spi'}2 + type as a generic parameter}4 + +- id: class_super_not_usable_from_inline + msg: >- + %select{type referenced from |}0the superclass of a '@usableFromInline' + class must be '@usableFromInline' or public + +- id: class_super_not_usable_from_inline_warn + msg: >- + %select{type referenced from |}0the superclass of a '@usableFromInline' + class should be '@usableFromInline' or public + +- id: dot_protocol_on_non_existential + msg: >- + cannot use 'Protocol' with non-protocol type %0 + +- id: tuple_single_element + msg: >- + cannot create a single-element tuple with an element label + +- id: tuple_ellipsis + msg: >- + cannot create a variadic tuple + +- id: tuple_duplicate_label + msg: >- + cannot create a tuple with a duplicate element label + +- id: enum_element_ellipsis + msg: >- + variadic enum cases are not supported + +- id: implicitly_unwrapped_optional_in_illegal_position_interpreted_as_optional + msg: >- + using '!' is not allowed here; treating this as '?' instead + +- id: implicitly_unwrapped_optional_deprecated_in_this_position + msg: >- + using '!' here is deprecated and will be removed in a future release + +- id: implicitly_unwrapped_optional_in_illegal_position + msg: >- + using '!' is not allowed here; perhaps '?' was intended? + +- id: invalid_ownership_type + msg: >- + %0 may only be applied to class and class-bound protocol types, not %1 + +- id: invalid_ownership_protocol_type + msg: >- + %0 must not be applied to non-class-bound %1; consider adding a protocol + conformance that has a class bound + +- id: invalid_ownership_incompatible_class + msg: >- + %0 is incompatible with %1 references + +- id: invalid_ownership_with_optional + msg: >- + %0 variable cannot have optional type + +- id: invalid_ownership_not_optional + msg: >- + %0 variable should have optional type %1 + +- id: invalid_ownership_is_let + msg: >- + %0 must be a mutable variable, because it may change at runtime + +- id: ownership_invalid_in_protocols + msg: >- + %0 cannot be applied to a property declaration in a protocol + +- id: ownership_invalid_in_protocols_compat_warning + msg: >- + %0 should not be applied to a property declaration in a protocol and will + be disallowed in future versions + +- id: required_initializer_nonclass + msg: >- + 'required' initializer in non-class type %0 + +- id: required_initializer_in_extension + msg: >- + 'required' initializer must be declared directly in class %0 (not in an + extension) + +- id: required_initializer_missing + msg: >- + 'required' initializer %0 must be provided by subclass of %1 + +- id: required_initializer_here + msg: >- + 'required' initializer is declared in superclass here + +- id: required_initializer_not_accessible + msg: >- + 'required' initializer must be accessible wherever class %0 can be + subclassed + +- id: required_initializer_missing_keyword + msg: >- + 'required' modifier must be present on all overrides of a required + initializer + +- id: required_initializer_override_wrong_keyword + msg: >- + use the 'required' modifier to override a required initializer + +- id: required_initializer_override_keyword + msg: >- + 'override' is implied when overriding a required initializer + +- id: overridden_required_initializer_here + msg: >- + overridden required initializer is here + +- id: attribute_requires_function_type + msg: >- + @%0 attribute only applies to function types + +- id: unsupported_convention + msg: >- + convention '%0' not supported + +- id: unreferenced_generic_parameter + msg: >- + generic parameter '%0' is not used in function signature + +- id: unexpected_ctype_for_non_c_convention + msg: >- + convention '%0' does not support the 'cType' argument label, did you mean + @convention(c, cType: "%1") or @convention(block, cType: "%1") instead? + +- id: unable_to_parse_c_function_type + msg: >- + unable to parse '%0'; it should be a C function pointer type or a block + pointer type + +- id: unsupported_opaque_type + msg: >- + 'some' types are only implemented for the declared type of properties and + subscripts and the return type of functions + +- id: opaque_type_unsupported_pattern + msg: >- + 'some' type can only be declared on a single property declaration + +- id: opaque_type_in_protocol_requirement + msg: >- + 'some' type cannot be the return type of a protocol requirement; + did you mean to add an associated type? + +- id: attr_only_on_parameters_of_differentiable + msg: >- + '%0' may only be used on parameters of '@differentiable' function types + +- id: differentiable_function_type_invalid_parameter + msg: >- + parameter type '%0' does not conform to 'Differentiable'%select{| and + satisfy '%0 == %0.TangentVector'}1, but the enclosing function type is + '@differentiable%select{|(linear)}1'%select{|; did you want to add + '@noDerivative' to this parameter?}2 + +- id: differentiable_function_type_invalid_result + msg: >- + result type '%0' does not conform to 'Differentiable'%select{| and + satisfy '%0 == %0.TangentVector'}1, but the enclosing function type is + '@differentiable%select{|(linear)}1' + +- id: opened_non_protocol + msg: >- + @opened cannot be applied to non-protocol type %0 + +- id: sil_function_ellipsis + msg: >- + SIL function types cannot be variadic + +- id: sil_function_input_label + msg: >- + SIL function types cannot have labeled inputs + +- id: sil_function_output_label + msg: >- + SIL function types cannot have labeled results + +- id: sil_non_coro_yields + msg: >- + non-coroutine SIL function types cannot have @yield results + +- id: sil_function_repeat_convention + msg: >- + repeated %select{parameter|result|callee}0 convention attribute + +- id: ast_subst_function_type + msg: >- + substitutions cannot be provided on a formal function type + +- id: sil_function_multiple_error_results + msg: >- + SIL function types cannot have multiple @error results + +- id: unsupported_sil_convention + msg: >- + convention '%0' not supported in SIL + +- id: illegal_sil_type + msg: >- + type %0 is not a legal SIL value type + +- id: sil_box_arg_mismatch + msg: >- + SIL box type has wrong number of generic arguments for layout + +- id: sil_metatype_without_repr + msg: >- + metatypes in SIL must have @thin, @thick, or @objc_metatype attribute + +- id: sil_metatype_multiple_reprs + msg: >- + metatypes in SIL can only be one of @thin, @thick, or @objc_metatype + +- id: objc_interop_disabled + msg: >- + Objective-C interoperability is disabled + +- id: attr_used_without_required_module + msg: >- + %0 attribute used without importing module %1 + +- id: invalid_objc_decl_context + msg: >- + @objc can only be used with members of classes, @objc protocols, and + concrete extensions of classes + +- id: invalid_objc_decl + msg: >- + only classes (and their extensions), protocols, methods, initializers, + properties, and subscript declarations can be declared @objc + +- id: invalid_objc_swift_rooted_class + msg: >- + only classes that inherit from NSObject can be declared @objc + +- id: invalid_nonobjc_decl + msg: >- + only class members and extensions of classes can be declared @nonobjc + +- id: invalid_nonobjc_extension + msg: >- + only extensions of classes can be declared @nonobjc + +- id: objc_in_extension_context + msg: >- + members of constrained extensions cannot be declared @objc + +- id: objc_in_generic_extension + msg: >- + extensions of %select{classes from generic context|generic classes}0 + cannot contain '@objc' members + +- id: objc_in_resilient_extension + msg: >- + '@objc' %0 in extension of subclass of %1 requires %2 %3 + +- id: objc_operator + msg: >- + operator methods cannot be declared @objc + +- id: objc_operator_proto + msg: >- + @objc protocols must not have operator requirements + +- id: objc_inference_swift3_dynamic + msg: >- + inference of '@objc' for 'dynamic' members is deprecated + +- id: objc_inference_swift3_objc_derived + msg: >- + inference of '@objc' for members of Objective-C-derived classes is + deprecated + +- id: objc_inference_swift3_addobjc + msg: >- + add '@objc' to continue exposing an Objective-C entry point (Swift 3 + behavior) + +- id: objc_inference_swift3_addnonobjc + msg: >- + add '@nonobjc' to suppress the Objective-C entry point (Swift 4 behavior) + +- id: objc_for_generic_class + msg: >- + generic subclasses of '@objc' classes cannot have an explicit '@objc' + because they are not directly visible from Objective-C + +- id: objc_for_resilient_class + msg: >- + explicit '@objc' on subclass of %0 requires %1 %2 + +- id: objc_getter_for_nonobjc_property + msg: >- + '@objc' getter for non-'@objc' property + +- id: objc_getter_for_nonobjc_subscript + msg: >- + '@objc' getter for non-'@objc' subscript + +- id: objc_setter_for_nonobjc_property + msg: >- + '@objc' setter for non-'@objc' property + +- id: objc_setter_for_nonobjc_subscript + msg: >- + '@objc' setter for non-'@objc' subscript + +- id: accessor_swift3_objc_inference + msg: >- + %select{%0 %1|%1}2 with '@objc' %select{getter|setter}3 depends on + deprecated inference of '@objc' + +- id: objc_enum_generic + msg: >- + '@objc' enum cannot be generic + +- id: objc_name_req_nullary + msg: >- + '@objc' %0 must have a simple name + +- id: objc_name_subscript + msg: >- + '@objc' subscript cannot have a name; did you mean to put the name on the + getter or setter? + +- id: objc_name_deinit + msg: >- + '@objc' deinitializer cannot have a name + +- id: objc_name_func_mismatch + msg: >- + '@objc' %select{initializer|method}0 name provides %select{one argument + name|names for %1 arguments}2, but %select{initializer|method}0 has + %select{one parameter|%3 parameters}4%select{| + (%select{|including }4the error parameter)}5 + +- id: objc_enum_case_req_name + msg: >- + attribute has no effect; cases within an '@objc' enum are already exposed + to Objective-C + +- id: objc_enum_case_req_objc_enum + msg: >- + '@objc' enum case is not allowed outside of an '@objc' enum + +- id: objc_enum_case_multi + msg: >- + '@objc' enum case declaration defines multiple enum cases with the same + Objective-C name + +- id: objc_extension_not_class + msg: >- + '@objc' can only be applied to an extension of a class + +- id: attribute_meaningless_when_nonobjc + msg: >- + '@%0' attribute is meaningless on a property that cannot be represented + in Objective-C + +- id: objc_invalid_on_var + msg: >- + property cannot be %select{marked @_cdecl|marked dynamic|marked + @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked + @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc + override|an implementation of an @objc requirement|marked + @IBInspectable|marked @GKInspectable|in an @objc extension of a class + (without @nonobjc)}0 because its type cannot be represented in Objective-C + +- id: objc_invalid_on_subscript + msg: >- + subscript cannot be %select{marked @_cdecl|marked dynamic|marked + @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked + @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc + override|an implementation of an @objc requirement|marked + @IBInspectable|marked @GKInspectable|in an @objc extension of a class + (without @nonobjc)}0 because its type cannot be represented in Objective-C + +- id: objc_invalid_on_static_subscript + msg: >- + %0 cannot be %select{marked @_cdecl|marked dynamic|marked @objc|marked + @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member + of an @objc protocol|implicitly @objc|an @objc override|an implementation of + an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc + extension of a class (without @nonobjc)}1 + +- id: objc_invalid_with_generic_params + msg: >- + %0 cannot be %select{marked @_cdecl|marked dynamic|marked @objc|marked + @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member + of an @objc protocol|implicitly @objc|an @objc override|an implementation of + an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc + extension of a class (without @nonobjc)}1 because it has generic parameters + +- id: objc_convention_invalid + msg: >- + %0 is not representable in Objective-C, so it cannot be used with + '@convention(%1)' + +- id: paren_void_probably_void + msg: >- + when calling this function in Swift 4 or later, you must pass a '()' + tuple; did you mean for the input type to be '()'? + +- id: not_objc_empty_protocol_composition + msg: >- + 'Any' is not considered '@objc'; use 'AnyObject' instead + +- id: not_objc_protocol + msg: >- + protocol-constrained type containing protocol %0 cannot be represented in + Objective-C + +- id: not_objc_class_constraint + msg: >- + protocol-constrained type containing class %0 cannot be represented in + Objective-C + +- id: not_objc_error_protocol_composition + msg: >- + protocol-constrained type containing 'Error' cannot be represented in + Objective-C + +- id: not_objc_empty_tuple + msg: >- + empty tuple type cannot be represented in Objective-C + +- id: not_objc_tuple + msg: >- + tuples cannot be represented in Objective-C + +- id: not_objc_swift_class + msg: >- + classes not annotated with @objc cannot be represented in Objective-C + +- id: not_objc_swift_struct + msg: >- + Swift structs cannot be represented in Objective-C + +- id: not_objc_swift_enum + msg: >- + non-'@objc' enums cannot be represented in Objective-C + +- id: not_objc_generic_type_param + msg: >- + generic type parameters cannot be represented in Objective-C + +- id: not_objc_function_type_param + msg: >- + function types cannot be represented in Objective-C unless their + parameters and returns can be + +- id: not_objc_function_type_throwing + msg: >- + throwing function types cannot be represented in Objective-C + +- id: objc_inferring_on_objc_protocol_member + msg: >- + inferring '@objc' because the declaration is a member of an '@objc' protocol + +- id: objc_overriding_objc_decl + msg: >- + overriding '@objc' %select{property|subscript|initializer|method}0 %1 here + +- id: objc_witness_objc_requirement + msg: >- + satisfying requirement for %0 %1 in protocol %2 + +- id: witness_swift3_objc_inference + msg: >- + use of %0 %1 to satisfy a requirement of protocol %2 depends on '@objc' + inference deprecated in Swift 4 + +- id: no_opaque_return_type_of + msg: >- + unable to resolve type for _opaqueReturnTypeOf attribute + +- id: objc_observing_accessor + msg: >- + observing accessors are not allowed to be marked @objc + +- id: objc_addressor + msg: >- + addressors are not allowed to be marked @objc + +- id: objc_coroutine_accessor + msg: >- + 'read' and 'modify' accessors are not allowed to be marked @objc + +- id: objc_invalid_on_func_variadic + msg: >- + method cannot be %select{marked @_cdecl|marked dynamic|marked + @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked + @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc + override|an implementation of an @objc requirement|marked + @IBInspectable|marked @GKInspectable|in an @objc extension of a class + (without @nonobjc)}0 because it has a variadic parameter + +- id: objc_invalid_on_func_inout + msg: >- + method cannot be %select{marked @_cdecl|marked dynamic|marked + @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked + @NSManaged|a member of an @objc protocol|implicitly @objc|an + @objc override|an implementation of an @objc requirement|marked + @IBInspectable|marked @GKInspectable|in an @objc extension of a class + (without @nonobjc)}0 because inout parameters cannot be represented in + Objective-C + +- id: objc_invalid_on_func_param_type + msg: >- + method cannot be %select{marked @_cdecl|marked dynamic|marked + @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked + @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc + override|an implementation of an @objc requirement|marked + @IBInspectable|marked @GKInspectable|in an @objc extension of a class + (without @nonobjc)}1 because the type of the parameter %0 cannot be + represented in Objective-C + +- id: objc_invalid_on_func_single_param_type + msg: >- + method cannot be %select{marked @_cdecl|marked dynamic|marked + @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked + @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc + override|an implementation of an @objc requirement|marked + @IBInspectable|marked @GKInspectable|in an @objc extension of a class + (without @nonobjc)}0 because the type of the parameter cannot be + represented in Objective-C + +- id: objc_invalid_on_func_result_type + msg: >- + method cannot be %select{marked @_cdecl|marked dynamic|marked + @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked + @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc + override|an implementation of an @objc requirement|marked + @IBInspectable|marked @GKInspectable|in an @objc extension of a class + (without @nonobjc)}0 because its result type cannot be represented in + Objective-C + +- id: objc_invalid_on_foreign_class + msg: >- + method cannot be %select{marked @_cdecl|marked dynamic|marked + @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked + @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc + override|an implementation of an @objc requirement|marked + @IBInspectable|marked @GKInspectable|in an @objc extension of a class + (without @nonobjc)}0 because Core Foundation types are not classes in + Objective-C + +- id: objc_invalid_on_throwing_optional_result + msg: >- + throwing method cannot be %select{marked @_cdecl|marked dynamic|marked + @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked + @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc + override|an implementation of an @objc requirement|marked + @IBInspectable|marked @GKInspectable|in an @objc extension of a class + (without @nonobjc)}0 because it returns a value of optional type %1; 'nil' + indicates failure to Objective-C + +- id: objc_invalid_on_throwing_result + msg: >- + throwing method cannot be %select{marked @_cdecl|marked dynamic|marked + @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked + @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc + override|an implementation of an @objc requirement|marked + @IBInspectable|marked @GKInspectable|in an @objc extension of a class + (without @nonobjc)}0 because it returns a value of type %1; return 'Void' + or a type that bridges to an Objective-C class + +- id: objc_invalid_on_failing_init + msg: >- + a failable and throwing initializer cannot be %select{marked + @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked + @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly + @objc|an @objc override|an implementation of an @objc requirement|marked + @IBInspectable|marked @GKInspectable|in an @objc extension of a class + (without @nonobjc)}0 because 'nil' indicates failure to Objective-C + +- id: objc_in_objc_runtime_visible + msg: >- + %0 cannot be %select{marked @_cdecl|marked dynamic|marked @objc|marked + @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member + of an @objc protocol|implicitly @objc|an @objc override|an implementation of + an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an + @objc extension of a class (without @nonobjc)}1 because class %2 is only + visible via the Objective-C runtime + +- id: objc_override_method_selector_mismatch + msg: >- + Objective-C method has a different selector from the method it overrides + (%0 vs. %1) + +- id: objc_override_property_name_mismatch + msg: >- + Objective-C property has a different name from the property it overrides + (%0 vs. %1) + +- id: objc_ambiguous_inference + msg: >- + ambiguous inference of Objective-C name for %0 %1 (%2 vs %3) + +- id: objc_ambiguous_inference_candidate + msg: >- + %0 (in protocol %1) provides Objective-C name %2 + +- id: objc_ambiguous_error_convention + msg: >- + %0 overrides or implements protocol requirements for Objective-C + declarations with incompatible error argument conventions + +- id: objc_ambiguous_error_convention_candidate + msg: >- + %0 provides an error argument here + +- id: nonlocal_bridged_to_objc + msg: >- + conformance of %0 to %1 can only be written in module %2 + +- id: missing_bridging_function + msg: >- + missing + '%select{_forceBridgeFromObjectiveC|_conditionallyBridgeFromObjectiveC}0' + +- id: objc_redecl + msg: >- + %select{initializer %1|implicit initializer %1|deinitializer|implicit + deinitializer|method %1|getter for %1|subscript getter|setter for + %1|subscript setter}0 with Objective-C selector %4 conflicts with + %select{initializer %3|implicit initializer %3|deinitializer|implicit + deinitializer|method %3|getter for %3|subscript getter|setter + for %3|subscript setter}2 with the same Objective-C selector + +- id: objc_declared_here + msg: >- + %select{initializer %1|implicit initializer %1|deinitializer|implicit + deinitializer|method %1|getter for %1|subscript getter|setter for + %1|subscript setter}0 declared here + +- id: objc_redecl_same + msg: >- + %select{initializer %1|implicit initializer %1|deinitializer|implicit + deinitializer|method %1|getter for %1|subscript getter|setter for + %1|subscript setter}0 with Objective-C selector %2 conflicts with previous + declaration with the same Objective-C selector + +- id: objc_override_other + msg: >- + %select{initializer %1|implicit initializer %1|deinitializer|implicit + deinitializer|method %1|getter for %1|subscript getter|setter for + %1|subscript setter}0 with Objective-C selector %4 conflicts with + %select{initializer %3|implicit initializer %3|deinitializer|implicit + deinitializer|method %3|getter for %3|subscript getter|setter for + %3|subscript setter}2 from superclass %5 with the same Objective-C selector + +- id: objc_class_method_not_permitted + msg: >- + %select{initializer %1|implicit initializer %1|deinitializer|implicit + deinitializer|method %1|getter for %1|subscript getter|setter for + %1|subscript setter}0 defines Objective-C class method %2, which is not + permitted by Swift + +- id: objc_witness_selector_mismatch + msg: >- + Objective-C method %2 provided by %select{initializer %1|implicit + initializer %1|deinitializer|implicit deinitializer|method %1|getter for + %1|subscript getter|setter for %1|subscript setter}0 does not match the + requirement's selector (%3) + +- id: objc_optional_requirement_conflict + msg: >- + Objective-C method %4 provided by %select{initializer %1|implicit + initializer %1|deinitializer|implicit deinitializer|method %1|getter for + %1|subscript getter|setter for %1|subscript setter}0 conflicts with optional + requirement %select{initializer %3|implicit initializer + %3|deinitializer|implicit deinitializer|method %3|getter for %3|subscript + getter|setter for %3|subscript setter}2 in protocol %5 + +- id: objc_optional_requirement_swift_rename + msg: >- + rename %select{method|initializer|property|subscript}0 to match + requirement %1 + +- id: witness_non_objc + msg: >- + non-'@objc' %select{initializer %1|implicit initializer + %1|deinitializer|implicit deinitializer|method %1|getter for %1|subscript + getter|setter for %1|subscript setter}0 does not satisfy requirement of + '@objc' protocol %2 + +- id: witness_non_objc_optional + msg: >- + non-'@objc' %select{initializer %1|implicit initializer + %1|deinitializer|implicit deinitializer|method %1|getter for %1|subscript + getter|setter for %1|subscript setter}0 does not satisfy optional + requirement of '@objc' protocol %2 + +- id: witness_non_objc_storage + msg: >- + non-'@objc' %select{property %1|subscript}0 does not satisfy requirement + of '@objc' protocol %2 + +- id: witness_non_objc_storage_optional + msg: >- + non-'@objc' %select{property %1|subscript}0 does not satisfy optional + requirement of '@objc' protocol %2 + +- id: nonobjc_not_allowed + msg: >- + declaration is %select{marked @_cdecl|marked dynamic|marked @objc|marked + @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a + member of an @objc protocol|implicitly @objc|an @objc override|an + implementation of an @objc requirement|marked @IBInspectable|marked + @GKInspectable|in an @objc extension of a class (without @nonobjc)}0, + and cannot be marked @nonobjc + +- id: borrowed_with_objc_dynamic + msg: >- + %0 cannot be '@_borrowed' if it is '@objc dynamic' + +- id: borrowed_on_objc_protocol_requirement + msg: >- + %0 cannot be '@_borrowed' if it is an @objc protocol requirement + +- id: dynamic_with_transparent + msg: >- + a declaration cannot be both '@_tranparent' and 'dynamic' + +- id: dynamic_replacement_accessor_type_mismatch + msg: >- + replaced accessor %0's type does not match + +- id: dynamic_replacement_accessor_not_dynamic + msg: >- + replaced accessor for %0 is not marked dynamic + +- id: dynamic_replacement_accessor_not_explicit + msg: >- + replaced accessor + %select{get|set|_read|_modify|willSet|didSet|unsafeAddress|addressWithOwner|addressWithNativeOwner|unsafeMutableAddress|mutableAddressWithOwner|}0 + for %1 is not explicitly defined + +- id: dynamic_replacement_function_not_dynamic + msg: >- + replaced function %0 is not marked dynamic + +- id: dynamic_replacement_function_not_found + msg: >- + replaced function %0 could not be found + +- id: dynamic_replacement_accessor_not_found + msg: >- + replaced accessor for %0 could not be found + +- id: dynamic_replacement_accessor_ambiguous + msg: >- + replaced accessor for %0 occurs in multiple places + +- id: dynamic_replacement_accessor_ambiguous_candidate + msg: >- + candidate accessor found in module %0 + +- id: dynamic_replacement_function_of_type_not_found + msg: >- + replaced function %0 of type %1 could not be found + +- id: dynamic_replacement_found_function_of_type + msg: >- + found function %0 of type %1 + +- id: dynamic_replacement_not_in_extension + msg: >- + dynamicReplacement(for:) of %0 is not defined in an extension or at the + file level + +- id: dynamic_replacement_must_not_be_dynamic + msg: >- + dynamicReplacement(for:) of %0 must not be dynamic itself + +- id: dynamic_replacement_replaced_not_objc_dynamic + msg: >- + %0 is not marked @objc dynamic + +- id: dynamic_replacement_replacement_not_objc_dynamic + msg: >- + %0 is marked @objc dynamic + +- id: dynamic_replacement_replaced_constructor_is_convenience + msg: >- + replaced constructor %0 is marked as convenience + +- id: dynamic_replacement_replaced_constructor_is_not_convenience + msg: >- + replaced constructor %0 is not marked as convenience + +- id: non_nominal_type_eraser + msg: >- + type eraser must be a class, struct, or enum + +- id: type_eraser_does_not_conform + msg: >- + type eraser %0 must conform to protocol %1 + +- id: type_eraser_not_accessible + msg: >- + %select{private|fileprivate|internal|public|open}0 type eraser %1 cannot + have more restrictive access than protocol %2 (which is + %select{private|fileprivate|internal|public|open}3) + +- id: type_eraser_missing_init + msg: >- + type eraser %0 must have an initializer of the form 'init(erasing: + T)' + +- id: type_eraser_unviable_init + msg: >- + type eraser %0 has no viable initializer of the form 'init(erasing: T)' + +- id: type_eraser_declared_here + msg: >- + type eraser declared here + +- id: type_eraser_failable_init + msg: >- + 'init(erasing:)' cannot be failable + +- id: type_eraser_init_unsatisfied_requirements + msg: >- + 'init(erasing:)' cannot have unsatisfied requirements when %0 = 'some %1' + +- id: type_eraser_init_not_accessible + msg: >- + %select{private|fileprivate|internal|public|open}0 'init(erasing:)' + cannot have more restrictive access than protocol %1 (which is + %select{private|fileprivate|internal|public|open}2) + +- id: availability_decl_unavailable + msg: >- + %select{getter for |setter for |}0%1 is unavailable%select{ in + %3|}2%select{|: %4}4 + +- id: availability_decl_unavailable_rename + msg: >- + %select{getter for |setter for |}0%1 has been %select{renamed to|replaced + by}2%select{| instance method| property}3 '%4'%select{|: %5}5 + +- id: availability_marked_unavailable + msg: >- + %select{getter for |setter for |}0%1 has been explicitly marked + unavailable here + +- id: availability_introduced_in_version + msg: >- + %select{getter for |setter for |}0%1 was introduced in %2 %3 + +- id: availability_obsoleted + msg: >- + %select{getter for |setter for |}0%1 was obsoleted in %2 %3 + +- id: availability_deprecated + msg: >- + %select{getter for |setter for |}0%1 %select{is|%select{is|was}4}2 + deprecated%select{| in %3%select{| %5}4}2%select{|: %6}6 + +- id: availability_deprecated_rename + msg: >- + %select{getter for |setter for |}0%1 %select{is|%select{is|was}4}2 + deprecated%select{| in %3%select{| %5}4}2: %select{renamed to|replaced + by}6%select{| instance method| property}7 '%8' + +- id: note_deprecated_rename + msg: >- + use '%0' instead + +- id: availability_decl_more_than_enclosing + msg: >- + declaration cannot be more available than enclosing scope + +- id: availability_decl_more_than_enclosing_enclosing_here + msg: >- + enclosing scope here + +- id: availability_decl_only_version_newer + msg: >- + %0 is only available in %1 %2 or newer + +- id: availability_opaque_types_only_version_newer + msg: >- + 'some' return types are only available in %0 %1 or newer + +- id: availability_guard_with_version_check + msg: >- + add 'if #available' version check + +- id: availability_add_attribute + msg: >- + add @available attribute to enclosing %0 + +- id: availability_accessor_only_version_newer + msg: >- + %select{getter|setter}0 for %1 is only available in %2 %3 or newer + +- id: availability_inout_accessor_only_version_newer + msg: >- + cannot pass as inout because %select{getter|setter}0 for %1 is only + available in %2 %3 or newer + +- id: availability_query_required_for_platform + msg: >- + condition required for target platform '%0' + +- id: availability_query_useless_enclosing_scope + msg: >- + unnecessary check for '%0'; enclosing scope ensures guard will always be + true + +- id: availability_query_useless_enclosing_scope_here + msg: >- + enclosing scope here + +- id: availability_global_script_no_potential + msg: >- + global variable cannot be marked potentially unavailable with + '@available' in script mode + +- id: availability_stored_property_no_potential + msg: >- + stored properties cannot be marked potentially unavailable with + '@available' + +- id: availability_protocol_requires_version + msg: >- + protocol %0 requires %1 to be available in %2 %3 and newer + +- id: availability_protocol_requirement_here + msg: >- + protocol requirement here + +- id: public_decl_needs_availability + msg: >- + public declarations should have an availability attribute when building + with -require-explicit-availability + +- id: availabilty_string_subscript_migration + msg: >- + subscripts returning String were obsoleted in Swift 4; explicitly + construct a String from subscripted result + +- id: discardable_result_on_void_never_function + msg: >- + @discardableResult declared on a function returning %select{Never|Void}0 + is unnecessary + +- id: fixed_layout_attr_on_internal_type + msg: >- + '@_fixed_layout' attribute can only be applied to '@usableFromInline' or + public declarations, but %0 is + %select{private|fileprivate|internal|%error|%error}1 + +- id: fixed_layout_struct + msg: >- + '@frozen' attribute is now used for fixed-layout structs + +- id: frozen_attr_on_internal_type + msg: >- + '@frozen' attribute can only be applied to '@usableFromInline' or public + declarations, but %0 is %select{private|fileprivate|internal|%error|%error}1 + +- id: usable_from_inline_attr_with_explicit_access + msg: >- + '@usableFromInline' attribute can only be applied to internal + declarations, but %0 is %select{private|fileprivate|%error|public|open}1 + +- id: inlinable_implies_usable_from_inline + msg: >- + '@inlinable' declaration is already '@usableFromInline' + +- id: usable_from_inline_attr_in_protocol + msg: >- + '@usableFromInline' attribute cannot be used in protocols + +- id: local_type_in_inlinable_function + msg: >- + type %0 cannot be nested inside %select{a '@_transparent' function|an + '@inlinable' function|an '@_alwaysEmitIntoClient' function|a default + argument value|a property initializer in a '@frozen' type}1 + +- id: resilience_decl_unavailable + msg: >- + %select{%0|%0 for}4 %1 is + %select{private|fileprivate|internal|'@_spi'|'@_spi'}2 and cannot be + referenced from %select{a '@_transparent' function|an '@inlinable' + function|an '@_alwaysEmitIntoClient' function|a default argument value|a + property initializer in a '@frozen' type}3 + +- id: resilience_decl_unavailable_warn + msg: >- + %select{%0|%0 for}4 %1 is + %select{private|fileprivate|internal|'@_spi'|'@_spi'}2 and should not be + referenced from %select{a '@_transparent' function|an '@inlinable' + function|an '@_alwaysEmitIntoClient' function|a default argument value|a + property initializer in a '@frozen' type}3 + +- id: inlinable_decl_ref_from_hidden_module + msg: >- + %0 %1 cannot be used in %select{a '@_transparent' function|an + '@inlinable' function|an '@_alwaysEmitIntoClient' function|a default + argument value|a property initializer in a '@frozen' type}2 because + %select{%3 was imported implementation-only|it is an SPI imported from + %3|it is SPI}4 + +- id: resilience_decl_declared_here_public + msg: >- + %select{%0|%0 for}2 %1 is not public + +- id: resilience_decl_declared_here + msg: >- + %select{%0|%0 for}2 %1 is not '@usableFromInline' or public + +- id: class_designated_init_inlinable_resilient + msg: >- + initializer for class %0 is + '%select{@_transparent|@inlinable|@_alwaysEmitIntoClient|%error}1' + and must delegate to another initializer + +- id: attribute_invalid_on_stored_property + msg: >- + '%0' attribute cannot be applied to stored properties + +- id: inlinable_dynamic_not_supported + msg: >- + '@inlinable' attribute cannot be applied to 'dynamic' declarations + +- id: inlinable_decl_not_public + msg: >- + '@inlinable' attribute can only be applied to public declarations, but %0 + is %select{private|fileprivate|internal|%error|%error}1 + +- id: inlinable_resilient_deinit + msg: >- + deinitializer can only be '@inlinable' if the class is '@_fixed_layout' + +- id: specialize_attr_nongeneric_trailing_where + msg: >- + trailing 'where' clause in '_specialize' attribute of non-generic + function %0 + +- id: specialize_missing_where_clause + msg: >- + missing 'where' clause in '_specialize' attribute + +- id: specialize_empty_where_clause + msg: >- + empty 'where' clause in '_specialize' attribute + +- id: specialize_attr_non_concrete_same_type_req + msg: >- + Only concrete type same-type requirements are supported by '_specialize' + attribute + +- id: specialize_attr_only_generic_param_req + msg: >- + Only requirements on generic parameters are supported by '_specialize' + attribute + +- id: specialize_attr_only_one_concrete_same_type_req + msg: >- + Only one concrete type should be used in the same-type requirement in + '_specialize' attribute + +- id: specialize_attr_non_protocol_type_constraint_req + msg: >- + Only conformances to protocol types are supported by '_specialize' attribute + +- id: specialize_attr_type_parameter_count_mismatch + msg: >- + %select{too many|too few}2 type parameters are specified in '_specialize' + attribute (got %1, but expected %0) + +- id: specialize_attr_missing_constraint + msg: >- + Missing constraint for %0 in '_specialize' attribute + +- id: specialize_attr_unsupported_kind_of_req + msg: >- + Only same-type and layout requirements are supported by '_specialize' + attribute + +- id: pbd_never_used_stmtcond + msg: >- + value %0 was defined but never used; consider replacing with boolean test + +- id: unused_setter_parameter + msg: >- + setter argument %0 was never used, but the property was accessed + +- id: fixit_for_unused_setter_parameter + msg: >- + did you mean to use %0 instead of accessing the property's current value? + +- id: pbd_never_used + msg: >- + initialization of %select{variable|immutable value}1 %0 was never used; + consider replacing with assignment to '_' or removing it + +- id: capture_never_used + msg: >- + capture %0 was never used + +- id: variable_never_used + msg: >- + %select{variable|immutable value}1 %0 was never used; consider replacing + with '_' or removing it + +- id: immutable_value_never_used_but_assigned + msg: >- + immutable value %0 was never used; consider removing it + +- id: variable_never_mutated + msg: >- + variable %0 was never mutated; consider %select{removing 'var' to make + it|changing to 'let'}1 constant + +- id: variable_never_read + msg: >- + variable %0 was written to, but never read + +- id: observe_keypath_property_not_objc_dynamic + msg: >- + passing reference to non-'@objc dynamic' property %0 to KVO method %1 may + lead to unexpected behavior or runtime trap + +- id: default_magic_identifier_mismatch + msg: >- + parameter %0 with default argument '%1' passed to parameter %2, whose + default argument is '%3' + +- id: change_caller_default_to_match_callee + msg: >- + did you mean for parameter %0 to default to '%1'? + +- id: silence_default_magic_identifier_mismatch + msg: >- + add parentheses to silence this warning + +- id: debug_long_function_body + msg: >- + %0 %1 took %2ms to type-check (limit: %3ms) + +- id: debug_long_closure_body + msg: >- + closure took %0ms to type-check (limit: %1ms) + +- id: debug_long_expression + msg: >- + expression took %0ms to type-check (limit: %1ms) + +- id: empty_switch_stmt + msg: >- + 'switch' statement body must have at least one 'case' or 'default' block; + do you want to add a default case? + +- id: non_exhaustive_switch + msg: >- + switch must be exhaustive + +- id: possibly_non_exhaustive_switch + msg: >- + the compiler is unable to check that this switch is exhaustive in + reasonable time + +- id: missing_several_cases + msg: >- + do you want to add %select{missing cases|a default clause}0? + +- id: missing_unknown_case + msg: >- + handle unknown values using "@unknown default" + +- id: non_exhaustive_switch_drop_unknown + msg: >- + remove '@unknown' to handle remaining values + +- id: missing_particular_case + msg: >- + add missing case: '%0' + +- id: redundant_particular_case + msg: >- + case is already handled by previous patterns; consider removing it + +- id: redundant_particular_literal_case + msg: >- + literal value is already handled by previous pattern; consider removing it + +- id: redundant_particular_literal_case_here + msg: >- + first occurrence of identical literal pattern is here + +- id: non_exhaustive_switch_warn + msg: >- + switch must be exhaustive + +- id: non_exhaustive_switch_unknown_only + msg: >- + switch covers known cases, but %0 may have additional unknown + values%select{|, possibly added in future versions}1 + +- id: override_nsobject_hashvalue_error + msg: >- + 'NSObject.hashValue' is not overridable; did you mean to override + 'NSObject.hash'? + +- id: hashvalue_implementation + msg: >- + 'Hashable.hashValue' is deprecated as a protocol requirement; conform + type %0 to 'Hashable' by implementing 'hash(into:)' instead + +- id: property_wrapper_no_value_property + msg: >- + property wrapper type %0 does not contain a non-static property named %1 + +- id: property_wrapper_ambiguous_value_property + msg: >- + property wrapper type %0 has multiple non-static properties named %1 + +- id: property_wrapper_wrong_initial_value_init + msg: >- + %0 parameter type (%1) must be the same as its 'wrappedValue' property + type (%2) or an @autoclosure thereof + +- id: property_wrapper_failable_init + msg: >- + property wrapper initializer %0 cannot be failable + +- id: property_wrapper_type_requirement_not_accessible + msg: >- + %select{private|fileprivate|internal|public|open}0 %1 %2 cannot have more + restrictive access than its enclosing property wrapper type %3 (which is + %select{private|fileprivate|internal|public|open}4) + +- id: property_wrapper_ambiguous_enclosing_self_subscript + msg: >- + property wrapper type %0 has multiple enclosing-self subscripts %1 + +- id: property_wrapper_dynamic_self_type + msg: >- + property wrapper %select{wrapped value|projected value}0 cannot have + dynamic Self type + +- id: property_wrapper_attribute_not_on_property + msg: >- + property wrapper attribute %0 can only be applied to a property + +- id: property_wrapper_declared_here + msg: >- + property wrapper type %0 declared here + +- id: property_wrapper_mutating_get_composed_to_get_only + msg: >- + property wrapper %0 with a mutating getter cannot be composed inside + get-only property wrapper %1 + +- id: property_wrapper_local + msg: >- + property wrappers are not yet supported on local properties + +- id: property_wrapper_top_level + msg: >- + property wrappers are not yet supported in top-level code + +- id: property_wrapper_let + msg: >- + property wrapper can only be applied to a 'var' + +- id: property_wrapper_computed + msg: >- + property wrapper cannot be applied to a computed property + +- id: property_with_wrapper_conflict_attribute + msg: >- + property %0 with a wrapper cannot also be + %select{lazy|@NSCopying|@NSManaged|weak|unowned|unmanaged}1 + +- id: property_wrapper_not_single_var + msg: >- + property wrapper can only apply to a single variable + +- id: property_with_wrapper_in_bad_context + msg: >- + %select{|non-static |non-static }1property %0 declared inside %select{a + protocol|an extension|an enum}1 cannot have a wrapper + +- id: property_with_wrapper_overrides + msg: >- + property %0 with attached wrapper cannot override another property + +- id: property_wrapper_direct_init + msg: >- + initialize the property wrapper type directly with '(...') on the attribute + +- id: property_wrapper_incompatible_property + msg: >- + property type %0 does not match that of the 'wrappedValue' property of + its wrapper type %1 + +- id: property_wrapper_type_access + msg: >- + %select{%select{variable|constant}0|property}1 %select{must be declared + %select{%select{private|fileprivate|internal|%error|%error}3|private or + fileprivate}4|cannot be declared %select{in this + context|fileprivate|internal|public|open}3}2 because its property wrapper + type uses %select{a private|a fileprivate|an internal|%error|%error}5 type + +- id: property_wrapper_type_not_usable_from_inline + msg: >- + property wrapper type referenced from a '@usableFromInline' + %select{%select{variable|constant}0|property}1 must be '@usableFromInline' + or public + +- id: property_wrapper_wrapperValue + msg: >- + property wrapper's 'wrapperValue' property should be renamed to + 'projectedValue'; use of 'wrapperValue' is deprecated + +- id: property_wrapper_init_initialValue + msg: >- + property wrapper's 'init(initialValue:)' should be renamed to + 'init(wrappedValue:)'; use of 'init(initialValue:)' is deprecated + +- id: property_wrapper_projection_value_missing + msg: >- + could not find projection value property %0 + +- id: property_wrapper_missing_arg_init + msg: >- + missing argument for parameter %0 in property wrapper initializer; add + 'wrappedValue' and %0 arguments in '@%1(...)' + +- id: function_builder_decl + msg: >- + closure containing a declaration cannot be used with function builder %0 + +- id: note_function_builder_decl + msg: >- + closure containing a declaration cannot be used with function builder %0 + +- id: function_builder_control_flow + msg: >- + closure containing control flow statement cannot be used with function + builder %0 + +- id: note_function_builder_control_flow + msg: >- + closure containing control flow statement cannot be used with function + builder %0 + +- id: function_builder_attribute_not_allowed_here + msg: >- + function builder attribute %0 can only be applied to a parameter, + function, or computed property + +- id: function_builder_attribute_on_storage_without_getter + msg: >- + function builder attribute %0 can only be applied to a + %select{subscript|property|constant|variable}1 if it defines a getter + +- id: function_builder_parameter_not_of_function_type + msg: >- + function builder attribute %0 can only be applied to a parameter of + function type + +- id: function_builder_parameter_autoclosure + msg: >- + function builder attribute %0 cannot be applied to an autoclosure parameter + +- id: function_builder_multiple + msg: >- + only one function builder attribute can be attached to a + %select{declaration|parameter}0 + +- id: previous_function_builder_here + msg: >- + previous function builder specified here + +- id: function_builder_arguments + msg: >- + function builder attributes cannot have arguments + +- id: function_builder_disabled_by_return + msg: >- + application of function builder %0 disabled by explicit 'return' + statement + +- id: function_builder_remove_attr + msg: >- + remove the attribute to explicitly disable the function builder + +- id: function_builder_remove_returns + msg: >- + remove 'return' statements to apply the function builder + +- id: function_builder_infer_ambig + msg: >- + ambiguous function builder inferred for %0: %1 or %2 + +- id: function_builder_infer_add_return + msg: >- + add an explicit 'return' statement to not use a function builder + +- id: function_builder_infer_pick_specific + msg: >- + apply function builder %0 (inferred from %select{protocol|dynamic + replacement of}1 %2) + +- id: warn_reordering_tuple_shuffle_deprecated + msg: >- + expression shuffles the elements of this tuple; this behavior is + deprecated + +- id: differentiable_programming_attr_used_without_required_module + msg: >- + '@%0' attribute used without importing module %1 + +- id: oslog_arg_must_be_bool_literal + msg: >- + argument must be a bool literal + +- id: oslog_arg_must_be_integer_literal + msg: >- + argument must be an integer literal + +- id: oslog_arg_must_be_string_literal + msg: >- + argument must be a string literal + +- id: oslog_arg_must_be_float_literal + msg: >- + argument must be a floating-point literal + +- id: oslog_arg_must_be_metatype_literal + msg: >- + argument must be a .self + +- id: oslog_arg_must_be_closure + msg: >- + argument must be a closure + +- id: argument_must_be_constant + msg: >- + argument must be an expression with only literals + +- id: oslog_message_must_be_string_interpolation + msg: >- + argument must be a string interpolation + +- id: oslog_arg_must_be_enum_case + msg: >- + argument must be a case of enum %0 + +- id: oslog_arg_must_be_type_member_access + msg: >- + argument must be a static method or property of %0 + +- id: atomics_ordering_must_be_constant + msg: >- + ordering argument must be a static method or property of %0 + +- id: warning_from_clang + msg: >- + %0 + +- id: error_from_clang + msg: >- + %0 + +- id: note_from_clang + msg: >- + %0 + +- id: remark_from_clang + msg: >- + %0 + +- id: clang_cannot_build_module + msg: >- + could not build %select{C|Objective-C}0 module '%1' + +- id: bridging_header_missing + msg: >- + bridging header '%0' does not exist + +- id: bridging_header_error + msg: >- + failed to import bridging header '%0' + +- id: could_not_rewrite_bridging_header + msg: >- + failed to serialize bridging header; target may not be debuggable outside + of its original project + +- id: bridging_header_pch_error + msg: >- + failed to emit precompiled header '%0' for bridging header '%1' + +- id: emit_pcm_error + msg: >- + failed to emit precompiled module '%0' for module map '%1' + +- id: dump_pcm_error + msg: >- + failed to dump precompiled module '%0' + +- id: invalid_swift_name_method + msg: >- + too %select{few|many}0 parameters in swift_name attribute (expected %1; + got %2) + +- id: note_while_importing + msg: >- + while importing '%0' + +- id: swift_name_protocol_static + msg: >- + swift_name cannot be used to define %select{static member|init}0 on + protocol + +- id: swift_name_no_prototype + msg: >- + swift_name cannot be used on a non-prototyped function declaration + +- id: inconsistent_swift_name + msg: >- + inconsistent Swift name for Objective-C %select{method|property}0 '%1' in + '%2' (%3 in '%4' vs. %5 in '%6') + +- id: unresolvable_clang_decl + msg: >- + imported declaration '%0' could not be mapped to '%1' + +- id: unresolvable_clang_decl_is_a_framework_bug + msg: >- + please report this issue to the owners of '%0' + +- id: implicit_bridging_header_imported_from_module + msg: >- + implicit import of bridging header '%0' via module %1 is deprecated and + will be removed in a later version of Swift + +- id: bridging_module_missing + msg: >- + unable to find module '%0' for implicit conversion function '%0.%1' + +- id: bridging_function_missing + msg: >- + unable to find implicit conversion function '%0.%1' + +- id: bridging_function_overloaded + msg: >- + multiple definitions of implicit conversion function '%0.%1' + +- id: bridging_function_not_function + msg: >- + definition of implicit conversion function '%0.%1' is not a function + +- id: bridging_function_not_correct_type + msg: >- + definition of implicit conversion function '%0.%1' is not of the correct + type + +- id: bridging_objcbridgeable_missing + msg: >- + cannot find definition of '_ObjectiveCBridgeable' protocol + +- id: bridging_objcbridgeable_broken + msg: >- + broken definition of '_ObjectiveCBridgeable' protocol: missing %0 + +- id: invalid_sil_builtin + msg: >- + INTERNAL ERROR: invalid use of builtin: %0 + +- id: could_not_find_bridge_type + msg: >- + could not find Objective-C bridge type for type %0; did you forget to + import Foundation? + +- id: could_not_find_pointer_pointee_property + msg: >- + could not find 'pointee' property of pointer type %0 + +- id: writeback_overlap_property + msg: >- + inout writeback to computed property %0 occurs in multiple arguments to + call, introducing invalid aliasing + +- id: writeback_overlap_subscript + msg: >- + inout writeback through subscript occurs in multiple arguments to call, + introducing invalid aliasing + +- id: writebackoverlap_note + msg: >- + concurrent writeback occurred here + +- id: inout_argument_alias + msg: >- + inout arguments are not allowed to alias each other + +- id: previous_inout_alias + msg: >- + previous aliasing argument + +- id: unimplemented_generator_witnesses + msg: >- + protocol conformance emission for generator coroutines is unimplemented + +- id: exclusivity_access_required + msg: >- + overlapping accesses to %0, but + %select{initialization|read|modification|deinitialization}1 requires + exclusive access; %select{consider copying to a local variable|consider + calling MutableCollection.swapAt(_:_:)}2 + +- id: exclusivity_access_required_unknown_decl + msg: >- + overlapping accesses, but + %select{initialization|read|modification|deinitialization}0 + requires exclusive access; consider copying to a local variable + +- id: exclusivity_conflicting_access + msg: >- + conflicting access is here + +- id: unsupported_c_function_pointer_conversion + msg: >- + C function pointer signature %0 is not compatible with expected type %1 + +- id: c_function_pointer_from_function_with_context + msg: >- + a C function pointer cannot be formed from a %select{local + function|closure}0 that captures %select{context|generic parameters|dynamic + Self type}1 + +- id: objc_selector_malformed + msg: >- + the type ObjectiveC.Selector is malformed + +- id: capture_before_declaration + msg: >- + closure captures %0 before it is declared + +- id: capture_before_declaration_defer + msg: >- + 'defer' block captures %0 before it is declared + +- id: captured_value_declared_here + msg: >- + captured value declared here + +- id: escaping_inout_capture + msg: >- + escaping %select{local function|closure|autoclosure}0 captures 'inout' + parameter %1 + +- id: inout_param_defined_here + msg: >- + parameter %0 is declared 'inout' + +- id: escaping_mutable_self_capture + msg: >- + escaping %select{local function|closure|autoclosure}0 captures mutating + 'self' parameter + +- id: escaping_noescape_param_capture + msg: >- + escaping %select{local function|closure|autoclosure}0 captures + non-escaping parameter %1 + +- id: noescape_param_defined_here + msg: >- + parameter %0 is implicitly non-escaping + +- id: escaping_noescape_var_capture + msg: >- + escaping %select{local function|closure|autoclosure}0 captures + non-escaping value + +- id: value_captured_here + msg: >- + captured here + +- id: copy_inout_captured_by_autoclosure + msg: >- + pass a copy of %0 + +- id: copy_self_captured_by_autoclosure + msg: >- + pass a copy of 'self' + +- id: value_captured_transitively + msg: >- + captured indirectly by this call + +- id: err_noescape_param_call + msg: >- + passing a %select{|closure which captures a }1non-escaping function + parameter %0 to a call to a non-escaping function parameter can allow + re-entrant modification of a variable + +- id: variable_defined_here + msg: >- + %select{variable|constant}0 defined here + +- id: variable_used_before_initialized + msg: >- + %select{variable|constant}1 '%0' used before being initialized + +- id: variable_inout_before_initialized + msg: >- + %select{variable|constant}1 '%0' passed by reference before being + initialized + +- id: variable_closure_use_uninit + msg: >- + %select{variable|constant}1 '%0' captured by a closure before being + initialized + +- id: variable_defer_use_uninit + msg: >- + %select{variable|constant}1 '%0' used in defer before being initialized + +- id: self_closure_use_uninit + msg: >- + 'self' captured by a closure before all members were initialized + +- id: variable_addrtaken_before_initialized + msg: >- + address of %select{variable|constant}1 '%0' taken before it is initialized + +- id: ivar_not_initialized_at_superinit + msg: >- + property '%0' not initialized at super.init call + +- id: ivar_not_initialized_at_implicit_superinit + msg: >- + property '%0' not initialized at implicitly generated super.init call + +- id: self_use_before_fully_init + msg: >- + 'self' used in %select{method call|property access}1 %0 before + %select{all stored properties are initialized|'super.init' call|'self.init' + call}2 + +- id: use_of_self_before_fully_init + msg: >- + 'self' used before all stored properties are initialized + +- id: stored_property_not_initialized + msg: >- + '%0' not initialized + +- id: selfinit_multiple_times + msg: >- + '%select{super|self}0.init' called multiple times in initializer + +- id: superselfinit_not_called_before_return + msg: >- + '%select{super|self}0.init' isn't called on all paths before returning + from initializer + +- id: self_before_superinit + msg: >- + 'self' used before 'super.init' call + +- id: self_before_selfinit + msg: >- + 'self' used before 'self.init' call + +- id: self_before_selfinit_value_type + msg: >- + 'self' used before 'self.init' call or assignment to 'self' + +- id: self_inside_catch_superselfinit + msg: >- + 'self' used inside 'catch' block reachable from %select{super|self}0.init + call + +- id: return_from_init_without_initing_stored_properties + msg: >- + return from initializer without initializing all stored properties + +- id: variable_function_use_uninit + msg: >- + %select{variable|constant}1 '%0' used by function definition before being + initialized + +- id: struct_not_fully_initialized + msg: >- + struct '%0' must be completely initialized before a member is stored to + +- id: immutable_property_already_initialized + msg: >- + immutable value '%0' may only be initialized once + +- id: initial_value_provided_in_let_decl + msg: >- + initial value already provided in 'let' declaration + +- id: mutation_of_property_of_immutable_value + msg: >- + cannot mutate %select{property %0|subscript}1 of immutable value '%2' + +- id: using_mutating_accessor_on_immutable_value + msg: >- + mutating accessor for %select{property %0|subscript}1 may not be used on + immutable value '%2' + +- id: mutating_method_called_on_immutable_value + msg: >- + mutating %select{method|operator}1 %0 may not be used on immutable value + '%2' + +- id: immutable_value_passed_inout + msg: >- + immutable value '%0' must not be passed inout + +- id: assignment_to_immutable_value + msg: >- + immutable value '%0' must not be assigned to + +- id: designated_init_in_cross_module_extension + msg: >- + initializer for struct %0 must use "self.init(...)" or "self = + ..."%select{| on all paths}1 because %select{it is not in module %2|the + struct was imported from C}3 + +- id: designated_init_c_struct_fix + msg: >- + use "self.init()" to initialize the struct with zero values + +- id: missing_return + msg: >- + missing return in a %select{function|closure}1 expected to return %0 + +- id: missing_return_last_expr + msg: >- + missing return in a %select{function|closure}1 expected to return %0; + did you mean to return the last expression? + +- id: missing_never_call + msg: >- + %select{function|closure}1 with uninhabited return type %0 is missing + call to another never-returning function on all paths + +- id: guard_body_must_not_fallthrough + msg: >- + 'guard' body must not fall through, consider using a 'return' or 'throw' + to exit the scope + +- id: unreachable_code + msg: >- + will never be executed + +- id: unreachable_code_uninhabited_param_note + msg: >- + '%0' is uninhabited, so this function body can never be executed + +- id: unreachable_code_branch + msg: >- + condition always evaluates to %select{false|true}0 + +- id: call_to_noreturn_note + msg: >- + a call to a never-returning function + +- id: unreachable_code_after_stmt + msg: >- + code after '%select{return|break|continue|throw}0' will never be executed + +- id: unreachable_case + msg: >- + %select{case|default}0 will never be executed + +- id: switch_on_a_constant + msg: >- + switch condition evaluates to a constant + +- id: unreachable_code_note + msg: >- + will never be executed + +- id: warn_infinite_recursive_function + msg: >- + all paths through this function will call itself + +- id: circular_transparent + msg: >- + inlining 'transparent' functions forms circular loop + +- id: note_while_inlining + msg: >- + while inlining here + +- id: cannot_prespecialize + msg: >- + Cannot pre-specialize %0 + +- id: missing_prespecialization + msg: >- + Pre-specialized function %0 missing in SwiftOnoneSupport module + +- id: integer_conversion_overflow + msg: >- + integer overflows when converted from %0 to %1 + +- id: integer_conversion_overflow_builtin_types + msg: >- + integer overflows when converted from %select{unsigned|signed}0 %1 to + %select{unsigned|signed}2 %3 + +- id: integer_conversion_overflow_warn + msg: >- + integer overflows when converted from %0 to %1 + +- id: negative_integer_literal_overflow_unsigned + msg: >- + negative integer '%1' overflows when stored into unsigned type %0 + +- id: integer_literal_overflow + msg: >- + integer literal '%1' overflows when stored into %0 + +- id: integer_literal_overflow_builtin_types + msg: >- + integer literal '%2' overflows when stored into %select{unsigned|signed}0 %1 + +- id: integer_literal_overflow_warn + msg: >- + integer literal overflows when stored into %0 + +- id: arithmetic_operation_overflow + msg: >- + arithmetic operation '%0 %1 %2' (on type %3) results in an overflow + +- id: arithmetic_operation_overflow_generic_type + msg: >- + arithmetic operation '%0 %1 %2' (on %select{unsigned|signed}3 %4-bit + integer type) results in an overflow + +- id: division_overflow + msg: >- + division '%0 %1 %2' results in an overflow + +- id: division_by_zero + msg: >- + division by zero + +- id: wrong_non_negative_assumption + msg: >- + assumed non-negative value '%0' is negative + +- id: shifting_all_significant_bits + msg: >- + shift amount is greater than or equal to type size in bits + +- id: static_report_error + msg: >- + static report error + +- id: pound_assert_condition_not_constant + msg: >- + #assert condition not constant + +- id: pound_assert_failure + msg: >- + %0 + +- id: constexpr_unknown_reason_default + msg: >- + cannot evaluate expression as constant here + +- id: constexpr_unevaluable_operation + msg: >- + cannot constant evaluate operation%select{| used by this call}0 + +- id: constexpr_too_many_instructions + msg: >- + exceeded instruction limit: %0 when evaluating the expression at compile + time + +- id: constexpr_limit_exceeding_instruction + msg: >- + limit exceeded %select{here|during this call}0 + +- id: constexpr_loop_found_note + msg: >- + control-flow loop found during evaluation + +- id: constexpr_loop_instruction + msg: >- + found loop %select{here|inside this call}0 + +- id: constexpr_overflow + msg: >- + integer overflow detected + +- id: constexpr_overflow_operation + msg: >- + operation%select{| performed during this call}0 overflows + +- id: constexpr_trap + msg: >- + %0 + +- id: constexpr_trap_operation + msg: >- + operation%select{| performed during this call}0 traps + +- id: constexpr_invalid_operand_seen + msg: >- + operation with invalid operands encountered during evaluation + +- id: constexpr_operand_invalid_here + msg: >- + operation with invalid operands encountered %select{here|during this call}0 + +- id: constexpr_value_unknown_at_top_level + msg: >- + cannot evaluate top-level value as constant here + +- id: constexpr_multiple_writers_found_at_top_level + msg: >- + top-level value has multiple assignments + +- id: constexpr_unsupported_instruction_found + msg: >- + encountered operation not supported by the evaluator: %0 + +- id: constexpr_unsupported_instruction_found_here + msg: >- + operation%select{| used by this call is}0 not supported by the evaluator + +- id: constexpr_found_callee_with_no_body + msg: >- + encountered call to '%0' whose body is not available. Imported functions + must be marked '@inlinable' to constant evaluate + +- id: constexpr_callee_with_no_body + msg: >- + %select{|calls a }0function whose body is not available + +- id: constexpr_found_call_with_unknown_arg + msg: >- + encountered call to '%0' where the %1 argument is not a constant + +- id: constexpr_call_with_unknown_arg + msg: >- + %select{|makes a }0function call with non-constant arguments + +- id: constexpr_untracked_sil_value_use_found + msg: >- + encountered use of a variable not tracked by the evaluator + +- id: constexpr_untracked_sil_value_used_here + msg: >- + untracked variable used %select{here|by this call}0 + +- id: constexpr_unevaluable_cast_found + msg: >- + encountered an unevaluable cast + +- id: constexpr_unevaluable_cast_used_here + msg: >- + unevaluable cast encountered %select{here|by this call}0 + +- id: constexpr_unresolvable_witness_call + msg: >- + encountered unresolvable witness method call: '%0' + +- id: constexpr_no_witness_table_entry + msg: >- + cannot find witness table entry %select{for this call|for a + witness-method invoked during this call}0 + +- id: constexpr_witness_call_with_no_conformance + msg: >- + cannot find concrete conformance %select{for this call|for a + witness-method invoked during this call}0 + +- id: constexpr_unknown_control_flow_due_to_skip + msg: >- + branch depends on non-constant value produced by an unevaluated + instructions + +- id: constexpr_returned_by_unevaluated_instruction + msg: >- + result of an unevaluated instruction is not a constant + +- id: constexpr_mutated_by_unevaluated_instruction + msg: >- + value mutable by an unevaluated instruction is not a constant + +- id: not_constant_evaluable + msg: >- + not constant evaluable + +- id: constexpr_imported_func_not_onone + msg: >- + imported constant evaluable function '%0' must be annotated + '@_optimize(none)' + +- id: autodiff_internal_swift_not_imported + msg: >- + Automatic differentiation internal error: the Swift module is not + imported + +- id: autodiff_differentiation_module_not_imported + msg: >- + Automatic differentiation requires the '_Differentiation' module to be + imported + +- id: autodiff_conversion_to_linear_function_not_supported + msg: >- + conversion to '@differentiable(linear)' function type is not yet + supported + +- id: autodiff_function_not_differentiable_error + msg: >- + function is not differentiable + +- id: autodiff_expression_not_differentiable_error + msg: >- + expression is not differentiable + +- id: autodiff_expression_not_differentiable_note + msg: >- + expression is not differentiable + +- id: autodiff_when_differentiating_function_call + msg: >- + when differentiating this function call + +- id: autodiff_when_differentiating_function_definition + msg: >- + when differentiating this function definition + +- id: autodiff_implicitly_inherited_differentiable_attr_here + msg: >- + differentiability required by the corresponding protocol requirement here + +- id: autodiff_jvp_control_flow_not_supported + msg: >- + forward-mode differentiation does not yet support control flow + +- id: autodiff_control_flow_not_supported + msg: >- + cannot differentiate unsupported control flow + +- id: autodiff_missing_return + msg: >- + missing return for differentiation + +- id: autodiff_external_nondifferentiable_function + msg: >- + cannot differentiate functions that have not been marked + '@differentiable' and that are defined in other files + +- id: autodiff_opaque_function_not_differentiable + msg: >- + opaque non-'@differentiable' function is not differentiable + +- id: autodiff_private_derivative_from_fragile + msg: >- + differentiated functions in %select{'@inlinable' functions|default + arguments}0 must be marked '@differentiable' or have a public + '@derivative'%select{|; this is not possible with a closure, make a + top-level function instead}1 + +- id: autodiff_function_noderivative_parameter_not_differentiable + msg: >- + cannot differentiate with respect to a '@noDerivative' parameter + +- id: autodiff_function_assoc_func_unmet_requirements + msg: >- + function call is not differentiable because generic requirements are not + met: '%0' + +- id: autodiff_nondifferentiable_argument + msg: >- + cannot differentiate through a non-differentiable argument; do you want + to use 'withoutDerivative(at:)'? + +- id: autodiff_nondifferentiable_result + msg: >- + cannot differentiate through a non-differentiable result; do you want to + use 'withoutDerivative(at:)'? + +- id: autodiff_protocol_member_not_differentiable + msg: >- + member is not differentiable because the corresponding protocol + requirement is not '@differentiable' + +- id: autodiff_class_member_not_differentiable + msg: >- + member is not differentiable because the corresponding class member is + not '@differentiable' + +- id: autodiff_member_subset_indices_not_differentiable + msg: >- + member is differentiable only with respect to a smaller subset of arguments + +- id: autodiff_cannot_param_subset_thunk_partially_applied_orig_fn + msg: >- + cannot convert a direct method reference to a '@differentiable' function; + use an explicit closure instead + +- id: autodiff_cannot_differentiate_through_multiple_results + msg: >- + cannot differentiate through multiple results + +- id: autodiff_cannot_differentiate_through_inout_arguments + msg: >- + cannot differentiate through 'inout' arguments + +- id: autodiff_enums_unsupported + msg: >- + differentiating enum values is not yet supported + +- id: autodiff_stored_property_parent_not_differentiable + msg: >- + cannot differentiate access to property '%0.%1' because '%0' does not + conform to 'Differentiable' + +- id: autodiff_stored_property_not_differentiable + msg: >- + cannot differentiate access to property '%0.%1' because property type %2 + does not conform to 'Differentiable' + +- id: autodiff_stored_property_tangent_not_struct + msg: >- + cannot differentiate access to property '%0.%1' because + '%0.TangentVector' is not a struct + +- id: autodiff_stored_property_no_corresponding_tangent + msg: >- + cannot differentiate access to property '%0.%1' because + '%0.TangentVector' does not have a stored property named '%1' + +- id: autodiff_tangent_property_wrong_type + msg: >- + cannot differentiate access to property '%0.%1' because + '%0.TangentVector.%1' does not have expected type %2 + +- id: autodiff_tangent_property_not_stored + msg: >- + cannot differentiate access to property '%0.%1' because + '%0.TangentVector.%1' is not a stored property + +- id: autodiff_coroutines_not_supported + msg: >- + differentiation of coroutine calls is not yet supported + +- id: autodiff_cannot_differentiate_writes_to_global_variables + msg: >- + cannot differentiate writes to global variables + +- id: autodiff_cannot_differentiate_writes_to_mutable_captures + msg: >- + cannot differentiate writes to mutable captures + +- id: non_physical_addressof + msg: >- + addressof only works with purely physical lvalues; use + 'withUnsafePointer' or 'withUnsafeBytes' unless you're implementing + 'withUnsafePointer' or 'withUnsafeBytes' + +- id: non_borrowed_indirect_addressof + msg: >- + addressof only works with borrowable in-memory rvalues; use + 'withUnsafePointer' or 'withUnsafeBytes' unless you're implementing + 'withUnsafePointer' or 'withUnsafeBytes' + +- id: opt_remark_passed + msg: >- + %0 + +- id: opt_remark_missed + msg: >- + %0 + +- id: float_to_int_overflow + msg: >- + invalid%select{| implicit}2 conversion: '%0' overflows %1 + +- id: negative_fp_literal_overflow_unsigned + msg: >- + negative literal '%0' cannot be converted to %select{|unsigned }2%1 + +- id: warning_float_trunc_overflow + msg: >- + '%0' overflows to %select{|-}2inf during conversion to %1 + +- id: warning_float_trunc_underflow + msg: >- + '%0' underflows and loses precision during conversion to %1 + +- id: warning_float_trunc_hex_inexact + msg: >- + '%0' loses precision during conversion to %1 + +- id: warning_float_overflows_maxbuiltin + msg: >- + '%0' overflows to %select{|-}1inf because its magnitude exceeds the + limits of a float literal + +- id: warning_int_to_fp_inexact + msg: >- + '%1' is not exactly representable as %0; it becomes '%2' + +- id: return_before_yield + msg: >- + accessor must yield before returning + +- id: multiple_yields + msg: >- + accessor must not yield more than once + +- id: previous_yield + msg: >- + previous yield was here + +- id: possible_return_before_yield + msg: >- + accessor must yield on all paths before returning + +- id: branch_doesnt_yield + msg: >- + missing yield when the condition is %select{false|true}0 + +- id: named_case_doesnt_yield + msg: >- + missing yield in the %0 case + +- id: case_doesnt_yield + msg: >- + missing yield in %select{this|the nil|the non-nil}0 case + +- id: switch_value_case_doesnt_yield + msg: >- + missing yield in the %0 case + +- id: try_branch_doesnt_yield + msg: >- + missing yield when error is %select{not |}0thrown + +- id: oslog_constant_eval_trap + msg: >- + %0 + +- id: oslog_too_many_instructions + msg: >- + interpolated expression and arguments are too complex + +- id: oslog_invalid_log_message + msg: >- + invalid log message; extending types defined in the os module is not + supported + +- id: oslog_const_evaluable_fun_error + msg: >- + '%0' failed evaluation + +- id: oslog_non_constant_message + msg: >- + 'OSLogMessage' instance passed to the log call is not a constant + +- id: oslog_non_constant_interpolation + msg: >- + 'OSLogInterpolation' instance passed to 'OSLogMessage.init' is not a + constant + +- id: oslog_property_not_constant + msg: >- + 'OSLogInterpolation.%0' is not a constant + +- id: oslog_message_alive_after_opts + msg: >- + string interpolation cannot be used in this context; if you are calling + an os_log function, try a different overload + +- id: oslog_message_explicitly_created + msg: >- + 'OSLogMessage' must be created from a string interpolation or string + literal + +- id: oslog_call_in_unreachable_code + msg: >- + os log call will never be executed and may have undiagnosed errors + +- id: global_string_pointer_on_non_constant + msg: >- + globalStringTablePointer builtin must be used only on string literals + +- id: polymorphic_builtin_passed_non_trivial_non_builtin_type + msg: >- + Argument of type %0 can not be passed as an argument to a Polymorphic + builtin. Polymorphic builtins can only be passed arguments that are trivial + builtin typed + +- id: polymorphic_builtin_passed_type_without_static_overload + msg: >- + Static overload %0 does not exist for polymorphic builtin '%1'. Static + overload implied by passing argument of type %2 + +- id: box_to_stack_cannot_promote_box_to_stack_due_to_escape_alloc + msg: >- + Can not promote value from heap to stack due to value escaping + +- id: box_to_stack_cannot_promote_box_to_stack_due_to_escape_location + msg: >- + value escapes here + +- id: no_llvm_target + msg: >- + error loading LLVM target for triple '%0': %1 + +- id: error_codegen_init_fail + msg: >- + cannot initialize code generation passes for target + +- id: irgen_unimplemented + msg: >- + unimplemented IR generation feature %0 + +- id: irgen_failure + msg: >- + IR generation failure: %0 + +- id: type_to_verify_not_found + msg: >- + unable to find type '%0' to verify + +- id: type_to_verify_ambiguous + msg: >- + type to verify '%0' is ambiguous + +- id: type_to_verify_dependent + msg: >- + type to verify '%0' has unbound generic parameters + +- id: too_few_output_filenames + msg: >- + too few output file names specified + +- id: no_input_files_for_mt + msg: >- + no swift input files for multi-threaded compilation + +- id: alignment_dynamic_type_layout_unsupported + msg: >- + @_alignment is not supported on types with dynamic layout + +- id: alignment_less_than_natural + msg: >- + @_alignment cannot decrease alignment below natural alignment of %0 + +- id: alignment_more_than_maximum + msg: >- + @_alignment cannot increase alignment above maximum alignment of %0 + +- id: warning_no_such_sdk + msg: >- + no such SDK: '%0' + +- id: error_no_frontend_args + msg: >- + no arguments provided to '-frontend' + +- id: error_no_such_file_or_directory + msg: >- + no such file or directory: '%0' + +- id: error_unsupported_target_os + msg: >- + unsupported target OS: '%0' + +- id: error_unsupported_target_arch + msg: >- + unsupported target architecture: '%0' + +- id: error_unsupported_opt_for_target + msg: >- + unsupported option '%0' for target '%1' + +- id: warning_inferred_simulator_target + msg: >- + inferring simulator environment for target '%0'; use '-target %1' instead + +- id: error_argument_not_allowed_with + msg: >- + argument '%0' is not allowed with '%1' + +- id: warning_argument_not_supported_with_optimization + msg: >- + argument '%0' is not supported with optimization + +- id: error_option_requires_sanitizer + msg: >- + option '%0' requires a sanitizer to be enabled. Use -sanitize= to enable + a sanitizer + +- id: warning_option_requires_specific_sanitizer + msg: >- + option '%0' has no effect when '%1' sanitizer is disabled. Use + -sanitize=%1 to enable the sanitizer + +- id: error_option_missing_required_argument + msg: >- + option '%0' is missing a required argument (%1) + +- id: cannot_open_file + msg: >- + cannot open file '%0' (%1) + +- id: cannot_open_serialized_file + msg: >- + cannot open file '%0' for diagnostics emission (%1) + +- id: error_open_input_file + msg: >- + error opening input file '%0' (%1) + +- id: error_clang_importer_create_fail + msg: >- + clang importer creation failed + +- id: error_missing_arg_value + msg: >- + missing argument value for '%0', expected %1 argument(s) + +- id: error_unknown_arg + msg: >- + unknown argument: '%0' + +- id: error_invalid_arg_value + msg: >- + invalid value '%1' in '%0' + +- id: warning_invalid_locale_code + msg: >- + unsupported locale code; supported locale codes are: '%0' + +- id: warning_locale_path_not_found + msg: >- + specified localization directory '%0' does not exist, translation is + disabled + +- id: warning_cannot_find_locale_file + msg: >- + cannot find translations for '%0' at '%1': no such file + +- id: warning_cannot_multithread_batch_mode + msg: >- + ignoring -num-threads argument; cannot multithread batch mode + +- id: error_unsupported_option_argument + msg: >- + unsupported argument '%1' to option '%0' + +- id: error_immediate_mode_missing_stdlib + msg: >- + could not load the swift standard library + +- id: error_immediate_mode_missing_library + msg: >- + could not load %select{shared library|framework}0 '%1' + +- id: error_immediate_mode_primary_file + msg: >- + immediate mode is incompatible with -primary-file + +- id: error_missing_frontend_action + msg: >- + no frontend action was selected + +- id: error_invalid_source_location_str + msg: >- + invalid source location string '%0' + +- id: error_no_source_location_scope_map + msg: >- + -dump-scope-maps argument must be 'expanded' or a list of source + locations + +- id: note_valid_swift_versions + msg: >- + valid arguments to '-swift-version' are %0 + +- id: error_mode_cannot_emit_dependencies + msg: >- + this mode does not support emitting dependency files + +- id: error_mode_cannot_emit_reference_dependencies + msg: >- + this mode does not support emitting reference dependency files + +- id: error_mode_cannot_emit_swift_ranges + msg: >- + this mode does not support emitting unparsed ranges files + +- id: error_mode_cannot_emit_compiled_source + msg: >- + this mode does not support emitting compiled source files + +- id: error_mode_cannot_emit_header + msg: >- + this mode does not support emitting Objective-C headers + +- id: error_mode_cannot_emit_loaded_module_trace + msg: >- + this mode does not support emitting the loaded module trace + +- id: error_mode_cannot_emit_module + msg: >- + this mode does not support emitting modules + +- id: error_mode_cannot_emit_module_doc + msg: >- + this mode does not support emitting module documentation files + +- id: error_mode_cannot_emit_module_source_info + msg: >- + this mode does not support emitting module source info files + +- id: error_mode_cannot_emit_interface + msg: >- + this mode does not support emitting module interface files + +- id: cannot_emit_ir_skipping_function_bodies + msg: >- + -experimental-skip-non-inlinable-function-bodies does not support + emitting IR + +- id: emit_reference_dependencies_without_primary_file + msg: >- + ignoring -emit-reference-dependencies (requires -primary-file) + +- id: emit_swift_ranges_without_primary_file + msg: >- + ignoring -emit-swift-ranges (requires -primary-file) + +- id: emit_compiled_source_without_primary_file + msg: >- + ignoring -emit-compiled-source (requires -primary-file) + +- id: error_bad_module_name + msg: >- + module name "%0" is not a valid identifier%select{|; use -module-name + flag to specify an alternate name}1 + +- id: error_stdlib_module_name + msg: >- + module name "%0" is reserved for the standard library%select{|; use + -module-name flag to specify an alternate name}1 + +- id: error_stdlib_not_found + msg: >- + unable to load standard library for target '%0' + +- id: error_unable_to_load_supplementary_output_file_map + msg: >- + unable to load supplementary output file map '%0': %1 + +- id: error_missing_entry_in_supplementary_output_file_map + msg: >- + supplementary output file map '%0' is missing an entry for '%1' (this + likely indicates a compiler issue; please file a bug report) + +- id: error_repl_requires_no_input_files + msg: >- + REPL mode requires no input files + +- id: error_mode_requires_one_input_file + msg: >- + this mode requires a single input file + +- id: error_mode_requires_an_input_file + msg: >- + this mode requires at least one input file + +- id: error_mode_requires_one_sil_multi_sib + msg: >- + this mode requires .sil for primary-file and only .sib for other inputs + +- id: error_no_output_filename_specified + msg: >- + an output filename was not specified for a mode which requires an output + filename + +- id: error_implicit_output_file_is_directory + msg: >- + the implicit output file '%0' is a directory; explicitly specify a + filename using -o + +- id: error_if_any_output_files_are_specified_they_all_must_be + msg: >- + if any output files are specified, they all must be + +- id: error_primary_file_not_found + msg: >- + primary file '%0' was not found in file list '%1' + +- id: error_cannot_have_input_files_with_file_list + msg: >- + cannot have input files with file list + +- id: error_cannot_have_primary_files_with_primary_file_list + msg: >- + cannot have primary input files with primary file list + +- id: error_cannot_have_supplementary_outputs + msg: >- + cannot have '%0' with '%1' + +- id: error_duplicate_input_file + msg: >- + duplicate input file '%0' + +- id: repl_must_be_initialized + msg: >- + variables currently must have an initial value when entered at the top + level of the REPL + +- id: verify_encountered_fatal + msg: >- + fatal error encountered while in -verify mode + +- id: error_parse_input_file + msg: >- + error parsing input file '%0' (%1) + +- id: error_write_index_unit + msg: >- + writing index unit file: %0 + +- id: error_create_index_dir + msg: >- + creating index directory: %0 + +- id: error_write_index_record + msg: >- + writing index record file: %0 + +- id: error_index_failed_status_check + msg: >- + failed file status check: %0 + +- id: error_index_inputs_more_than_outputs + msg: >- + index output filenames do not match input source files + +- id: error_wrong_number_of_arguments + msg: >- + wrong number of '%0' arguments (expected %1, got %2) + +- id: error_formatting_multiple_file_ranges + msg: >- + file ranges don't support multiple input files + +- id: error_formatting_invalid_range + msg: >- + file range is invalid + +- id: stats_disabled + msg: >- + compiler was not built with support for collecting statistics + +- id: tbd_warn_truncating_version + msg: >- + truncating %select{current|compatibility}0 version '%1' in TBD file to + fit in 32-bit space used by old mach-o format + +- id: tbd_err_invalid_version + msg: >- + invalid dynamic library %select{current|compatibility}0 version '%1' + +- id: tbd_only_supported_in_whole_module + msg: >- + TBD generation is only supported when the whole module can be seen + +- id: tbd_not_supported_with_cmo + msg: >- + Test-Based InstallAPI (TBD) is not support with cross-module-optimization + +- id: linker_directives_choice_confusion + msg: >- + only one of -emit-ldadd-cfile-path and -module-installname-map-file can + be specified;the c file won't be generated + +- id: previous_installname_map_missing + msg: >- + cannot open previous install name map from %0 + +- id: previous_installname_map_corrupted + msg: >- + previous install name map from %0 is malformed + +- id: explicit_swift_module_map_missing + msg: >- + cannot open explicit Swift module map from %0 + +- id: explicit_swift_module_map_corrupted + msg: >- + explicit Swift module map from %0 is malformed + +- id: default_previous_install_name + msg: >- + default previous install name for %0 is %1 + +- id: platform_previous_install_name + msg: >- + previous install name for %0 in %1 is %2 + +- id: unknown_platform_name + msg: >- + unkown platform name %0 + +- id: unknown_swift_module_name + msg: >- + cannot find Swift module with name %0 + +- id: cannot_find_install_name + msg: >- + cannot find previous install name for module %0 in %1 + +- id: symbol_in_tbd_not_in_ir + msg: >- + symbol '%0' (%1) is in TBD file, but not in generated IR + +- id: symbol_in_ir_not_in_tbd + msg: >- + symbol '%0' (%1) is in generated IR file, but not in TBD file + +- id: tbd_validation_failure + msg: >- + please file a radar or open a bug on bugs.swift.org with this code, and + add -Xfrontend -validate-tbd-against-ir=none to squash the errors + +- id: redundant_prefix_compilation_flag + msg: >- + invalid argument '-D%0'; did you provide a redundant '-D' in your build + settings? + +- id: invalid_conditional_compilation_flag + msg: >- + conditional compilation flags must be valid Swift identifiers (rather + than '%0') + +- id: cannot_assign_value_to_conditional_compilation_flag + msg: >- + conditional compilation flags do not have values in Swift; they are + either present or absent (rather than '%0') + +- id: framework_search_path_includes_framework_extension + msg: >- + framework search path ends in ".framework"; add directory containing + framework instead: %0 + +- id: error_optimization_remark_pattern + msg: >- + %0 in '%1' + +- id: error_invalid_debug_prefix_map + msg: >- + invalid argument '%0' to -debug-prefix-map; it must be of the form + 'original=remapped' + +- id: error_invalid_coverage_prefix_map + msg: >- + invalid argument '%0' to -coverage-prefix-map; it must be of the form + 'original=remapped' + +- id: error_unable_to_write_swift_ranges_file + msg: >- + unable to write unparsed ranges file '$0': %1 + +- id: error_unable_to_write_compiled_source_file + msg: >- + unable to write compiled source file: '$0': %1 + +- id: invalid_vfs_overlay_file + msg: >- + invalid virtual overlay file '%0' + +- id: module_interface_scoped_import_unsupported + msg: >- + scoped imports are not yet supported in module interfaces + +- id: warn_unsupported_module_interface_swift_version + msg: >- + module interfaces are only supported with Swift language version 5 or + later (currently using -swift-version %0) + +- id: warn_unsupported_module_interface_library_evolution + msg: >- + module interfaces are only supported with -enable-library-evolution + +- id: error_extracting_version_from_module_interface + msg: >- + error extracting version from module interface + +- id: unsupported_version_of_module_interface + msg: >- + unsupported version of module interface '%0': '%1' + +- id: error_opening_explicit_module_file + msg: >- + failed to open explicit Swift module: %0 + +- id: error_extracting_flags_from_module_interface + msg: >- + error extracting flags from module interface + +- id: rebuilding_module_from_interface + msg: >- + rebuilding module '%0' from interface '%1' + +- id: out_of_date_module_here + msg: >- + %select{compiled|cached|forwarding|prebuilt}0 module is out of date: '%1' + +- id: module_interface_dependency_out_of_date + msg: >- + dependency is out of date: '%0' + +- id: module_interface_dependency_missing + msg: >- + dependency is missing: '%0' + +- id: compiled_module_invalid + msg: >- + unable to load compiled module '%0' + +- id: compiled_module_invalid_reason + msg: >- + unable to load compiled module '%0': %1 + +- id: unknown_forced_module_loading_mode + msg: >- + unknown value for SWIFT_FORCE_MODULE_LOADING variable: '%0' + +- id: error_creating_remark_serializer + msg: >- + error while creating remark serializer: '%0' + +- id: interface_file_lock_failure + msg: >- + could not acquire lock file for module interface '%0' + +- id: interface_file_lock_timed_out + msg: >- + timed out waiting to acquire lock file for module interface '%0' + +- id: dependency_cascading_mismatch + msg: >- + expected %select{non-cascading|cascading}0 dependency; found + %select{non-cascading|cascading}1 dependency instead + +- id: potential_dependency_cascading_mismatch + msg: >- + expected %select{non-cascading|cascading}0 potential member dependency; + found %select{non-cascading|cascading}1 potential member dependency instead + +- id: missing_member_dependency + msg: >- + expected %select{%error|provided|member|potential member|dynamic member}0 + dependency does not exist: %1 + +- id: unexpected_dependency + msg: >- + unexpected %0 %select{%error|%error|member|potential member|dynamic + member}1 dependency: %2 + +- id: unexpected_provided_entity + msg: >- + unexpected provided entity: %0 + +- id: negative_expectation_violated + msg: >- + unexpected dependency exists: %0 + +- id: expectation_missing_opening_braces + msg: >- + expected {{ in expectation + +- id: expectation_missing_closing_braces + msg: >- + didn't find '}}' to match '{{' in expectation + +- id: module_incompatible_with_skip_function_bodies + msg: >- + module '%0' cannot be built with + -experimental-skip-non-inlinable-function-bodies; this option has been + automatically disabled + +- id: warning_parallel_execution_not_supported + msg: >- + parallel execution not supported; falling back to serial execution + +- id: error_unable_to_execute_command + msg: >- + unable to execute command: %0 + +- id: error_command_signalled_without_signal_number + msg: >- + %0 command failed due to signal (use -v to see invocation) + +- id: error_command_signalled + msg: >- + %0 command failed due to signal %1 (use -v to see invocation) + +- id: error_command_failed + msg: >- + %0 command failed with exit code %1 (use -v to see invocation) + +- id: error_expected_one_frontend_job + msg: >- + unable to handle compilation, expected exactly one frontend job + +- id: error_expected_frontend_command + msg: >- + expected a swift frontend command + +- id: error_cannot_specify__o_for_multiple_outputs + msg: >- + cannot specify -o when generating multiple output files + +- id: error_static_emit_executable_disallowed + msg: >- + -static may not be used with -emit-executable + +- id: error_unable_to_load_output_file_map + msg: >- + unable to load output file map '%1': %0 + +- id: error_no_output_file_map_specified + msg: >- + no output file map specified + +- id: error_unable_to_make_temporary_file + msg: >- + unable to make temporary file: %0 + +- id: error_no_input_files + msg: >- + no input files + +- id: error_unexpected_input_file + msg: >- + unexpected input file: %0 + +- id: error_unknown_target + msg: >- + unknown target '%0' + +- id: error_framework_bridging_header + msg: >- + using bridging headers with framework targets is unsupported + +- id: error_bridging_header_module_interface + msg: >- + using bridging headers with module interfaces is unsupported + +- id: error_i_mode + msg: >- + the flag '-i' is no longer required and has been removed; use '%0 + input-filename' + +- id: warning_unnecessary_repl_mode + msg: >- + unnecessary option '%0'; this is the default for '%1' with no input files + +- id: error_unsupported_option + msg: >- + option '%0' is not supported by '%1'; did you mean to use '%2'? + +- id: incremental_requires_output_file_map + msg: >- + ignoring -incremental (currently requires an output file map) + +- id: incremental_requires_build_record_entry + msg: >- + ignoring -incremental; output file map has no master dependencies entry + ("%0" under "") + +- id: unable_to_open_incremental_comparison_log + msg: >- + unable to open incremental comparison log file '%0' + +- id: error_os_minimum_deployment + msg: >- + Swift requires a minimum deployment target of %0 + +- id: error_sdk_too_old + msg: >- + Swift does not support the SDK '%0' + +- id: error_ios_maximum_deployment_32 + msg: >- + iOS %0 does not support 32-bit programs + +- id: error_unsupported_target_variant + msg: >- + unsupported '%select{-target|-target-variant}1' value '%0'; use + 'ios-macabi' instead + +- id: warn_arclite_not_found_when_link_objc_runtime + msg: >- + unable to find Objective-C runtime support library 'arclite'; pass + '-no-link-objc-runtime' to silence this warning + +- id: error_two_files_same_name + msg: >- + filename "%0" used twice: '%1' and '%2' + +- id: note_explain_two_files_same_name + msg: >- + filenames are used to distinguish private declarations with the same name + +- id: warn_cannot_stat_input + msg: >- + unable to determine when '%0' was last modified: %1 + +- id: warn_unable_to_load_dependencies + msg: >- + unable to load dependencies file "%0", disabling incremental mode + +- id: error_input_changed_during_build + msg: >- + input file '%0' was modified during the build + +- id: error_conflicting_options + msg: >- + conflicting options '%0' and '%1' + +- id: error_option_not_supported + msg: >- + '%0' is not supported with '%1' + +- id: warn_ignore_embed_bitcode + msg: >- + ignoring -embed-bitcode since no object file is being generated + +- id: warn_ignore_embed_bitcode_marker + msg: >- + ignoring -embed-bitcode-marker since no object file is being generated + +- id: verify_debug_info_requires_debug_option + msg: >- + ignoring '-verify-debug-info'; no debug info is being generated + +- id: verify_incremental_dependencies_needs_incremental + msg: >- + '-verify-incremental-dependencies' requires '-incremental' + +- id: error_profile_missing + msg: >- + no profdata file exists at '%0' + +- id: warn_opt_remark_disabled + msg: >- + Emission of optimization records has been disabled, because it requires a + single compiler invocation: consider enabling the -whole-module-optimization + flag + +- id: warn_ignoring_batch_mode + msg: >- + ignoring '-enable-batch-mode' because '%0' was also specified + +- id: warn_ignoring_wmo + msg: >- + ignoring '-wmo' because '-dump-ast' was also specified + +- id: warn_ignoring_source_range_dependencies + msg: >- + ignoring '-enable-source-range-dependencies' because '%0' was also specified + +- id: warn_bad_swift_ranges_header + msg: >- + ignoring '-enable-source-range-dependencies' because of bad header in '%0' + +- id: warn_bad_swift_ranges_format + msg: >- + ignoring '-enable-source-range-dependencies' because of bad format '%1' + in '%0' + +- id: warn_use_filelists_deprecated + msg: >- + the option '-driver-use-filelists' is deprecated; use + '-driver-filelist-threshold=0' instead + +- id: warn_unable_to_load_swift_ranges + msg: >- + unable to load swift ranges file "%0", %1 + +- id: warn_unable_to_load_compiled_swift + msg: >- + unable to load previously compiled swift file "%0", %1 + +- id: warn_unable_to_load_primary + msg: >- + unable to load primary swift file "%0", %1 + +- id: cannot_find_migration_script + msg: >- + missing migration script from path '%0' + +- id: error_darwin_static_stdlib_not_supported + msg: >- + -static-stdlib is no longer supported on Apple platforms + +- id: warn_drv_darwin_sdk_invalid_settings + msg: >- + SDK settings were ignored because 'SDKSettings.json' could not be parsed + +- id: invalid_name + msg: >- + '%0' is not a valid name + +- id: invalid_location + msg: >- + given location is not valid + +- id: arity_mismatch + msg: >- + the given new name '%0' does not match the arity of the old name '%1' + +- id: name_not_functionlike + msg: >- + the 'call' name usage cannot be used with a non-function-like name '%0' + +- id: unresolved_location + msg: >- + cannot resolve location as name + +- id: location_module_mismatch + msg: >- + given location does not belong to module '%0' + +- id: value_decl_no_loc + msg: >- + value decl '%0' has no declaration location + +- id: value_decl_referenced_out_of_range + msg: >- + value decl '%0' is referenced out of range + +- id: multi_entry_range + msg: >- + selected range has more than one entry point + +- id: orphan_loop_keyword + msg: >- + selected range contains %0 but not its target loop + +- id: invalid_default_location + msg: >- + given location is not on a default statement + +- id: no_parent_switch + msg: >- + cannot find enclosing switch statement + +- id: no_remaining_cases + msg: >- + no remaining cases to expand + +- id: mismatched_rename + msg: >- + the name at the given location cannot be renamed to '%0' + +- id: no_insert_position + msg: >- + cannot find inserting position + +- id: generic_sig_change + msg: >- + %0 has generic signature change from %1 to %2 + +- id: raw_type_change + msg: >- + %0(%1) is now %2 representable + +- id: removed_decl + msg: >- + %0 has been removed%select{| (deprecated)}1 + +- id: moved_decl + msg: >- + %0 has been moved to %1 + +- id: renamed_decl + msg: >- + %0 has been renamed to %1 + +- id: decl_type_change + msg: >- + %0 has %1 type change from %2 to %3 + +- id: decl_attr_change + msg: >- + %0 changes from %1 to %2 + +- id: decl_new_attr + msg: >- + %0 is now %1 + +- id: decl_reorder + msg: >- + %0 in a non-resilient type changes position from %1 to %2 + +- id: decl_added + msg: >- + %0 is added to a non-resilient type + +- id: var_has_fixed_order_change + msg: >- + %0 is %select{now|no longer}1 a stored property + +- id: func_has_fixed_order_change + msg: >- + %0 is %select{now|no longer}1 a non-final instance function + +- id: default_arg_removed + msg: >- + %0 has removed default argument from %1 + +- id: conformance_removed + msg: >- + %0 has removed %select{conformance to|inherited protocol}2 %1 + +- id: conformance_added + msg: >- + %0 has added inherited protocol %1 + +- id: existing_conformance_added + msg: >- + %0 has added a conformance to an existing protocol %1 + +- id: default_associated_type_removed + msg: >- + %0 has removed default type %1 + +- id: protocol_req_added + msg: >- + %0 has been added as a protocol requirement + +- id: super_class_removed + msg: >- + %0 has removed its super class %1 + +- id: super_class_changed + msg: >- + %0 has changed its super class from %1 to %2 + +- id: decl_kind_changed + msg: >- + %0 has been changed to a %1 + +- id: optional_req_changed + msg: >- + %0 is %select{now|no longer}1 an optional requirement + +- id: no_longer_open + msg: >- + %0 is no longer open for subclassing + +- id: func_type_escaping_changed + msg: >- + %0 has %select{removed|added}2 @escaping in %1 + +- id: func_self_access_change + msg: >- + %0 has self access kind changing from %1 to %2 + +- id: param_ownership_change + msg: >- + %0 has %1 changing from %2 to %3 + +- id: type_witness_change + msg: >- + %0 has type witness type for %1 changing from %2 to %3 + +- id: decl_new_witness_table_entry + msg: >- + %0 now requires %select{|no}1 new witness table entry + +- id: new_decl_without_intro + msg: >- + %0 is a new API without @available attribute + +- id: objc_name_change + msg: >- + %0 has ObjC name change from %1 to %2 + +- id: desig_init_added + msg: >- + %0 has been added as a designated initializer to an open class + +- id: added_invisible_designated_init + msg: >- + %0 has new designated initializers that are not visible to clients + +- id: not_inheriting_convenience_inits + msg: >- + %0 no longer inherits convenience inits from its superclass + +- id: enum_case_added + msg: >- + %0 has been added as a new enum case + diff --git a/include/swift/Serialization/SerializedModuleLoader.h b/include/swift/Serialization/SerializedModuleLoader.h index df1788fc8cd9a..0eb1690aa6ed7 100644 --- a/include/swift/Serialization/SerializedModuleLoader.h +++ b/include/swift/Serialization/SerializedModuleLoader.h @@ -58,7 +58,7 @@ class SerializedModuleLoaderBase : public ModuleLoader { using LoadedModulePair = std::pair, unsigned>; std::vector LoadedModuleFiles; - SmallVector, 2> OrphanedMemoryBuffers; + SmallVector, 2> OrphanedModuleFiles; protected: ASTContext &Ctx; diff --git a/include/swift/Strings.h b/include/swift/Strings.h index 506954fc39029..32a7bb2d0072c 100644 --- a/include/swift/Strings.h +++ b/include/swift/Strings.h @@ -26,6 +26,8 @@ constexpr static const StringLiteral SWIFT_ONONE_SUPPORT = "SwiftOnoneSupport"; constexpr static const StringLiteral SWIFT_SHIMS_NAME = "SwiftShims"; /// The name of the Builtin module, which contains Builtin functions. constexpr static const StringLiteral BUILTIN_NAME = "Builtin"; +/// The name of the clang imported header module. +constexpr static const StringLiteral CLANG_HEADER_MODULE_NAME = "__ObjC"; /// The prefix of module names used by LLDB to capture Swift expressions constexpr static const StringLiteral LLDB_EXPRESSIONS_MODULE_NAME_PREFIX = "__lldb_expr_"; diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 539b3027cc09b..620990a9511f6 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -40,6 +40,7 @@ #include "swift/Config.h" #include "swift/Parse/Lexer.h" #include "swift/Parse/Parser.h" +#include "swift/Strings.h" #include "swift/Subsystems.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Mangle.h" @@ -1196,7 +1197,8 @@ ClangImporter::create(ASTContext &ctx, const ClangImporterOptions &importerOpts, = clangContext.Selectors.getSelector(2, setObjectForKeyedSubscriptIdents); // Set up the imported header module. - auto *importedHeaderModule = ModuleDecl::create(ctx.getIdentifier("__ObjC"), ctx); + auto *importedHeaderModule = + ModuleDecl::create(ctx.getIdentifier(CLANG_HEADER_MODULE_NAME), ctx); importer->Impl.ImportedHeaderUnit = new (ctx) ClangModuleUnit(*importedHeaderModule, importer->Impl, nullptr); importedHeaderModule->addFile(*importer->Impl.ImportedHeaderUnit); diff --git a/lib/SILOptimizer/IPO/GlobalOpt.cpp b/lib/SILOptimizer/IPO/GlobalOpt.cpp index 4c5178eba7f3d..515c312cdab90 100644 --- a/lib/SILOptimizer/IPO/GlobalOpt.cpp +++ b/lib/SILOptimizer/IPO/GlobalOpt.cpp @@ -713,11 +713,6 @@ void SILGlobalOpt::reset() { void SILGlobalOpt::collect() { for (auto &F : *Module) { - // TODO: Add support for ownership. - if (F.hasOwnership()) { - continue; - } - // Make sure to create an entry. This is important in case a global variable // (e.g. a public one) is not used inside the same module. if (F.isGlobalInit()) diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp index 5152ff23e24c8..26a960875a91d 100644 --- a/lib/Sema/TypeCheckConstraints.cpp +++ b/lib/Sema/TypeCheckConstraints.cpp @@ -1157,7 +1157,7 @@ namespace { ExprStack.pop_back(); // Mark the direct callee as being a callee. - if (auto *call = dyn_cast(expr)) + if (auto *call = dyn_cast(expr)) markDirectCallee(call->getFn()); // Fold sequence expressions. diff --git a/lib/Serialization/CMakeLists.txt b/lib/Serialization/CMakeLists.txt index 90e73ee5ed30c..9a795e3a9b64d 100644 --- a/lib/Serialization/CMakeLists.txt +++ b/lib/Serialization/CMakeLists.txt @@ -3,6 +3,7 @@ add_swift_host_library(swiftSerialization STATIC DeserializeSIL.cpp ModuleDependencyScanner.cpp ModuleFile.cpp + ModuleFileSharedCore.cpp Serialization.cpp SerializedModuleLoader.cpp SerializedSILLoader.cpp diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index baebdbba93bd4..4237e03aa6e41 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -56,7 +56,7 @@ using namespace swift::serialization; using llvm::Expected; StringRef swift::getNameOfModule(const ModuleFile *MF) { - return MF->Name; + return MF->getName(); } namespace { @@ -166,13 +166,13 @@ static void skipRecord(llvm::BitstreamCursor &cursor, unsigned recordKind) { void ModuleFile::fatal(llvm::Error error) { if (FileContext) { - getContext().Diags.diagnose(SourceLoc(), diag::serialization_fatal, Name); + getContext().Diags.diagnose(SourceLoc(), diag::serialization_fatal, Core->Name); getContext().Diags.diagnose(SourceLoc(), diag::serialization_misc_version, - Name, MiscVersion); + Core->Name, Core->MiscVersion); - if (!CompatibilityVersion.empty()) { + if (!Core->CompatibilityVersion.empty()) { if (getContext().LangOpts.EffectiveLanguageVersion - != CompatibilityVersion) { + != Core->CompatibilityVersion) { SmallString<16> effectiveVersionBuffer, compatVersionBuffer; { llvm::raw_svector_ostream out(effectiveVersionBuffer); @@ -180,19 +180,16 @@ void ModuleFile::fatal(llvm::Error error) { } { llvm::raw_svector_ostream out(compatVersionBuffer); - out << CompatibilityVersion; + out << Core->CompatibilityVersion; } getContext().Diags.diagnose( SourceLoc(), diag::serialization_compatibility_version_mismatch, - effectiveVersionBuffer, Name, compatVersionBuffer); + effectiveVersionBuffer, Core->Name, compatVersionBuffer); } } } - logAllUnhandledErrors(std::move(error), llvm::errs(), - "\n*** DESERIALIZATION FAILURE (please include this " - "section in any bug report) ***\n"); - abort(); + ModuleFileSharedCore::fatal(std::move(error)); } static Optional @@ -1871,13 +1868,7 @@ StringRef ModuleFile::getIdentifierText(IdentifierID IID) { if (!identRecord.Ident.empty()) return identRecord.Ident.str(); - assert(!IdentifierData.empty() && "no identifier data in module"); - - StringRef rawStrPtr = IdentifierData.substr(identRecord.Offset); - size_t terminatorOffset = rawStrPtr.find('\0'); - assert(terminatorOffset != StringRef::npos && - "unterminated identifier string data"); - return rawStrPtr.slice(0, terminatorOffset); + return Core->getIdentifierText(IID); } DeclContext *ModuleFile::getLocalDeclContext(LocalDeclContextID DCID) { diff --git a/lib/Serialization/DeserializationErrors.h b/lib/Serialization/DeserializationErrors.h index 318eeb9c5de9b..bf46e12af52f0 100644 --- a/lib/Serialization/DeserializationErrors.h +++ b/lib/Serialization/DeserializationErrors.h @@ -21,8 +21,10 @@ namespace swift { class ModuleFile; +class ModuleFileSharedCore; StringRef getNameOfModule(const ModuleFile *); +StringRef getNameOfModule(const ModuleFileSharedCore *); namespace serialization { @@ -456,6 +458,17 @@ class PrettyStackTraceModuleFile : public llvm::PrettyStackTraceEntry { } }; +class PrettyStackTraceModuleFileCore : public llvm::PrettyStackTraceEntry { + const ModuleFileSharedCore &MF; +public: + explicit PrettyStackTraceModuleFileCore(ModuleFileSharedCore &module) + : MF(module) {} + + void print(raw_ostream &os) const override { + os << "While reading from \'" << getNameOfModule(&MF) << "'\n"; + } +}; + } // end namespace serialization } // end namespace swift diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp index 6cc6d6f7e8a15..e2f8a402ac467 100644 --- a/lib/Serialization/DeserializeSIL.cpp +++ b/lib/Serialization/DeserializeSIL.cpp @@ -666,7 +666,7 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn, // Mark this function as deserialized. This avoids rerunning diagnostic // passes. Certain passes in the madatory pipeline may not work as expected // after arbitrary optimization and lowering. - if (!MF->IsSIB) + if (!MF->isSIB()) fn->setWasDeserializedCanonical(); fn->setBare(IsBare); diff --git a/lib/Serialization/ModuleFile.cpp b/lib/Serialization/ModuleFile.cpp index 95f3d883f788d..7b17160859a72 100644 --- a/lib/Serialization/ModuleFile.cpp +++ b/lib/Serialization/ModuleFile.cpp @@ -11,10 +11,9 @@ //===----------------------------------------------------------------------===// #include "ModuleFile.h" +#include "ModuleFileCoreTableInfo.h" #include "BCReadingExtras.h" #include "DeserializationErrors.h" -#include "DocFormat.h" -#include "SourceInfoFormat.h" #include "ModuleFormat.h" #include "swift/Serialization/SerializationOptions.h" #include "swift/Subsystems.h" @@ -30,7 +29,6 @@ #include "swift/Serialization/SerializedModuleLoader.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Chrono.h" -#include "llvm/Support/DJB.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/OnDiskHashTable.h" @@ -42,1288 +40,6 @@ using llvm::Expected; static_assert(IsTriviallyDestructible::value, "SerializedASTFiles are BumpPtrAllocated; d'tors are not called"); -static bool checkModuleSignature(llvm::BitstreamCursor &cursor, - ArrayRef signature) { - for (unsigned char byte : signature) { - if (cursor.AtEndOfStream()) - return false; - if (Expected maybeRead = - cursor.Read(8)) { - if (maybeRead.get() != byte) - return false; - } else { - consumeError(maybeRead.takeError()); - return false; - } - } - return true; -} - -static bool enterTopLevelModuleBlock(llvm::BitstreamCursor &cursor, - unsigned ID, - bool shouldReadBlockInfo = true) { - Expected maybeNext = cursor.advance(); - if (!maybeNext) { - // FIXME this drops the error on the floor. - consumeError(maybeNext.takeError()); - return false; - } - llvm::BitstreamEntry next = maybeNext.get(); - - if (next.Kind != llvm::BitstreamEntry::SubBlock) - return false; - - if (next.ID == llvm::bitc::BLOCKINFO_BLOCK_ID) { - if (shouldReadBlockInfo) { - if (!cursor.ReadBlockInfoBlock()) - return false; - } else { - if (cursor.SkipBlock()) - return false; - } - return enterTopLevelModuleBlock(cursor, ID, false); - } - - if (next.ID != ID) - return false; - - if (llvm::Error Err = cursor.EnterSubBlock(ID)) { - // FIXME this drops the error on the floor. - consumeError(std::move(Err)); - return false; - } - - return true; -} - -/// Populate \p extendedInfo with the data from the options block. -/// -/// Returns true on success. -static bool readOptionsBlock(llvm::BitstreamCursor &cursor, - SmallVectorImpl &scratch, - ExtendedValidationInfo &extendedInfo) { - while (!cursor.AtEndOfStream()) { - Expected maybeEntry = cursor.advance(); - if (!maybeEntry) { - // FIXME this drops the error on the floor. - consumeError(maybeEntry.takeError()); - return false; - } - llvm::BitstreamEntry entry = maybeEntry.get(); - if (entry.Kind == llvm::BitstreamEntry::EndBlock) - break; - - if (entry.Kind == llvm::BitstreamEntry::Error) - return false; - - if (entry.Kind == llvm::BitstreamEntry::SubBlock) { - // Unknown metadata sub-block, possibly for use by a future version of - // the module format. - if (cursor.SkipBlock()) - return false; - continue; - } - - scratch.clear(); - StringRef blobData; - Expected maybeKind = - cursor.readRecord(entry.ID, scratch, &blobData); - if (!maybeKind) { - // FIXME this drops the error on the floor. - consumeError(maybeKind.takeError()); - return false; - } - unsigned kind = maybeKind.get(); - switch (kind) { - case options_block::SDK_PATH: - extendedInfo.setSDKPath(blobData); - break; - case options_block::XCC: - extendedInfo.addExtraClangImporterOption(blobData); - break; - case options_block::IS_SIB: - bool IsSIB; - options_block::IsSIBLayout::readRecord(scratch, IsSIB); - extendedInfo.setIsSIB(IsSIB); - break; - case options_block::IS_TESTABLE: - extendedInfo.setIsTestable(true); - break; - case options_block::ARE_PRIVATE_IMPORTS_ENABLED: - extendedInfo.setPrivateImportsEnabled(true); - break; - case options_block::IS_IMPLICIT_DYNAMIC_ENABLED: - extendedInfo.setImplicitDynamicEnabled(true); - break; - case options_block::RESILIENCE_STRATEGY: - unsigned Strategy; - options_block::ResilienceStrategyLayout::readRecord(scratch, Strategy); - extendedInfo.setResilienceStrategy(ResilienceStrategy(Strategy)); - break; - default: - // Unknown options record, possibly for use by a future version of the - // module format. - break; - } - } - - return true; -} - -static ValidationInfo -validateControlBlock(llvm::BitstreamCursor &cursor, - SmallVectorImpl &scratch, - std::pair expectedVersion, - ExtendedValidationInfo *extendedInfo) { - // The control block is malformed until we've at least read a major version - // number. - ValidationInfo result; - bool versionSeen = false; - - while (!cursor.AtEndOfStream()) { - Expected maybeEntry = cursor.advance(); - if (!maybeEntry) { - // FIXME this drops the error on the floor. - consumeError(maybeEntry.takeError()); - result.status = Status::Malformed; - return result; - } - llvm::BitstreamEntry entry = maybeEntry.get(); - if (entry.Kind == llvm::BitstreamEntry::EndBlock) - break; - - if (entry.Kind == llvm::BitstreamEntry::Error) { - result.status = Status::Malformed; - return result; - } - - if (entry.Kind == llvm::BitstreamEntry::SubBlock) { - if (entry.ID == OPTIONS_BLOCK_ID && extendedInfo) { - if (llvm::Error Err = cursor.EnterSubBlock(OPTIONS_BLOCK_ID)) { - // FIXME this drops the error on the floor. - consumeError(std::move(Err)); - result.status = Status::Malformed; - return result; - } - if (!readOptionsBlock(cursor, scratch, *extendedInfo)) { - result.status = Status::Malformed; - return result; - } - } else { - // Unknown metadata sub-block, possibly for use by a future version of - // the module format. - if (cursor.SkipBlock()) { - result.status = Status::Malformed; - return result; - } - } - continue; - } - - scratch.clear(); - StringRef blobData; - Expected maybeKind = - cursor.readRecord(entry.ID, scratch, &blobData); - if (!maybeKind) { - // FIXME this drops the error on the floor. - consumeError(maybeKind.takeError()); - result.status = Status::Malformed; - return result; - } - unsigned kind = maybeKind.get(); - switch (kind) { - case control_block::METADATA: { - if (versionSeen) { - result.status = Status::Malformed; - break; - } - - uint16_t versionMajor = scratch[0]; - if (versionMajor > expectedVersion.first) - result.status = Status::FormatTooNew; - else if (versionMajor < expectedVersion.first) - result.status = Status::FormatTooOld; - else - result.status = Status::Valid; - - // Major version 0 does not have stable minor versions. - if (versionMajor == 0) { - uint16_t versionMinor = scratch[1]; - if (versionMinor != expectedVersion.second) { - if (versionMinor < expectedVersion.second) - result.status = Status::FormatTooOld; - else - result.status = Status::FormatTooNew; - } - } - - // These fields were added later; be resilient against their absence. - switch (scratch.size()) { - default: - // Add new cases here, in descending order. - case 4: - if (scratch[3] != 0) { - result.compatibilityVersion = - version::Version(blobData.substr(scratch[2]+1, scratch[3]), - SourceLoc(), nullptr); - } - LLVM_FALLTHROUGH; - case 3: - result.shortVersion = blobData.slice(0, scratch[2]); - LLVM_FALLTHROUGH; - case 2: - case 1: - case 0: - break; - } - - result.miscVersion = blobData; - versionSeen = true; - break; - } - case control_block::MODULE_NAME: - result.name = blobData; - break; - case control_block::TARGET: - result.targetTriple = blobData; - break; - default: - // Unknown metadata record, possibly for use by a future version of the - // module format. - break; - } - } - - return result; -} - -static bool validateInputBlock( - llvm::BitstreamCursor &cursor, SmallVectorImpl &scratch, - SmallVectorImpl &dependencies) { - SmallVector dependencyDirectories; - SmallString<256> dependencyFullPathBuffer; - - while (!cursor.AtEndOfStream()) { - Expected maybeEntry = cursor.advance(); - if (!maybeEntry) { - // FIXME this drops the error on the floor. - consumeError(maybeEntry.takeError()); - return true; - } - llvm::BitstreamEntry entry = maybeEntry.get(); - if (entry.Kind == llvm::BitstreamEntry::EndBlock) - break; - - if (entry.Kind == llvm::BitstreamEntry::Error) - return true; - - scratch.clear(); - StringRef blobData; - Expected maybeKind = - cursor.readRecord(entry.ID, scratch, &blobData); - if (!maybeKind) { - // FIXME this drops the error on the floor. - consumeError(maybeKind.takeError()); - return true; - } - unsigned kind = maybeKind.get(); - switch (kind) { - case input_block::FILE_DEPENDENCY: { - bool isHashBased = scratch[2] != 0; - bool isSDKRelative = scratch[3] != 0; - - StringRef path = blobData; - size_t directoryIndex = scratch[4]; - if (directoryIndex != 0) { - if (directoryIndex > dependencyDirectories.size()) - return true; - dependencyFullPathBuffer = dependencyDirectories[directoryIndex-1]; - llvm::sys::path::append(dependencyFullPathBuffer, blobData); - path = dependencyFullPathBuffer; - } - - if (isHashBased) { - dependencies.push_back( - SerializationOptions::FileDependency::hashBased( - path, isSDKRelative, scratch[0], scratch[1])); - } else { - dependencies.push_back( - SerializationOptions::FileDependency::modTimeBased( - path, isSDKRelative, scratch[0], scratch[1])); - } - break; - } - case input_block::DEPENDENCY_DIRECTORY: - dependencyDirectories.push_back(blobData); - break; - default: - // Unknown metadata record, possibly for use by a future version of the - // module format. - break; - } - } - return false; -} - - -bool serialization::isSerializedAST(StringRef data) { - StringRef signatureStr(reinterpret_cast(SWIFTMODULE_SIGNATURE), - llvm::array_lengthof(SWIFTMODULE_SIGNATURE)); - return data.startswith(signatureStr); -} - -ValidationInfo serialization::validateSerializedAST( - StringRef data, - ExtendedValidationInfo *extendedInfo, - SmallVectorImpl *dependencies) { - ValidationInfo result; - - // Check 32-bit alignment. - if (data.size() % SWIFTMODULE_ALIGNMENT != 0 || - reinterpret_cast(data.data()) % SWIFTMODULE_ALIGNMENT != 0) - return result; - - llvm::BitstreamCursor cursor(data); - SmallVector scratch; - - if (!checkModuleSignature(cursor, SWIFTMODULE_SIGNATURE) || - !enterTopLevelModuleBlock(cursor, MODULE_BLOCK_ID, false)) - return result; - - llvm::BitstreamEntry topLevelEntry; - - while (!cursor.AtEndOfStream()) { - Expected maybeEntry = - cursor.advance(AF_DontPopBlockAtEnd); - if (!maybeEntry) { - // FIXME this drops the error on the floor. - consumeError(maybeEntry.takeError()); - result.status = Status::Malformed; - return result; - } - topLevelEntry = maybeEntry.get(); - if (topLevelEntry.Kind != llvm::BitstreamEntry::SubBlock) - break; - - if (topLevelEntry.ID == CONTROL_BLOCK_ID) { - if (llvm::Error Err = cursor.EnterSubBlock(CONTROL_BLOCK_ID)) { - // FIXME this drops the error on the floor. - consumeError(std::move(Err)); - result.status = Status::Malformed; - return result; - } - result = validateControlBlock(cursor, scratch, - {SWIFTMODULE_VERSION_MAJOR, - SWIFTMODULE_VERSION_MINOR}, - extendedInfo); - if (result.status == Status::Malformed) - return result; - } else if (dependencies && - result.status == Status::Valid && - topLevelEntry.ID == INPUT_BLOCK_ID) { - if (llvm::Error Err = cursor.EnterSubBlock(INPUT_BLOCK_ID)) { - // FIXME this drops the error on the floor. - consumeError(std::move(Err)); - result.status = Status::Malformed; - return result; - } - if (validateInputBlock(cursor, scratch, *dependencies)) { - result.status = Status::Malformed; - return result; - } - } else { - if (cursor.SkipBlock()) { - result.status = Status::Malformed; - return result; - } - } - } - - if (topLevelEntry.Kind == llvm::BitstreamEntry::EndBlock) { - cursor.ReadBlockEnd(); - assert(cursor.GetCurrentBitNo() % CHAR_BIT == 0); - result.bytes = cursor.GetCurrentBitNo() / CHAR_BIT; - } else { - result.status = Status::Malformed; - } - - return result; -} - -std::string ModuleFile::Dependency::getPrettyPrintedPath() const { - StringRef pathWithoutScope = RawPath; - if (isScoped()) { - size_t splitPoint = pathWithoutScope.find_last_of('\0'); - pathWithoutScope = pathWithoutScope.slice(0, splitPoint); - } - std::string output = pathWithoutScope.str(); - std::replace(output.begin(), output.end(), '\0', '.'); - return output; -} - -/// Used to deserialize entries in the on-disk decl hash table. -class ModuleFile::DeclTableInfo { -public: - using internal_key_type = std::pair; - using external_key_type = DeclBaseName; - using data_type = SmallVector, 8>; - using hash_value_type = uint32_t; - using offset_type = unsigned; - - internal_key_type GetInternalKey(external_key_type ID) { - if (ID.getKind() == DeclBaseName::Kind::Normal) { - return {DeclBaseName::Kind::Normal, ID.getIdentifier().str()}; - } else { - return {ID.getKind(), StringRef()}; - } - } - - hash_value_type ComputeHash(internal_key_type key) { - if (key.first == DeclBaseName::Kind::Normal) { - return llvm::djbHash(key.second, SWIFTMODULE_HASH_SEED); - } else { - return (hash_value_type)key.first; - } - } - - static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { - return lhs == rhs; - } - - static std::pair ReadKeyDataLength(const uint8_t *&data) { - unsigned keyLength = endian::readNext(data); - unsigned dataLength = endian::readNext(data); - return { keyLength, dataLength }; - } - - static internal_key_type ReadKey(const uint8_t *data, unsigned length) { - uint8_t kind = endian::readNext(data); - switch (kind) { - case static_cast(DeclNameKind::Normal): { - StringRef str(reinterpret_cast(data), - length - sizeof(uint8_t)); - return {DeclBaseName::Kind::Normal, str}; - } - case static_cast(DeclNameKind::Subscript): - return {DeclBaseName::Kind::Subscript, StringRef()}; - case static_cast(DeclNameKind::Destructor): - return {DeclBaseName::Kind::Destructor, StringRef()}; - default: - llvm_unreachable("Unknown DeclNameKind"); - } - } - - static data_type ReadData(internal_key_type key, const uint8_t *data, - unsigned length) { - data_type result; - while (length > 0) { - uint8_t kind = *data++; - DeclID offset = endian::readNext(data); - result.push_back({ kind, offset }); - length -= 5; - } - - return result; - } -}; - -/// Used to deserialize entries in the on-disk decl hash table. -class ModuleFile::ExtensionTableInfo { - ModuleFile &File; -public: - using internal_key_type = StringRef; - using external_key_type = Identifier; - using data_type = SmallVector, 8>; - using hash_value_type = uint32_t; - using offset_type = unsigned; - - internal_key_type GetInternalKey(external_key_type ID) { - return ID.str(); - } - - hash_value_type ComputeHash(internal_key_type key) { - return llvm::djbHash(key, SWIFTMODULE_HASH_SEED); - } - - static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { - return lhs == rhs; - } - - static std::pair ReadKeyDataLength(const uint8_t *&data) { - unsigned keyLength = endian::readNext(data); - unsigned dataLength = endian::readNext(data); - return { keyLength, dataLength }; - } - - static internal_key_type ReadKey(const uint8_t *data, unsigned length) { - return StringRef(reinterpret_cast(data), length); - } - - data_type ReadData(internal_key_type key, const uint8_t *data, - unsigned length) { - data_type result; - const uint8_t *limit = data + length; - while (data < limit) { - DeclID offset = endian::readNext(data); - - int32_t nameIDOrLength = - endian::readNext(data); - StringRef moduleNameOrMangledBase; - if (nameIDOrLength < 0) { - const ModuleDecl *module = File.getModule(-nameIDOrLength); - if (module) - moduleNameOrMangledBase = module->getName().str(); - } else { - moduleNameOrMangledBase = - StringRef(reinterpret_cast(data), nameIDOrLength); - data += nameIDOrLength; - } - - result.push_back({ moduleNameOrMangledBase, offset }); - } - - return result; - } - - explicit ExtensionTableInfo(ModuleFile &file) : File(file) {} -}; - -/// Used to deserialize entries in the on-disk decl hash table. -class ModuleFile::LocalDeclTableInfo { -public: - using internal_key_type = StringRef; - using external_key_type = internal_key_type; - using data_type = DeclID; - using hash_value_type = uint32_t; - using offset_type = unsigned; - - internal_key_type GetInternalKey(external_key_type ID) { - return ID; - } - - external_key_type GetExternalKey(internal_key_type ID) { - return ID; - } - - hash_value_type ComputeHash(internal_key_type key) { - return llvm::djbHash(key, SWIFTMODULE_HASH_SEED); - } - - static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { - return lhs == rhs; - } - - static std::pair ReadKeyDataLength(const uint8_t *&data) { - unsigned keyLength = endian::readNext(data); - return { keyLength, sizeof(uint32_t) }; - } - - static internal_key_type ReadKey(const uint8_t *data, unsigned length) { - return StringRef(reinterpret_cast(data), length); - } - - static data_type ReadData(internal_key_type key, const uint8_t *data, - unsigned length) { - return endian::readNext(data); - } -}; - -class ModuleFile::NestedTypeDeclsTableInfo { -public: - using internal_key_type = StringRef; - using external_key_type = Identifier; - using data_type = SmallVector, 4>; - using hash_value_type = uint32_t; - using offset_type = unsigned; - - internal_key_type GetInternalKey(external_key_type ID) { - return ID.str(); - } - - hash_value_type ComputeHash(internal_key_type key) { - return llvm::djbHash(key, SWIFTMODULE_HASH_SEED); - } - - static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { - return lhs == rhs; - } - - static std::pair ReadKeyDataLength(const uint8_t *&data) { - unsigned keyLength = endian::readNext(data); - unsigned dataLength = endian::readNext(data); - return { keyLength, dataLength }; - } - - static internal_key_type ReadKey(const uint8_t *data, unsigned length) { - return StringRef(reinterpret_cast(data), length); - } - - static data_type ReadData(internal_key_type key, const uint8_t *data, - unsigned length) { - data_type result; - while (length > 0) { - DeclID parentID = endian::readNext(data); - DeclID childID = endian::readNext(data); - result.push_back({ parentID, childID }); - length -= sizeof(uint32_t) * 2; - } - - return result; - } -}; - -// Indexing the members of all Decls (well, NominalTypeDecls anyway) is -// accomplished by a 2-level hashtable scheme. The outer table here maps from -// DeclBaseNames to serialization::BitOffsets of sub-tables. The sub-tables -- -// SerializedDeclMembersTables, one table per name -- map from the enclosing -// (NominalTypeDecl) DeclID to a vector of DeclIDs of members of the nominal -// with the name. See DeclMembersTableInfo below. -class ModuleFile::DeclMemberNamesTableInfo { -public: - using internal_key_type = std::pair; - using external_key_type = DeclBaseName; - using data_type = serialization::BitOffset; - using hash_value_type = uint32_t; - using offset_type = unsigned; - - internal_key_type GetInternalKey(external_key_type ID) { - if (ID.getKind() == DeclBaseName::Kind::Normal) { - return {DeclBaseName::Kind::Normal, ID.getIdentifier().str()}; - } else { - return {ID.getKind(), StringRef()}; - } - } - - hash_value_type ComputeHash(internal_key_type key) { - if (key.first == DeclBaseName::Kind::Normal) { - return llvm::djbHash(key.second, SWIFTMODULE_HASH_SEED); - } else { - return (hash_value_type)key.first; - } - } - - static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { - return lhs == rhs; - } - - static std::pair ReadKeyDataLength(const uint8_t *&data) { - unsigned keyLength = endian::readNext(data); - return { keyLength, sizeof(uint32_t) }; - } - - static internal_key_type ReadKey(const uint8_t *data, unsigned length) { - uint8_t kind = endian::readNext(data); - switch (kind) { - case static_cast(DeclNameKind::Normal): { - StringRef str(reinterpret_cast(data), - length - sizeof(uint8_t)); - return {DeclBaseName::Kind::Normal, str}; - } - case static_cast(DeclNameKind::Subscript): - return {DeclBaseName::Kind::Subscript, StringRef()}; - case static_cast(DeclNameKind::Destructor): - return {DeclBaseName::Kind::Destructor, StringRef()}; - case static_cast(DeclNameKind::Constructor): - return {DeclBaseName::Kind::Constructor, StringRef()}; - default: - llvm_unreachable("Unknown DeclNameKind"); - } - } - - static data_type ReadData(internal_key_type key, const uint8_t *data, - unsigned length) { - assert(length == sizeof(uint32_t)); - return endian::readNext(data); - } -}; - -// Second half of the 2-level member name lookup scheme, see -// DeclMemberNamesTableInfo above. There is one of these tables for each member -// DeclBaseName N in the module, and it maps from enclosing DeclIDs (say: each -// NominalTypeDecl T that has members named N) to the set of N-named members of -// T. In other words, there are no names in this table: the names are one level -// up, this table just maps { Owner-DeclID => [Member-DeclID, ...] }. -class ModuleFile::DeclMembersTableInfo { -public: - using internal_key_type = uint32_t; - using external_key_type = DeclID; - using data_type = SmallVector; - using hash_value_type = uint32_t; - using offset_type = unsigned; - - internal_key_type GetInternalKey(external_key_type ID) { - return ID; - } - - hash_value_type ComputeHash(internal_key_type key) { - return llvm::hash_value(key); - } - - static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { - return lhs == rhs; - } - - static std::pair ReadKeyDataLength(const uint8_t *&data) { - unsigned dataLength = endian::readNext(data); - return { sizeof(uint32_t), dataLength }; - } - - static internal_key_type ReadKey(const uint8_t *data, unsigned length) { - return endian::readNext(data); - } - - static data_type ReadData(internal_key_type key, const uint8_t *data, - unsigned length) { - data_type result; - while (length > 0) { - DeclID declID = endian::readNext(data); - result.push_back(declID); - length -= sizeof(uint32_t); - } - return result; - } -}; - - -std::unique_ptr -ModuleFile::readDeclTable(ArrayRef fields, StringRef blobData) { - uint32_t tableOffset; - index_block::DeclListLayout::readRecord(fields, tableOffset); - auto base = reinterpret_cast(blobData.data()); - - using OwnedTable = std::unique_ptr; - return OwnedTable(SerializedDeclTable::Create(base + tableOffset, - base + sizeof(uint32_t), base)); -} - -std::unique_ptr -ModuleFile::readExtensionTable(ArrayRef fields, StringRef blobData) { - uint32_t tableOffset; - index_block::DeclListLayout::readRecord(fields, tableOffset); - auto base = reinterpret_cast(blobData.data()); - - using OwnedTable = std::unique_ptr; - return OwnedTable(SerializedExtensionTable::Create(base + tableOffset, - base + sizeof(uint32_t), base, ExtensionTableInfo(*this))); -} - -std::unique_ptr -ModuleFile::readLocalDeclTable(ArrayRef fields, StringRef blobData) { - uint32_t tableOffset; - index_block::DeclListLayout::readRecord(fields, tableOffset); - auto base = reinterpret_cast(blobData.data()); - - using OwnedTable = std::unique_ptr; - return OwnedTable(SerializedLocalDeclTable::Create(base + tableOffset, - base + sizeof(uint32_t), base)); -} - -std::unique_ptr -ModuleFile::readNestedTypeDeclsTable(ArrayRef fields, - StringRef blobData) { - uint32_t tableOffset; - index_block::NestedTypeDeclsLayout::readRecord(fields, tableOffset); - auto base = reinterpret_cast(blobData.data()); - - using OwnedTable = std::unique_ptr; - return OwnedTable(SerializedNestedTypeDeclsTable::Create(base + tableOffset, - base + sizeof(uint32_t), base)); -} - -std::unique_ptr -ModuleFile::readDeclMemberNamesTable(ArrayRef fields, - StringRef blobData) { - uint32_t tableOffset; - index_block::DeclMemberNamesLayout::readRecord(fields, tableOffset); - auto base = reinterpret_cast(blobData.data()); - - using OwnedTable = std::unique_ptr; - return OwnedTable(SerializedDeclMemberNamesTable::Create(base + tableOffset, - base + sizeof(uint32_t), base)); -} - -std::unique_ptr -ModuleFile::readDeclMembersTable(ArrayRef fields, - StringRef blobData) { - uint32_t tableOffset; - decl_member_tables_block::DeclMembersLayout::readRecord(fields, - tableOffset); - auto base = reinterpret_cast(blobData.data()); - - using OwnedTable = std::unique_ptr; - return OwnedTable(SerializedDeclMembersTable::Create(base + tableOffset, - base + sizeof(uint32_t), base)); -} - -/// Used to deserialize entries in the on-disk Objective-C method table. -class ModuleFile::ObjCMethodTableInfo { -public: - using internal_key_type = std::string; - using external_key_type = ObjCSelector; - using data_type = SmallVector, 8>; - using hash_value_type = uint32_t; - using offset_type = unsigned; - - internal_key_type GetInternalKey(external_key_type ID) { - llvm::SmallString<32> scratch; - return ID.getString(scratch).str(); - } - - hash_value_type ComputeHash(internal_key_type key) { - return llvm::djbHash(key, SWIFTMODULE_HASH_SEED); - } - - static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { - return lhs == rhs; - } - - static std::pair ReadKeyDataLength(const uint8_t *&data) { - unsigned keyLength = endian::readNext(data); - unsigned dataLength = endian::readNext(data); - return { keyLength, dataLength }; - } - - static internal_key_type ReadKey(const uint8_t *data, unsigned length) { - return std::string(reinterpret_cast(data), length); - } - - static data_type ReadData(internal_key_type key, const uint8_t *data, - unsigned length) { - const constexpr auto recordSize = sizeof(uint32_t) + 1 + sizeof(uint32_t); - data_type result; - while (length > 0) { - unsigned ownerLen = endian::readNext(data); - bool isInstanceMethod = *data++ != 0; - DeclID methodID = endian::readNext(data); - std::string ownerName((const char *)data, ownerLen); - result.push_back( - std::make_tuple(std::move(ownerName), isInstanceMethod, methodID)); - data += ownerLen; - length -= (recordSize + ownerLen); - } - - return result; - } -}; - -std::unique_ptr -ModuleFile::readObjCMethodTable(ArrayRef fields, StringRef blobData) { - uint32_t tableOffset; - index_block::ObjCMethodTableLayout::readRecord(fields, tableOffset); - auto base = reinterpret_cast(blobData.data()); - - using OwnedTable = std::unique_ptr; - return OwnedTable( - SerializedObjCMethodTable::Create(base + tableOffset, - base + sizeof(uint32_t), base)); -} - -/// Used to deserialize entries in the on-disk derivative function configuration -/// table. -class ModuleFile::DerivativeFunctionConfigTableInfo { -public: - using internal_key_type = StringRef; - using external_key_type = internal_key_type; - using data_type = SmallVector, 8>; - using hash_value_type = uint32_t; - using offset_type = unsigned; - - external_key_type GetExternalKey(internal_key_type ID) { return ID; } - - internal_key_type GetInternalKey(external_key_type ID) { return ID; } - - hash_value_type ComputeHash(internal_key_type key) { - return llvm::djbHash(key, SWIFTMODULE_HASH_SEED); - } - - static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { - return lhs == rhs; - } - - static std::pair ReadKeyDataLength(const uint8_t *&data) { - unsigned keyLength = endian::readNext(data); - unsigned dataLength = endian::readNext(data); - return {keyLength, dataLength}; - } - - static internal_key_type ReadKey(const uint8_t *data, unsigned length) { - return StringRef(reinterpret_cast(data), length); - } - - static data_type ReadData(internal_key_type key, const uint8_t *data, - unsigned length) { - data_type result; - const uint8_t *limit = data + length; - while (data < limit) { - DeclID genSigId = endian::readNext(data); - int32_t nameLength = endian::readNext(data); - StringRef mangledName(reinterpret_cast(data), nameLength); - data += nameLength; - result.push_back({mangledName, genSigId}); - } - return result; - } -}; - -std::unique_ptr -ModuleFile::readDerivativeFunctionConfigTable(ArrayRef fields, - StringRef blobData) { - uint32_t tableOffset; - index_block::DerivativeFunctionConfigTableLayout::readRecord(fields, - tableOffset); - auto base = reinterpret_cast(blobData.data()); - - using OwnedTable = std::unique_ptr; - return OwnedTable(SerializedDerivativeFunctionConfigTable::Create( - base + tableOffset, base + sizeof(uint32_t), base)); -} - -bool ModuleFile::readIndexBlock(llvm::BitstreamCursor &cursor) { - if (llvm::Error Err = cursor.EnterSubBlock(INDEX_BLOCK_ID)) { - // FIXME this drops the error on the floor. - consumeError(std::move(Err)); - return false; - } - - SmallVector scratch; - StringRef blobData; - - while (!cursor.AtEndOfStream()) { - Expected maybeEntry = cursor.advance(); - if (!maybeEntry) { - // FIXME this drops the error on the floor. - consumeError(maybeEntry.takeError()); - return false; - } - llvm::BitstreamEntry entry = maybeEntry.get(); - switch (entry.Kind) { - case llvm::BitstreamEntry::EndBlock: - return true; - - case llvm::BitstreamEntry::Error: - return false; - - case llvm::BitstreamEntry::SubBlock: - if (entry.ID == DECL_MEMBER_TABLES_BLOCK_ID) { - DeclMemberTablesCursor = cursor; - if (llvm::Error Err = DeclMemberTablesCursor.EnterSubBlock( - DECL_MEMBER_TABLES_BLOCK_ID)) { - // FIXME this drops the error on the floor. - consumeError(std::move(Err)); - return false; - } - llvm::BitstreamEntry subentry; - do { - // Scan forward, to load the cursor with any abbrevs we'll need while - // seeking inside this block later. - Expected maybeEntry = - DeclMemberTablesCursor.advance( - llvm::BitstreamCursor::AF_DontPopBlockAtEnd); - if (!maybeEntry) { - // FIXME this drops the error on the floor. - consumeError(maybeEntry.takeError()); - return false; - } - subentry = maybeEntry.get(); - } while (!DeclMemberTablesCursor.AtEndOfStream() && - subentry.Kind != llvm::BitstreamEntry::Record && - subentry.Kind != llvm::BitstreamEntry::EndBlock); - } - if (cursor.SkipBlock()) - return false; - break; - - case llvm::BitstreamEntry::Record: - scratch.clear(); - blobData = {}; - Expected maybeKind = - cursor.readRecord(entry.ID, scratch, &blobData); - if (!maybeKind) { - // FIXME this drops the error on the floor. - consumeError(maybeKind.takeError()); - return false; - } - unsigned kind = maybeKind.get(); - - switch (kind) { - case index_block::DECL_OFFSETS: - assert(blobData.empty()); - allocateBuffer(Decls, scratch); - break; - case index_block::TYPE_OFFSETS: - assert(blobData.empty()); - allocateBuffer(Types, scratch); - break; - case index_block::CLANG_TYPE_OFFSETS: - assert(blobData.empty()); - allocateBuffer(ClangTypes, scratch); - break; - case index_block::IDENTIFIER_OFFSETS: - assert(blobData.empty()); - allocateBuffer(Identifiers, scratch); - break; - case index_block::TOP_LEVEL_DECLS: - TopLevelDecls = readDeclTable(scratch, blobData); - break; - case index_block::OPERATORS: - OperatorDecls = readDeclTable(scratch, blobData); - break; - case index_block::PRECEDENCE_GROUPS: - PrecedenceGroupDecls = readDeclTable(scratch, blobData); - break; - case index_block::EXTENSIONS: - ExtensionDecls = readExtensionTable(scratch, blobData); - break; - case index_block::CLASS_MEMBERS_FOR_DYNAMIC_LOOKUP: - ClassMembersForDynamicLookup = readDeclTable(scratch, blobData); - break; - case index_block::OPERATOR_METHODS: - OperatorMethodDecls = readDeclTable(scratch, blobData); - break; - case index_block::OBJC_METHODS: - ObjCMethods = readObjCMethodTable(scratch, blobData); - break; - case index_block::DERIVATIVE_FUNCTION_CONFIGURATIONS: - DerivativeFunctionConfigurations = - readDerivativeFunctionConfigTable(scratch, blobData); - break; - case index_block::ENTRY_POINT: - assert(blobData.empty()); - setEntryPointClassID(scratch.front()); - break; - case index_block::ORDERED_TOP_LEVEL_DECLS: - allocateBuffer(OrderedTopLevelDecls, scratch); - break; - case index_block::LOCAL_TYPE_DECLS: - LocalTypeDecls = readLocalDeclTable(scratch, blobData); - break; - case index_block::OPAQUE_RETURN_TYPE_DECLS: - OpaqueReturnTypeDecls = readLocalDeclTable(scratch, blobData); - break; - case index_block::NESTED_TYPE_DECLS: - NestedTypeDecls = readNestedTypeDeclsTable(scratch, blobData); - break; - case index_block::DECL_MEMBER_NAMES: - DeclMemberNames = readDeclMemberNamesTable(scratch, blobData); - break; - case index_block::LOCAL_DECL_CONTEXT_OFFSETS: - assert(blobData.empty()); - allocateBuffer(LocalDeclContexts, scratch); - break; - case index_block::GENERIC_SIGNATURE_OFFSETS: - assert(blobData.empty()); - allocateBuffer(GenericSignatures, scratch); - break; - case index_block::SUBSTITUTION_MAP_OFFSETS: - assert(blobData.empty()); - allocateBuffer(SubstitutionMaps, scratch); - break; - case index_block::NORMAL_CONFORMANCE_OFFSETS: - assert(blobData.empty()); - allocateBuffer(NormalConformances, scratch); - break; - case index_block::SIL_LAYOUT_OFFSETS: - assert(blobData.empty()); - allocateBuffer(SILLayouts, scratch); - break; - - default: - // Unknown index kind, which this version of the compiler won't use. - break; - } - break; - } - } - - return false; -} - -class ModuleFile::DeclCommentTableInfo { - ModuleFile &F; - -public: - using internal_key_type = StringRef; - using external_key_type = StringRef; - using data_type = CommentInfo; - using hash_value_type = uint32_t; - using offset_type = unsigned; - - DeclCommentTableInfo(ModuleFile &F) : F(F) {} - - internal_key_type GetInternalKey(external_key_type key) { - return key; - } - - hash_value_type ComputeHash(internal_key_type key) { - assert(!key.empty()); - return llvm::djbHash(key, SWIFTDOC_HASH_SEED_5_1); - } - - static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { - return lhs == rhs; - } - - static std::pair ReadKeyDataLength(const uint8_t *&data) { - unsigned keyLength = endian::readNext(data); - unsigned dataLength = endian::readNext(data); - return { keyLength, dataLength }; - } - - static internal_key_type ReadKey(const uint8_t *data, unsigned length) { - return StringRef(reinterpret_cast(data), length); - } - - data_type ReadData(internal_key_type key, const uint8_t *data, - unsigned length) { - data_type result; - - { - unsigned BriefSize = endian::readNext(data); - result.Brief = StringRef(reinterpret_cast(data), BriefSize); - data += BriefSize; - } - - unsigned NumComments = endian::readNext(data); - MutableArrayRef Comments = - F.getContext().AllocateUninitialized(NumComments); - - for (unsigned i = 0; i != NumComments; ++i) { - unsigned StartColumn = - endian::readNext(data); - unsigned RawSize = endian::readNext(data); - auto RawText = StringRef(reinterpret_cast(data), RawSize); - data += RawSize; - - new (&Comments[i]) SingleRawComment(RawText, StartColumn); - } - result.Raw = RawComment(Comments); - result.Group = endian::readNext(data); - result.SourceOrder = endian::readNext(data); - return result; - } -}; - -std::unique_ptr -ModuleFile::readDeclCommentTable(ArrayRef fields, - StringRef blobData) { - if (fields.empty() || blobData.empty()) - return nullptr; - uint32_t tableOffset = static_cast(fields.front()); - auto base = reinterpret_cast(blobData.data()); - - return std::unique_ptr( - SerializedDeclCommentTable::Create(base + tableOffset, - base + sizeof(uint32_t), base, - DeclCommentTableInfo(*this))); -} - -std::unique_ptr -ModuleFile::readGroupTable(ArrayRef Fields, StringRef BlobData) { - std::unique_ptr pMap( - new ModuleFile::GroupNameTable); - auto Data = reinterpret_cast(BlobData.data()); - unsigned GroupCount = endian::readNext(Data); - for (unsigned I = 0; I < GroupCount; ++I) { - auto RawSize = endian::readNext(Data); - auto RawText = StringRef(reinterpret_cast(Data), RawSize); - Data += RawSize; - (*pMap)[I] = RawText; - } - return pMap; -} - -bool ModuleFile::readCommentBlock(llvm::BitstreamCursor &cursor) { - if (llvm::Error Err = cursor.EnterSubBlock(COMMENT_BLOCK_ID)) { - // FIXME this drops the error on the floor. - consumeError(std::move(Err)); - return false; - } - - SmallVector scratch; - StringRef blobData; - - while (!cursor.AtEndOfStream()) { - Expected maybeEntry = cursor.advance(); - if (!maybeEntry) { - // FIXME this drops the error on the floor. - consumeError(maybeEntry.takeError()); - return false; - } - llvm::BitstreamEntry entry = maybeEntry.get(); - switch (entry.Kind) { - case llvm::BitstreamEntry::EndBlock: - return true; - - case llvm::BitstreamEntry::Error: - return false; - - case llvm::BitstreamEntry::SubBlock: - // Unknown sub-block, which this version of the compiler won't use. - if (cursor.SkipBlock()) - return false; - break; - - case llvm::BitstreamEntry::Record: - scratch.clear(); - Expected maybeKind = - cursor.readRecord(entry.ID, scratch, &blobData); - if (!maybeKind) { - // FIXME this drops the error on the floor. - consumeError(maybeKind.takeError()); - return false; - } - unsigned kind = maybeKind.get(); - - switch (kind) { - case comment_block::DECL_COMMENTS: - DeclCommentTable = readDeclCommentTable(scratch, blobData); - break; - case comment_block::GROUP_NAMES: - GroupNamesMap = readGroupTable(scratch, blobData); - break; - default: - // Unknown index kind, which this version of the compiler won't use. - break; - } - break; - } - } - - return false; -} - -static Optional getActualLibraryKind(unsigned rawKind) { - auto stableKind = static_cast(rawKind); - if (stableKind != rawKind) - return None; - - switch (stableKind) { - case serialization::LibraryKind::Library: - return swift::LibraryKind::Library; - case serialization::LibraryKind::Framework: - return swift::LibraryKind::Framework; - } - - // If there's a new case value in the module file, ignore it. - return None; -} - -static Optional -getActualImportControl(unsigned rawValue) { - // We switch on the raw value rather than the enum in order to handle future - // values. - switch (rawValue) { - case static_cast(serialization::ImportControl::Normal): - return ModuleDecl::ImportFilterKind::Private; - case static_cast(serialization::ImportControl::Exported): - return ModuleDecl::ImportFilterKind::Public; - case static_cast(serialization::ImportControl::ImplementationOnly): - return ModuleDecl::ImportFilterKind::ImplementationOnly; - default: - return None; - } -} - static bool areCompatibleArchitectures(const llvm::Triple &moduleTarget, const llvm::Triple &ctxTarget) { if (moduleTarget.getArch() == ctxTarget.getArch()) @@ -1374,610 +90,32 @@ static bool isTargetTooNew(const llvm::Triple &moduleTarget, return ctxTarget.isOSVersionLT(major, minor, micro); } -bool ModuleFile::readModuleDocIfPresent() { - if (!this->ModuleDocInputBuffer) - return true; - - llvm::BitstreamCursor docCursor{ModuleDocInputBuffer->getMemBufferRef()}; - if (!checkModuleSignature(docCursor, SWIFTDOC_SIGNATURE) || - !enterTopLevelModuleBlock(docCursor, MODULE_DOC_BLOCK_ID)) { - return false; - } - - SmallVector scratch; - llvm::BitstreamEntry topLevelEntry; - - bool hasValidControlBlock = false; - ValidationInfo info; - - while (!docCursor.AtEndOfStream()) { - Expected maybeEntry = - docCursor.advance(AF_DontPopBlockAtEnd); - if (!maybeEntry) { - // FIXME this drops the error on the floor. - consumeError(maybeEntry.takeError()); - return false; - } - topLevelEntry = maybeEntry.get(); - if (topLevelEntry.Kind != llvm::BitstreamEntry::SubBlock) - break; - - switch (topLevelEntry.ID) { - case CONTROL_BLOCK_ID: { - if (llvm::Error Err = docCursor.EnterSubBlock(CONTROL_BLOCK_ID)) { - // FIXME this drops the error on the floor. - consumeError(std::move(Err)); - return false; - } - - info = validateControlBlock(docCursor, scratch, - {SWIFTDOC_VERSION_MAJOR, - SWIFTDOC_VERSION_MINOR}, - /*extendedInfo*/nullptr); - if (info.status != Status::Valid) - return false; - // Check that the swiftdoc is actually for this module. - if (info.name != Name) - return false; - hasValidControlBlock = true; - break; - } - - case COMMENT_BLOCK_ID: { - if (!hasValidControlBlock || !readCommentBlock(docCursor)) - return false; - break; - } - - default: - // Unknown top-level block, possibly for use by a future version of the - // module format. - if (docCursor.SkipBlock()) - return false; - break; - } - } - - if (topLevelEntry.Kind != llvm::BitstreamEntry::EndBlock) - return false; - - return true; -} - -class ModuleFile::DeclUSRTableInfo { -public: - using internal_key_type = StringRef; - using external_key_type = StringRef; - using data_type = uint32_t; - using hash_value_type = uint32_t; - using offset_type = unsigned; - - internal_key_type GetInternalKey(external_key_type key) { return key; } - - hash_value_type ComputeHash(internal_key_type key) { - assert(!key.empty()); - return llvm::djbHash(key, SWIFTSOURCEINFO_HASH_SEED); - } - - static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { - return lhs == rhs; - } - - static std::pair ReadKeyDataLength(const uint8_t *&data) { - unsigned keyLength = endian::readNext(data); - unsigned dataLength = 4; - return { keyLength, dataLength }; - } - - static internal_key_type ReadKey(const uint8_t *data, unsigned length) { - return StringRef(reinterpret_cast(data), length); - } - - data_type ReadData(internal_key_type key, const uint8_t *data, unsigned length) { - assert(length == 4); - return endian::readNext(data); - } -}; - -std::unique_ptr -ModuleFile::readDeclUSRsTable(ArrayRef fields, StringRef blobData) { - if (fields.empty() || blobData.empty()) - return nullptr; - uint32_t tableOffset = static_cast(fields.front()); - auto base = reinterpret_cast(blobData.data()); - return std::unique_ptr( - SerializedDeclUSRTable::Create(base + tableOffset, base + sizeof(uint32_t), - base)); -} - -bool ModuleFile::readDeclLocsBlock(llvm::BitstreamCursor &cursor) { - if (llvm::Error Err = cursor.EnterSubBlock(CONTROL_BLOCK_ID)) { - consumeError(std::move(Err)); - return false; - } - - SmallVector scratch; - StringRef blobData; - - while (!cursor.AtEndOfStream()) { - Expected entry = cursor.advance(); - if (!entry) { - consumeError(entry.takeError()); - return false; - } - switch (entry->Kind) { - case llvm::BitstreamEntry::EndBlock: - return true; - - case llvm::BitstreamEntry::Error: - return false; - - case llvm::BitstreamEntry::SubBlock: - // Unknown sub-block, which this version of the compiler won't use. - if (cursor.SkipBlock()) - return false; - break; - - case llvm::BitstreamEntry::Record: - scratch.clear(); - Expected kind = - cursor.readRecord(entry->ID, scratch, &blobData); - if (!kind) { - consumeError(kind.takeError()); - return false; - } - switch (*kind) { - case decl_locs_block::BASIC_DECL_LOCS: - BasicDeclLocsData = blobData; - break; - case decl_locs_block::TEXT_DATA: - SourceLocsTextData = blobData; - break; - case decl_locs_block::DECL_USRS: - DeclUSRsTable = readDeclUSRsTable(scratch, blobData); - break; - case decl_locs_block::DOC_RANGES: - DocRangesData = blobData; - break; - default: - // Unknown index kind, which this version of the compiler won't use. - break; - } - break; - } - } - - return false; -} - -bool ModuleFile::readModuleSourceInfoIfPresent() { - if (!this->ModuleSourceInfoInputBuffer) - return true; - - llvm::BitstreamCursor infoCursor{ModuleSourceInfoInputBuffer->getMemBufferRef()}; - if (!checkModuleSignature(infoCursor, SWIFTSOURCEINFO_SIGNATURE) || - !enterTopLevelModuleBlock(infoCursor, MODULE_SOURCEINFO_BLOCK_ID)) { - return false; - } - - SmallVector scratch; - - bool hasValidControlBlock = false; - ValidationInfo info; - unsigned kind = llvm::BitstreamEntry::Error; - - while (!infoCursor.AtEndOfStream()) { - Expected topLevelEntry = - infoCursor.advance(AF_DontPopBlockAtEnd); - if (!topLevelEntry) { - consumeError(topLevelEntry.takeError()); - return false; - } - kind = topLevelEntry->Kind; - if (kind != llvm::BitstreamEntry::SubBlock) - break; - - switch (topLevelEntry->ID) { - case CONTROL_BLOCK_ID: { - if (llvm::Error Err = infoCursor.EnterSubBlock(CONTROL_BLOCK_ID)) { - consumeError(std::move(Err)); - return false; - } - info = validateControlBlock(infoCursor, scratch, - {SWIFTSOURCEINFO_VERSION_MAJOR, - SWIFTSOURCEINFO_VERSION_MINOR}, - /*extendedInfo*/nullptr); - if (info.status != Status::Valid) - return false; - // Check that the swiftsourceinfo is actually for this module. - if (info.name != Name) - return false; - hasValidControlBlock = true; - break; - } - - case DECL_LOCS_BLOCK_ID: { - if (!hasValidControlBlock || !readDeclLocsBlock(infoCursor)) - return false; - break; - } - - default: - // Unknown top-level block, possibly for use by a future version of the - // module format. - if (infoCursor.SkipBlock()) - return false; - break; - } - } - - if (kind != llvm::BitstreamEntry::EndBlock) - return false; - - return true; -} - -ModuleFile::ModuleFile( - std::unique_ptr moduleInputBuffer, - std::unique_ptr moduleDocInputBuffer, - std::unique_ptr moduleSourceInfoInputBuffer, - bool isFramework, serialization::ValidationInfo &info, - serialization::ExtendedValidationInfo *extInfo) - : ModuleInputBuffer(std::move(moduleInputBuffer)), - ModuleDocInputBuffer(std::move(moduleDocInputBuffer)), - ModuleSourceInfoInputBuffer(std::move(moduleSourceInfoInputBuffer)), +ModuleFile::ModuleFile(std::shared_ptr core) + : Core(core), DeserializedTypeCallback([](Type ty) {}) { - assert(!hasError()); - Bits.IsFramework = isFramework; - - PrettyStackTraceModuleFile stackEntry(*this); - - llvm::BitstreamCursor cursor{ModuleInputBuffer->getMemBufferRef()}; - - if (!checkModuleSignature(cursor, SWIFTMODULE_SIGNATURE) || - !enterTopLevelModuleBlock(cursor, MODULE_BLOCK_ID)) { - info.status = error(Status::Malformed); - return; - } - - // Future-proofing: make sure we validate the control block before we try to - // read any other blocks. - bool hasValidControlBlock = false; - SmallVector scratch; - - llvm::BitstreamEntry topLevelEntry; - - while (!cursor.AtEndOfStream()) { - Expected maybeEntry = - cursor.advance(AF_DontPopBlockAtEnd); - if (!maybeEntry) { - // FIXME this drops the error diagnostic on the floor. - consumeError(maybeEntry.takeError()); - info.status = error(Status::Malformed); - return; - } - topLevelEntry = maybeEntry.get(); - if (topLevelEntry.Kind != llvm::BitstreamEntry::SubBlock) - break; - - switch (topLevelEntry.ID) { - case CONTROL_BLOCK_ID: { - if (llvm::Error Err = cursor.EnterSubBlock(CONTROL_BLOCK_ID)) { - // FIXME this drops the error on the floor. - consumeError(std::move(Err)); - info.status = error(Status::Malformed); - return; - } - - info = validateControlBlock(cursor, scratch, - {SWIFTMODULE_VERSION_MAJOR, - SWIFTMODULE_VERSION_MINOR}, - extInfo); - if (info.status != Status::Valid) { - error(info.status); - return; - } - Name = info.name; - TargetTriple = info.targetTriple; - CompatibilityVersion = info.compatibilityVersion; - IsSIB = extInfo->isSIB(); - MiscVersion = info.miscVersion; - - hasValidControlBlock = true; - break; - } - - case INPUT_BLOCK_ID: { - if (!hasValidControlBlock) { - info.status = error(Status::Malformed); - return; - } - - if (llvm::Error Err = cursor.EnterSubBlock(INPUT_BLOCK_ID)) { - // FIXME this drops the error on the floor. - consumeError(std::move(Err)); - info.status = error(Status::Malformed); - return; - } - - Expected maybeNext = cursor.advance(); - if (!maybeNext) { - // FIXME this drops the error on the floor. - consumeError(maybeNext.takeError()); - info.status = error(Status::Malformed); - return; - } - llvm::BitstreamEntry next = maybeNext.get(); - while (next.Kind == llvm::BitstreamEntry::Record) { - scratch.clear(); - StringRef blobData; - Expected maybeKind = - cursor.readRecord(next.ID, scratch, &blobData); - if (!maybeKind) { - // FIXME this drops the error on the floor. - consumeError(maybeKind.takeError()); - info.status = error(Status::Malformed); - return; - } - unsigned kind = maybeKind.get(); - switch (kind) { - case input_block::IMPORTED_MODULE: { - unsigned rawImportControl; - bool scoped; - bool hasSPI; - input_block::ImportedModuleLayout::readRecord(scratch, - rawImportControl, - scoped, hasSPI); - auto importKind = getActualImportControl(rawImportControl); - if (!importKind) { - // We don't know how to import this dependency. - info.status = error(Status::Malformed); - return; - } - - StringRef spiBlob; - if (hasSPI) { - scratch.clear(); - - llvm::BitstreamEntry entry = - fatalIfUnexpected(cursor.advance(AF_DontPopBlockAtEnd)); - unsigned recordID = - fatalIfUnexpected(cursor.readRecord(entry.ID, scratch, &spiBlob)); - assert(recordID == input_block::IMPORTED_MODULE_SPIS); - input_block::ImportedModuleLayoutSPI::readRecord(scratch); - (void) recordID; - } else { - spiBlob = StringRef(); - } - - Dependencies.push_back({blobData, spiBlob, importKind.getValue(), scoped}); - break; - } - case input_block::LINK_LIBRARY: { - uint8_t rawKind; - bool shouldForceLink; - input_block::LinkLibraryLayout::readRecord(scratch, rawKind, - shouldForceLink); - if (auto libKind = getActualLibraryKind(rawKind)) - LinkLibraries.push_back({blobData, *libKind, shouldForceLink}); - // else ignore the dependency...it'll show up as a linker error. - break; - } - case input_block::IMPORTED_HEADER: { - assert(!importedHeaderInfo.fileSize && "only one header allowed"); - bool exported; - input_block::ImportedHeaderLayout::readRecord(scratch, - exported, importedHeaderInfo.fileSize, - importedHeaderInfo.fileModTime); - Dependencies.push_back(Dependency::forHeader(blobData, exported)); - break; - } - case input_block::IMPORTED_HEADER_CONTENTS: { - assert(Dependencies.back().isHeader() && "must follow header record"); - assert(importedHeaderInfo.contents.empty() && - "contents seen already"); - importedHeaderInfo.contents = blobData; - break; - } - case input_block::SEARCH_PATH: { - bool isFramework; - bool isSystem; - input_block::SearchPathLayout::readRecord(scratch, isFramework, - isSystem); - SearchPaths.push_back({blobData, isFramework, isSystem}); - break; - } - case input_block::MODULE_INTERFACE_PATH: { - ModuleInterfacePath = blobData; - break; - } - default: - // Unknown input kind, possibly for use by a future version of the - // module format. - // FIXME: Should we warn about this? - break; - } - - maybeNext = cursor.advance(); - if (!maybeNext) { - // FIXME this drops the error on the floor. - consumeError(maybeNext.takeError()); - info.status = error(Status::Malformed); - return; - } - next = maybeNext.get(); - } - - if (next.Kind != llvm::BitstreamEntry::EndBlock) - info.status = error(Status::Malformed); - - break; - } - - case DECLS_AND_TYPES_BLOCK_ID: { - if (!hasValidControlBlock) { - info.status = error(Status::Malformed); - return; - } - - // The decls-and-types block is lazily loaded. Save the cursor and load - // any abbrev records at the start of the block. - DeclTypeCursor = cursor; - if (llvm::Error Err = - DeclTypeCursor.EnterSubBlock(DECLS_AND_TYPES_BLOCK_ID)) { - // FIXME this drops the error on the floor. - consumeError(std::move(Err)); - info.status = error(Status::Malformed); - return; - } - - Expected maybeCursor = DeclTypeCursor.advance(); - if (!maybeCursor) { - // FIXME this drops the error on the floor. - consumeError(maybeCursor.takeError()); - info.status = error(Status::Malformed); - return; - } - if (maybeCursor.get().Kind == llvm::BitstreamEntry::Error) - info.status = error(Status::Malformed); - - // With the main cursor, skip over the block and continue. - if (cursor.SkipBlock()) { - info.status = error(Status::Malformed); - return; - } - break; - } - - case IDENTIFIER_DATA_BLOCK_ID: { - if (!hasValidControlBlock) { - info.status = error(Status::Malformed); - return; - } - - if (llvm::Error Err = cursor.EnterSubBlock(IDENTIFIER_DATA_BLOCK_ID)) { - // FIXME this drops the error on the floor. - consumeError(std::move(Err)); - info.status = error(Status::Malformed); - return; - } - - Expected maybeNext = - cursor.advanceSkippingSubblocks(); - if (!maybeNext) { - // FIXME this drops the error on the floor. - consumeError(maybeNext.takeError()); - info.status = error(Status::Malformed); - return; - } - llvm::BitstreamEntry next = maybeNext.get(); - while (next.Kind == llvm::BitstreamEntry::Record) { - scratch.clear(); - StringRef blobData; - Expected maybeKind = - cursor.readRecord(next.ID, scratch, &blobData); - if (!maybeKind) { - // FIXME this drops the error on the floor. - consumeError(maybeKind.takeError()); - info.status = error(Status::Malformed); - return; - } - unsigned kind = maybeKind.get(); - - switch (kind) { - case identifier_block::IDENTIFIER_DATA: - assert(scratch.empty()); - IdentifierData = blobData; - break; - default: - // Unknown identifier data, which this version of the compiler won't - // use. - break; - } - - maybeNext = cursor.advanceSkippingSubblocks(); - if (!maybeNext) { - // FIXME this drops the error on the floor. - consumeError(maybeNext.takeError()); - info.status = error(Status::Malformed); - return; - } - next = maybeNext.get(); - } - - if (next.Kind != llvm::BitstreamEntry::EndBlock) { - info.status = error(Status::Malformed); - return; - } + assert(!core->hasError()); - break; - } - - case INDEX_BLOCK_ID: { - if (!hasValidControlBlock || !readIndexBlock(cursor)) { - info.status = error(Status::Malformed); - return; - } - break; - } + DeclTypeCursor = core->DeclTypeCursor; + SILCursor = core->SILCursor; + SILIndexCursor = core->SILIndexCursor; + DeclMemberTablesCursor = core->DeclMemberTablesCursor; - case SIL_INDEX_BLOCK_ID: { - // Save the cursor. - SILIndexCursor = cursor; - if (llvm::Error Err = SILIndexCursor.EnterSubBlock(SIL_INDEX_BLOCK_ID)) { - // FIXME this drops the error on the floor. - consumeError(std::move(Err)); - info.status = error(Status::Malformed); - return; - } - - // With the main cursor, skip over the block and continue. - if (cursor.SkipBlock()) { - info.status = error(Status::Malformed); - return; - } - break; - } - - case SIL_BLOCK_ID: { - // Save the cursor. - SILCursor = cursor; - if (llvm::Error Err = SILCursor.EnterSubBlock(SIL_BLOCK_ID)) { - // FIXME this drops the error on the floor. - consumeError(std::move(Err)); - info.status = error(Status::Malformed); - return; - } - - // With the main cursor, skip over the block and continue. - if (cursor.SkipBlock()) { - info.status = error(Status::Malformed); - return; - } - break; - } - - default: - // Unknown top-level block, possibly for use by a future version of the - // module format. - if (cursor.SkipBlock()) { - info.status = error(Status::Malformed); - return; - } - break; - } + for (const auto &coreDep : core->Dependencies) { + Dependencies.emplace_back(coreDep); } - if (topLevelEntry.Kind != llvm::BitstreamEntry::EndBlock) { - info.status = error(Status::Malformed); - return; - } - // Read source info file. - readModuleSourceInfoIfPresent(); - if (!readModuleDocIfPresent()) { - info.status = error(Status::MalformedDocumentation); - return; - } + // `ModuleFileSharedCore` has immutable data, we copy these into `ModuleFile` + // so we can mutate the arrays and replace the offsets with AST object + // pointers as we lazily deserialize them. + allocateBuffer(Decls, core->Decls); + allocateBuffer(LocalDeclContexts, core->LocalDeclContexts); + allocateBuffer(NormalConformances, core->NormalConformances); + allocateBuffer(SILLayouts, core->SILLayouts); + allocateBuffer(Types, core->Types); + allocateBuffer(ClangTypes, core->ClangTypes); + allocateBuffer(GenericSignatures, core->GenericSignatures); + allocateBuffer(SubstitutionMaps, core->SubstitutionMaps); + allocateBuffer(Identifiers, core->Identifiers); } Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc) { @@ -1988,12 +126,12 @@ Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc) { FileContext = file; ModuleDecl *M = file->getParentModule(); - if (M->getName().str() != Name) + if (M->getName().str() != Core->Name) return error(Status::NameMismatch); ASTContext &ctx = getContext(); - llvm::Triple moduleTarget(llvm::Triple::normalize(TargetTriple)); + llvm::Triple moduleTarget(llvm::Triple::normalize(Core->TargetTriple)); if (!areCompatibleArchitectures(moduleTarget, ctx.LangOpts.Target) || !areCompatibleOSs(moduleTarget, ctx.LangOpts.Target)) { return error(Status::TargetIncompatible); @@ -2004,7 +142,7 @@ Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc) { return error(Status::TargetTooNew); } - for (const auto &searchPath : SearchPaths) + for (const auto &searchPath : Core->SearchPaths) ctx.addSearchPath(searchPath.Path, searchPath.IsFramework, searchPath.IsSystem); @@ -2017,13 +155,13 @@ Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc) { if (dependency.isHeader()) { // The path may be empty if the file being loaded is a partial AST, // and the current compiler invocation is a merge-modules step. - if (!dependency.RawPath.empty()) { + if (!dependency.Core.RawPath.empty()) { bool hadError = - clangImporter->importHeader(dependency.RawPath, + clangImporter->importHeader(dependency.Core.RawPath, file->getParentModule(), - importedHeaderInfo.fileSize, - importedHeaderInfo.fileModTime, - importedHeaderInfo.contents, + Core->importedHeaderInfo.fileSize, + Core->importedHeaderInfo.fileModTime, + Core->importedHeaderInfo.contents, diagLoc); if (hadError) return error(Status::FailedToLoadBridgingHeader); @@ -2049,7 +187,7 @@ Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc) { continue; } - StringRef modulePathStr = dependency.RawPath; + StringRef modulePathStr = dependency.Core.RawPath; StringRef scopePath; if (dependency.isScoped()) { auto splitPoint = modulePathStr.find_last_of('\0'); @@ -2094,7 +232,7 @@ Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc) { } // SPI - StringRef spisStr = dependency.RawSPIs; + StringRef spisStr = dependency.Core.RawSPIs; while (!spisStr.empty()) { StringRef nextComponent; std::tie(nextComponent, spisStr) = spisStr.split('\0'); @@ -2113,7 +251,7 @@ Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc) { return error(Status::MissingDependency); } - if (Bits.HasEntryPoint) { + if (Core->Bits.HasEntryPoint) { FileContext->getParentModule()->registerEntryPointFile(FileContext, SourceLoc(), None); @@ -2122,15 +260,13 @@ Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc) { return Status::Valid; } -std::unique_ptr ModuleFile::takeBufferForDiagnostics() { - assert(hasError()); +bool ModuleFile::mayHaveDiagnosticsPointingAtBuffer() const { + if (!hasError()) + return false; // Today, the only buffer that might have diagnostics in them is the input // buffer, and even then only if it has imported module contents. - if (!importedHeaderInfo.contents.empty()) - return std::move(ModuleInputBuffer); - - return nullptr; + return !Core->importedHeaderInfo.contents.empty(); } ModuleFile::~ModuleFile() { } @@ -2139,13 +275,13 @@ void ModuleFile::lookupValue(DeclName name, SmallVectorImpl &results) { PrettyStackTraceModuleFile stackEntry(*this); - if (TopLevelDecls) { + if (Core->TopLevelDecls) { // Find top-level declarations with the given name. // FIXME: As a bit of a hack, do lookup by the simple name, then filter // compound decls, to avoid having to completely redo how modules are // serialized. - auto iter = TopLevelDecls->find(name.getBaseName()); - if (iter != TopLevelDecls->end()) { + auto iter = Core->TopLevelDecls->find(name.getBaseName()); + if (iter != Core->TopLevelDecls->end()) { for (auto item : *iter) { Expected declOrError = getDeclChecked(item.second); if (!declOrError) { @@ -2162,9 +298,9 @@ void ModuleFile::lookupValue(DeclName name, } // If the name is an operator name, also look for operator methods. - if (name.isOperator() && OperatorMethodDecls) { - auto iter = OperatorMethodDecls->find(name.getBaseName()); - if (iter != OperatorMethodDecls->end()) { + if (name.isOperator() && Core->OperatorMethodDecls) { + auto iter = Core->OperatorMethodDecls->find(name.getBaseName()); + if (iter != Core->OperatorMethodDecls->end()) { for (auto item : *iter) { Expected declOrError = getDeclChecked(item.second); if (!declOrError) { @@ -2183,11 +319,11 @@ void ModuleFile::lookupValue(DeclName name, TypeDecl *ModuleFile::lookupLocalType(StringRef MangledName) { PrettyStackTraceModuleFile stackEntry(*this); - if (!LocalTypeDecls) + if (!Core->LocalTypeDecls) return nullptr; - auto iter = LocalTypeDecls->find(MangledName); - if (iter == LocalTypeDecls->end()) + auto iter = Core->LocalTypeDecls->find(MangledName); + if (iter == Core->LocalTypeDecls->end()) return nullptr; return cast(getDecl(*iter)); @@ -2202,29 +338,39 @@ ModuleFile::getModuleName(ASTContext &Ctx, StringRef modulePath, if (!moduleBuf) return nullptr; + // FIXME: This goes through the full cost of creating a ModuleFile object + // and then it keeps just the name and discards the whole object. + // The user of this API is `ExplicitSwiftModuleLoader`, this API should + // change to return a `ModuleFileSharedCore` object that + // `ExplicitSwiftModuleLoader` caches. + // Load the module file without validation. - std::unique_ptr loadedModuleFile; + std::unique_ptr newBuf = + llvm::MemoryBuffer::getMemBuffer(llvm::MemoryBufferRef(*moduleBuf.get()), + /*RequiresNullTerminator=*/false); + std::shared_ptr loadedModuleFile; ExtendedValidationInfo ExtInfo; bool isFramework = false; serialization::ValidationInfo loadInfo = - ModuleFile::load(modulePath.str(), - std::move(moduleBuf.get()), + ModuleFileSharedCore::load(modulePath.str(), + std::move(newBuf), nullptr, nullptr, /*isFramework*/isFramework, loadedModuleFile, &ExtInfo); + Name = loadedModuleFile->Name; - return std::move(loadedModuleFile->ModuleInputBuffer); + return std::move(moduleBuf.get()); } OpaqueTypeDecl *ModuleFile::lookupOpaqueResultType(StringRef MangledName) { PrettyStackTraceModuleFile stackEntry(*this); - if (!OpaqueReturnTypeDecls) + if (!Core->OpaqueReturnTypeDecls) return nullptr; - auto iter = OpaqueReturnTypeDecls->find(MangledName); - if (iter == OpaqueReturnTypeDecls->end()) + auto iter = Core->OpaqueReturnTypeDecls->find(MangledName); + if (iter == Core->OpaqueReturnTypeDecls->end()) return nullptr; return cast(getDecl(*iter)); @@ -2234,9 +380,9 @@ TypeDecl *ModuleFile::lookupNestedType(Identifier name, const NominalTypeDecl *parent) { PrettyStackTraceModuleFile stackEntry(*this); - if (NestedTypeDecls) { - auto iter = NestedTypeDecls->find(name); - if (iter != NestedTypeDecls->end()) { + if (Core->NestedTypeDecls) { + auto iter = Core->NestedTypeDecls->find(name); + if (iter != Core->NestedTypeDecls->end()) { for (std::pair entry : *iter) { assert(entry.first); auto declOrOffset = Decls[entry.first - 1]; @@ -2265,11 +411,11 @@ OperatorDecl *ModuleFile::lookupOperator(Identifier name, OperatorFixity fixity) { PrettyStackTraceModuleFile stackEntry(*this); - if (!OperatorDecls) + if (!Core->OperatorDecls) return nullptr; - auto iter = OperatorDecls->find(name); - if (iter == OperatorDecls->end()) + auto iter = Core->OperatorDecls->find(name); + if (iter == Core->OperatorDecls->end()) return nullptr; for (auto item : *iter) { @@ -2282,11 +428,11 @@ OperatorDecl *ModuleFile::lookupOperator(Identifier name, PrecedenceGroupDecl *ModuleFile::lookupPrecedenceGroup(Identifier name) { PrettyStackTraceModuleFile stackEntry(*this); - if (!PrecedenceGroupDecls) + if (!Core->PrecedenceGroupDecls) return nullptr; - auto iter = PrecedenceGroupDecls->find(name); - if (iter == PrecedenceGroupDecls->end()) + auto iter = Core->PrecedenceGroupDecls->find(name); + if (iter == Core->PrecedenceGroupDecls->end()) return nullptr; auto data = *iter; @@ -2332,7 +478,7 @@ void ModuleFile::getImportDecls(SmallVectorImpl &Results) { if (Dep.isHeader()) continue; - StringRef ModulePathStr = Dep.RawPath; + StringRef ModulePathStr = Dep.Core.RawPath; StringRef ScopePath; if (Dep.isScoped()) std::tie(ModulePathStr, ScopePath) = ModulePathStr.rsplit('\0'); @@ -2397,7 +543,7 @@ void ModuleFile::lookupVisibleDecls(ModuleDecl::AccessPathTy accessPath, PrettyStackTraceModuleFile stackEntry(*this); assert(accessPath.size() <= 1 && "can only refer to top-level decls"); - if (!TopLevelDecls) + if (!Core->TopLevelDecls) return; auto tryImport = [this, &consumer](DeclID ID) { @@ -2413,8 +559,8 @@ void ModuleFile::lookupVisibleDecls(ModuleDecl::AccessPathTy accessPath, }; if (!accessPath.empty()) { - auto iter = TopLevelDecls->find(accessPath.front().Item); - if (iter == TopLevelDecls->end()) + auto iter = Core->TopLevelDecls->find(accessPath.front().Item); + if (iter == Core->TopLevelDecls->end()) return; for (auto item : *iter) @@ -2423,7 +569,7 @@ void ModuleFile::lookupVisibleDecls(ModuleDecl::AccessPathTy accessPath, return; } - for (auto entry : TopLevelDecls->data()) { + for (auto entry : Core->TopLevelDecls->data()) { for (auto item : entry) tryImport(item.second); } @@ -2431,11 +577,11 @@ void ModuleFile::lookupVisibleDecls(ModuleDecl::AccessPathTy accessPath, void ModuleFile::loadExtensions(NominalTypeDecl *nominal) { PrettyStackTraceModuleFile stackEntry(*this); - if (!ExtensionDecls) + if (!Core->ExtensionDecls) return; - auto iter = ExtensionDecls->find(nominal->getName()); - if (iter == ExtensionDecls->end()) + auto iter = Core->ExtensionDecls->find(nominal->getName()); + if (iter == Core->ExtensionDecls->end()) return; if (nominal->getEffectiveAccess() < AccessLevel::Internal) { @@ -2479,12 +625,12 @@ void ModuleFile::loadObjCMethods( bool isInstanceMethod, llvm::TinyPtrVector &methods) { // If we don't have an Objective-C method table, there's nothing to do. - if (!ObjCMethods) + if (!Core->ObjCMethods) return; // Look for all methods in the module file with this selector. - auto known = ObjCMethods->find(selector); - if (known == ObjCMethods->end()) { + auto known = Core->ObjCMethods->find(selector); + if (known == Core->ObjCMethods->end()) { return; } @@ -2510,13 +656,13 @@ void ModuleFile::loadObjCMethods( void ModuleFile::loadDerivativeFunctionConfigurations( AbstractFunctionDecl *originalAFD, llvm::SetVector &results) { - if (!DerivativeFunctionConfigurations) + if (!Core->DerivativeFunctionConfigurations) return; auto &ctx = originalAFD->getASTContext(); Mangle::ASTMangler Mangler; auto mangledName = Mangler.mangleDeclAsUSR(originalAFD, ""); - auto configs = DerivativeFunctionConfigurations->find(mangledName); - if (configs == DerivativeFunctionConfigurations->end()) + auto configs = Core->DerivativeFunctionConfigurations->find(mangledName); + if (configs == Core->DerivativeFunctionConfigurations->end()) return; for (auto entry : *configs) { auto *parameterIndices = IndexSubset::getFromString(ctx, entry.first); @@ -2541,11 +687,11 @@ ModuleFile::loadNamedMembers(const IterableDeclContext *IDC, DeclBaseName N, PrettyStackTraceDecl trace("loading members for", IDC->getDecl()); assert(IDC->wasDeserialized()); - assert(DeclMemberNames); + assert(Core->DeclMemberNames); TinyPtrVector results; - auto i = DeclMemberNames->find(N); - if (i == DeclMemberNames->end()) + auto i = Core->DeclMemberNames->find(N); + if (i == Core->DeclMemberNames->end()) return results; BitOffset subTableOffset = *i; @@ -2566,7 +712,7 @@ ModuleFile::loadNamedMembers(const IterableDeclContext *IDC, DeclBaseName N, DeclMemberTablesCursor.readRecord(entry.ID, scratch, &blobData)); assert(kind == decl_member_tables_block::DECL_MEMBERS); (void)kind; - subTable = readDeclMembersTable(scratch, blobData); + subTable = Core->readDeclMembersTable(scratch, blobData); } assert(subTable); @@ -2595,11 +741,11 @@ void ModuleFile::lookupClassMember(ModuleDecl::AccessPathTy accessPath, PrettyStackTraceModuleFile stackEntry(*this); assert(accessPath.size() <= 1 && "can only refer to top-level decls"); - if (!ClassMembersForDynamicLookup) + if (!Core->ClassMembersForDynamicLookup) return; - auto iter = ClassMembersForDynamicLookup->find(name.getBaseName()); - if (iter == ClassMembersForDynamicLookup->end()) + auto iter = Core->ClassMembersForDynamicLookup->find(name.getBaseName()); + if (iter == Core->ClassMembersForDynamicLookup->end()) return; if (!accessPath.empty()) { @@ -2644,11 +790,11 @@ void ModuleFile::lookupClassMembers(ModuleDecl::AccessPathTy accessPath, PrettyStackTraceModuleFile stackEntry(*this); assert(accessPath.size() <= 1 && "can only refer to top-level decls"); - if (!ClassMembersForDynamicLookup) + if (!Core->ClassMembersForDynamicLookup) return; if (!accessPath.empty()) { - for (const auto &list : ClassMembersForDynamicLookup->data()) { + for (const auto &list : Core->ClassMembersForDynamicLookup->data()) { for (auto item : list) { auto vd = cast(getDecl(item.second)); auto dc = vd->getDeclContext(); @@ -2663,7 +809,7 @@ void ModuleFile::lookupClassMembers(ModuleDecl::AccessPathTy accessPath, return; } - for (const auto &list : ClassMembersForDynamicLookup->data()) { + for (const auto &list : Core->ClassMembersForDynamicLookup->data()) { for (auto item : list) consumer.foundDecl(cast(getDecl(item.second)), DeclVisibilityKind::DynamicLookup, @@ -2675,11 +821,11 @@ void ModuleFile::lookupObjCMethods( ObjCSelector selector, SmallVectorImpl &results) { // If we don't have an Objective-C method table, there's nothing to do. - if (!ObjCMethods) return; + if (!Core->ObjCMethods) return; // Look for all methods in the module file with this selector. - auto known = ObjCMethods->find(selector); - if (known == ObjCMethods->end()) return; + auto known = Core->ObjCMethods->find(selector); + if (known == Core->ObjCMethods->end()) return; auto found = *known; for (const auto &result : found) { @@ -2704,17 +850,17 @@ void ModuleFile::lookupImportedSPIGroups( void ModuleFile::collectLinkLibraries(ModuleDecl::LinkLibraryCallback callback) const { - for (auto &lib : LinkLibraries) + for (const auto &lib : Core->LinkLibraries) callback(lib); - if (Bits.IsFramework) - callback(LinkLibrary(Name, LibraryKind::Framework)); + if (Core->Bits.IsFramework) + callback(LinkLibrary(Core->Name, LibraryKind::Framework)); } void ModuleFile::getTopLevelDecls( SmallVectorImpl &results, llvm::function_ref matchAttributes) { PrettyStackTraceModuleFile stackEntry(*this); - for (DeclID entry : OrderedTopLevelDecls) { + for (DeclID entry : Core->OrderedTopLevelDecls) { Expected declOrError = getDeclChecked(entry, matchAttributes); if (!declOrError) { if (declOrError.errorIsA()) { @@ -2735,10 +881,10 @@ void ModuleFile::getTopLevelDecls( void ModuleFile::getOperatorDecls(SmallVectorImpl &results) { PrettyStackTraceModuleFile stackEntry(*this); - if (!OperatorDecls) + if (!Core->OperatorDecls) return; - for (auto entry : OperatorDecls->data()) { + for (auto entry : Core->OperatorDecls->data()) { for (auto item : entry) results.push_back(cast(getDecl(item.second))); } @@ -2747,8 +893,8 @@ void ModuleFile::getOperatorDecls(SmallVectorImpl &results) { void ModuleFile::getPrecedenceGroups( SmallVectorImpl &results) { PrettyStackTraceModuleFile stackEntry(*this); - if (PrecedenceGroupDecls) { - for (auto entry : PrecedenceGroupDecls->data()) { + if (Core->PrecedenceGroupDecls) { + for (auto entry : Core->PrecedenceGroupDecls->data()) { for (auto item : entry) results.push_back(cast(getDecl(item.second))); } @@ -2758,10 +904,10 @@ void ModuleFile::getPrecedenceGroups( void ModuleFile::getLocalTypeDecls(SmallVectorImpl &results) { PrettyStackTraceModuleFile stackEntry(*this); - if (!LocalTypeDecls) + if (!Core->LocalTypeDecls) return; - for (auto DeclID : LocalTypeDecls->data()) { + for (auto DeclID : Core->LocalTypeDecls->data()) { auto TD = cast(getDecl(DeclID)); results.push_back(TD); } @@ -2771,10 +917,10 @@ void ModuleFile::getOpaqueReturnTypeDecls(SmallVectorImpl &results) { PrettyStackTraceModuleFile stackEntry(*this); - if (!OpaqueReturnTypeDecls) + if (!Core->OpaqueReturnTypeDecls) return; - for (auto DeclID : OpaqueReturnTypeDecls->data()) { + for (auto DeclID : Core->OpaqueReturnTypeDecls->data()) { auto TD = cast(getDecl(DeclID)); results.push_back(TD); } @@ -2799,7 +945,7 @@ Optional ModuleFile::getCommentForDecl(const Decl *D) const { assert(D->getDeclContext()->getModuleScopeContext() == FileContext && "Decl is from a different serialized file"); - if (!DeclCommentTable) + if (!Core->DeclCommentTable) return None; if (D->isImplicit()) return None; @@ -2822,10 +968,10 @@ ModuleFile::getBasicDeclLocsForDecl(const Decl *D) const { "cannot find comments for Clang decls in Swift modules"); assert(D->getDeclContext()->getModuleScopeContext() == FileContext && "Decl is from a different serialized file"); - if (!DeclUSRsTable) + if (!Core->DeclUSRsTable) return None; // Future compilers may not provide BasicDeclLocsData anymore. - if (BasicDeclLocsData.empty()) + if (Core->BasicDeclLocsData.empty()) return None; if (D->isImplicit()) return None; @@ -2835,8 +981,8 @@ ModuleFile::getBasicDeclLocsForDecl(const Decl *D) const { if (ide::printDeclUSR(D, OS)) return None; - auto It = DeclUSRsTable->find(OS.str()); - if (It == DeclUSRsTable->end()) + auto It = Core->DeclUSRsTable->find(OS.str()); + if (It == Core->DeclUSRsTable->end()) return None; auto UsrId = *It; uint32_t NumSize = 4; @@ -2848,23 +994,23 @@ ModuleFile::getBasicDeclLocsForDecl(const Decl *D) const { NumSize + // Offset into doc ranges blob NumSize * 2 * LineColumnCount; // Line/column of: Loc, StartLoc, EndLoc uint32_t RecordOffset = RecordSize * UsrId; - assert(RecordOffset < BasicDeclLocsData.size()); - assert(BasicDeclLocsData.size() % RecordSize == 0); + assert(RecordOffset < Core->BasicDeclLocsData.size()); + assert(Core->BasicDeclLocsData.size() % RecordSize == 0); BasicDeclLocs Result; - auto *Record = BasicDeclLocsData.data() + RecordOffset; + auto *Record = Core->BasicDeclLocsData.data() + RecordOffset; auto ReadNext = [&Record]() { return endian::readNext(Record); }; - auto FilePath = SourceLocsTextData.substr(ReadNext()); + auto FilePath = Core->SourceLocsTextData.substr(ReadNext()); size_t TerminatorOffset = FilePath.find('\0'); assert(TerminatorOffset != StringRef::npos && "unterminated string data"); Result.SourceFilePath = FilePath.slice(0, TerminatorOffset); const auto DocRangesOffset = ReadNext(); if (DocRangesOffset) { - assert(!DocRangesData.empty()); - const auto *Data = DocRangesData.data() + DocRangesOffset; + assert(!Core->DocRangesData.empty()); + const auto *Data = Core->DocRangesData.data() + DocRangesOffset; const auto NumLocs = endian::readNext(Data); assert(NumLocs); @@ -2890,9 +1036,13 @@ Result.X.Column = ReadNext(); const static StringRef Separator = "/"; Optional ModuleFile::getGroupNameById(unsigned Id) const { - if (!GroupNamesMap || GroupNamesMap->count(Id) == 0) + if (!Core->GroupNamesMap) + return None; + const auto &GroupNamesMap = *Core->GroupNamesMap; + auto it = GroupNamesMap.find(Id); + if (it == GroupNamesMap.end()) return None; - auto Original = (*GroupNamesMap)[Id]; + StringRef Original = it->second; if (Original.empty()) return None; auto SepPos = Original.find_last_of(Separator); @@ -2901,9 +1051,13 @@ Optional ModuleFile::getGroupNameById(unsigned Id) const { } Optional ModuleFile::getSourceFileNameById(unsigned Id) const { - if (!GroupNamesMap || GroupNamesMap->count(Id) == 0) + if (!Core->GroupNamesMap) return None; - auto Original = (*GroupNamesMap)[Id]; + const auto &GroupNamesMap = *Core->GroupNamesMap; + auto it = GroupNamesMap.find(Id); + if (it == GroupNamesMap.end()) + return None; + StringRef Original = it->second; if (Original.empty()) return None; auto SepPos = Original.find_last_of(Separator); @@ -2941,9 +1095,10 @@ ModuleFile::getSourceOrderForDecl(const Decl *D) const { } void ModuleFile::collectAllGroups(std::vector &Names) const { - if (!GroupNamesMap) + if (!Core->GroupNamesMap) return; - for (auto It = GroupNamesMap->begin(); It != GroupNamesMap->end(); ++ It) { + for (auto It = Core->GroupNamesMap->begin(); It != Core->GroupNamesMap->end(); + ++It) { StringRef FullGroupName = It->getSecond(); if (FullGroupName.empty()) continue; @@ -2959,14 +1114,27 @@ void ModuleFile::collectAllGroups(std::vector &Names) const { Optional ModuleFile::getCommentForDeclByUSR(StringRef USR) const { - if (!DeclCommentTable) + if (!Core->DeclCommentTable) return None; - auto I = DeclCommentTable->find(USR); - if (I == DeclCommentTable->end()) + // Use the comment cache to preserve the memory that the array of + // `SingleRawComment`s, inside `CommentInfo`, points to, and generally avoid + // allocating memory every time we query `Core->DeclCommentTable`. + auto it = CommentsCache.find(USR); + if (it != CommentsCache.end()) { + const auto &cachePtr = it->second; + if (!cachePtr) + return None; + return cachePtr->Info; + } + + auto I = Core->DeclCommentTable->find(USR); + if (I == Core->DeclCommentTable->end()) return None; - return *I; + auto &cachePtr = CommentsCache[USR]; + cachePtr = *I; + return cachePtr->Info; } Optional @@ -2993,7 +1161,7 @@ void ModuleFile::verify() const { } bool SerializedASTFile::hasEntryPoint() const { - return File.Bits.HasEntryPoint; + return File.hasEntryPoint(); } bool SerializedASTFile::getAllGenericSignatures( @@ -3009,11 +1177,11 @@ bool SerializedASTFile::getAllGenericSignatures( Decl *SerializedASTFile::getMainDecl() const { assert(hasEntryPoint()); - return File.getDecl(File.Bits.EntryPointDeclID); + return File.getDecl(File.getEntryPointDeclID()); } const version::Version &SerializedASTFile::getLanguageVersionBuiltWith() const { - return File.CompatibilityVersion; + return File.getCompatibilityVersion(); } StringRef SerializedASTFile::getModuleDefiningPath() const { diff --git a/lib/Serialization/ModuleFile.h b/lib/Serialization/ModuleFile.h index bd2f2fef92a4e..8a0c296a17a0c 100644 --- a/lib/Serialization/ModuleFile.h +++ b/lib/Serialization/ModuleFile.h @@ -14,6 +14,7 @@ #define SWIFT_SERIALIZATION_MODULEFILE_H #include "ModuleFormat.h" +#include "ModuleFileSharedCore.h" #include "swift/AST/Identifier.h" #include "swift/AST/LazyResolver.h" #include "swift/AST/LinkLibrary.h" @@ -57,17 +58,16 @@ class ModuleFile using Status = serialization::Status; using TypeID = serialization::TypeID; + /// The core data of a serialized module file. This is accessed as immutable + /// and thread-safe. + const std::shared_ptr Core; + /// A reference back to the AST representation of the file. FileUnit *FileContext = nullptr; /// The module that this module is an overlay of, if any. ModuleDecl *UnderlyingModule = nullptr; - /// The module file data. - std::unique_ptr ModuleInputBuffer; - std::unique_ptr ModuleDocInputBuffer; - std::unique_ptr ModuleSourceInfoInputBuffer; - /// The cursor used to lazily load things from the file. llvm::BitstreamCursor DeclTypeCursor; @@ -75,36 +75,11 @@ class ModuleFile llvm::BitstreamCursor SILIndexCursor; llvm::BitstreamCursor DeclMemberTablesCursor; - /// The name of the module. - StringRef Name; friend StringRef getNameOfModule(const ModuleFile *); - /// The target the module was built for. - StringRef TargetTriple; - - /// The name of the module interface this module was compiled from. - /// - /// Empty if this module didn't come from an interface file. - StringRef ModuleInterfacePath; - - /// The Swift compatibility version in use when this module was built. - version::Version CompatibilityVersion; - - /// The data blob containing all of the module's identifiers. - StringRef IdentifierData; - /// A callback to be invoked every time a type was deserialized. std::function DeserializedTypeCallback; - /// Is this module file actually a .sib file? .sib files are serialized SIL at - /// arbitrary granularity and arbitrary stage; unlike serialized Swift - /// modules, which are assumed to contain canonical SIL for an entire module. - bool IsSIB = false; - - // Full blob from the misc. version field of the metadata block. This should - // include the version string of the compiler that built the module. - StringRef MiscVersion; - public: static std::unique_ptr getModuleName(ASTContext &Ctx, StringRef modulePath, @@ -113,85 +88,33 @@ class ModuleFile /// Represents another module that has been imported as a dependency. class Dependency { public: + const ModuleFileSharedCore::Dependency &Core; + llvm::Optional Import = llvm::None; - const StringRef RawPath; - const StringRef RawSPIs; SmallVector spiGroups; - private: - using ImportFilterKind = ModuleDecl::ImportFilterKind; - const unsigned RawImportControl : 2; - const unsigned IsHeader : 1; - const unsigned IsScoped : 1; - - static unsigned rawControlFromKind(ImportFilterKind importKind) { - return llvm::countTrailingZeros(static_cast(importKind)); - } - ImportFilterKind getImportControl() const { - return static_cast(1 << RawImportControl); - } - - Dependency(StringRef path, StringRef spiGroups, bool isHeader, ImportFilterKind importControl, - bool isScoped) - : RawPath(path), RawSPIs(spiGroups), RawImportControl(rawControlFromKind(importControl)), - IsHeader(isHeader), IsScoped(isScoped) { - assert(llvm::countPopulation(static_cast(importControl)) == 1 && - "must be a particular filter option, not a bitset"); - assert(getImportControl() == importControl && "not enough bits"); - } - - public: - Dependency(StringRef path, StringRef spiGroups, ImportFilterKind importControl, bool isScoped) - : Dependency(path, spiGroups, false, importControl, isScoped) {} - - static Dependency forHeader(StringRef headerPath, bool exported) { - auto importControl = exported ? ImportFilterKind::Public - : ImportFilterKind::Private; - return Dependency(headerPath, StringRef(), true, importControl, false); - } + Dependency(const ModuleFileSharedCore::Dependency &coreDependency) + : Core(coreDependency) {} bool isLoaded() const { return Import.hasValue() && Import->importedModule != nullptr; } bool isExported() const { - return getImportControl() == ImportFilterKind::Public; + return Core.isExported(); } bool isImplementationOnly() const { - return getImportControl() == ImportFilterKind::ImplementationOnly; + return Core.isImplementationOnly(); } - bool isHeader() const { return IsHeader; } - bool isScoped() const { return IsScoped; } - - std::string getPrettyPrintedPath() const; + bool isHeader() const { return Core.isHeader(); } + bool isScoped() const { return Core.isScoped(); } }; private: /// All modules this module depends on. SmallVector Dependencies; - struct SearchPath { - StringRef Path; - bool IsFramework; - bool IsSystem; - }; - /// Search paths this module may provide. - /// - /// This is not intended for use by frameworks, but may show up in debug - /// modules. - std::vector SearchPaths; - - /// Info for the (lone) imported header for this module. - struct { - off_t fileSize; - time_t fileModTime; - StringRef contents; - } importedHeaderInfo = {}; - - /// All of this module's link-time dependencies. - SmallVector LinkLibraries; - public: template class Serialized { @@ -357,103 +280,23 @@ class ModuleFile /// Identifiers referenced by this module. MutableArrayRef Identifiers; - class DeclTableInfo; - using SerializedDeclTable = - llvm::OnDiskIterableChainedHashTable; - - class ExtensionTableInfo; - using SerializedExtensionTable = - llvm::OnDiskIterableChainedHashTable; - - class LocalDeclTableInfo; - using SerializedLocalDeclTable = - llvm::OnDiskIterableChainedHashTable; - - using OpaqueReturnTypeDeclTableInfo = LocalDeclTableInfo; - using SerializedOpaqueReturnTypeDeclTable = - llvm::OnDiskIterableChainedHashTable; - - class NestedTypeDeclsTableInfo; - using SerializedNestedTypeDeclsTable = - llvm::OnDiskIterableChainedHashTable; - - class DeclMemberNamesTableInfo; - using SerializedDeclMemberNamesTable = - llvm::OnDiskIterableChainedHashTable; - - class DeclMembersTableInfo; using SerializedDeclMembersTable = - llvm::OnDiskIterableChainedHashTable; - - std::unique_ptr TopLevelDecls; - std::unique_ptr OperatorDecls; - std::unique_ptr PrecedenceGroupDecls; - std::unique_ptr ClassMembersForDynamicLookup; - std::unique_ptr OperatorMethodDecls; - std::unique_ptr ExtensionDecls; - std::unique_ptr LocalTypeDecls; - std::unique_ptr OpaqueReturnTypeDecls; - std::unique_ptr NestedTypeDecls; - std::unique_ptr DeclMemberNames; + ModuleFileSharedCore::SerializedDeclMembersTable; llvm::DenseMap> DeclMembersTables; - class ObjCMethodTableInfo; - using SerializedObjCMethodTable = - llvm::OnDiskIterableChainedHashTable; - - std::unique_ptr ObjCMethods; - llvm::DenseMap PrivateDiscriminatorsByValue; llvm::DenseMap FilenamesForPrivateValues; TinyPtrVector ImportDecls; - ArrayRef OrderedTopLevelDecls; - - class DeclCommentTableInfo; - using SerializedDeclCommentTable = - llvm::OnDiskIterableChainedHashTable; - - using GroupNameTable = llvm::DenseMap; - - std::unique_ptr GroupNamesMap; - std::unique_ptr DeclCommentTable; - - class DeclUSRTableInfo; - using SerializedDeclUSRTable = - llvm::OnDiskIterableChainedHashTable; - std::unique_ptr DeclUSRsTable; - - class DerivativeFunctionConfigTableInfo; - using SerializedDerivativeFunctionConfigTable = - llvm::OnDiskIterableChainedHashTable; - std::unique_ptr - DerivativeFunctionConfigurations; - - /// A blob of 0 terminated string segments referenced in \c SourceLocsTextData - StringRef SourceLocsTextData; - - /// An array of fixed size source location data for each USR appearing in - /// \c DeclUSRsTable. - StringRef BasicDeclLocsData; - - /// An array of fixed-size location data for each `SingleRawComment` piece - /// of declaration's documentation `RawComment`s. - StringRef DocRangesData; + /// Maps USRs to their deserialized comment object. + mutable llvm::StringMap< + std::unique_ptr> + CommentsCache; struct ModuleBits { - /// The decl ID of the main class in this module file, if it has one. - unsigned EntryPointDeclID : 31; - - /// Whether or not this module file comes from a context that had a main - /// entry point. - unsigned HasEntryPoint : 1; - - /// Whether this module file comes from a framework. - unsigned IsFramework : 1; - /// Whether or not ImportDecls is valid. unsigned ComputedImportDecls : 1; @@ -466,26 +309,23 @@ class ModuleFile static_assert(sizeof(ModuleBits) <= 8, "The bit set should be small"); bool hasError() const { - return Bits.HasError; + return Bits.HasError || Core->hasError(); } - void setEntryPointClassID(serialization::DeclID DID) { - Bits.HasEntryPoint = true; - Bits.EntryPointDeclID = DID; - assert(Bits.EntryPointDeclID == DID && "not enough bits for DeclID"); + /// Whether or not this module file comes from a context that had a main entry point. + bool hasEntryPoint() const { + return Core->Bits.HasEntryPoint; + } + + /// The decl ID of the main class in this module file, if it has one. + unsigned getEntryPointDeclID() const { + return Core->Bits.EntryPointDeclID; } /// Creates a new AST node to represent a deserialized decl. template T *createDecl(Args &&... args); - /// Constructs a new module and validates it. - ModuleFile(std::unique_ptr moduleInputBuffer, - std::unique_ptr moduleDocInputBuffer, - std::unique_ptr moduleSourceInfoInputBuffer, - bool isFramework, serialization::ValidationInfo &info, - serialization::ExtendedValidationInfo *extInfo); - public: /// Change the status of the current module. Status error(Status issue) { @@ -530,85 +370,6 @@ class ModuleFile } private: - /// Read an on-disk decl hash table stored in index_block::DeclListLayout - /// format. - std::unique_ptr - readDeclTable(ArrayRef fields, StringRef blobData); - - /// Read an on-disk local decl hash table stored in - /// index_block::DeclListLayout format. - std::unique_ptr - readLocalDeclTable(ArrayRef fields, StringRef blobData); - - /// Read an on-disk Objective-C method table stored in - /// index_block::ObjCMethodTableLayout format. - std::unique_ptr - readObjCMethodTable(ArrayRef fields, StringRef blobData); - - /// Read an on-disk local decl hash table stored in - /// index_block::ExtensionTableLayout format. - std::unique_ptr - readExtensionTable(ArrayRef fields, StringRef blobData); - - /// Read an on-disk local decl hash table stored in - /// index_block::NestedTypeDeclsLayout format. - std::unique_ptr - readNestedTypeDeclsTable(ArrayRef fields, StringRef blobData); - - /// Read an on-disk local decl-name hash table stored in - /// index_block::DeclMemberNamesLayout format. - std::unique_ptr - readDeclMemberNamesTable(ArrayRef fields, StringRef blobData); - - /// Read an on-disk local decl-members hash table stored in - /// index_block::DeclMembersLayout format. - std::unique_ptr - readDeclMembersTable(ArrayRef fields, StringRef blobData); - - /// Read an on-disk derivative function configuration table stored in - /// index_block::DerivativeFunctionConfigTableLayout format. - std::unique_ptr - readDerivativeFunctionConfigTable(ArrayRef fields, - StringRef blobData); - - /// Reads the index block, which contains global tables. - /// - /// Returns false if there was an error. - bool readIndexBlock(llvm::BitstreamCursor &cursor); - - /// Read an on-disk decl hash table stored in - /// \c comment_block::DeclCommentListLayout format. - std::unique_ptr - readDeclCommentTable(ArrayRef fields, StringRef blobData); - - std::unique_ptr - readGroupTable(ArrayRef fields, StringRef blobData); - - /// Reads the comment block, which contains USR to comment mappings. - /// - /// Returns false if there was an error. - bool readCommentBlock(llvm::BitstreamCursor &cursor); - - /// Loads data from #ModuleDocInputBuffer. - /// - /// Returns false if there was an error. - bool readModuleDocIfPresent(); - - /// Reads the source loc block, which contains USR to decl location mapping. - /// - /// Returns false if there was an error. - bool readDeclLocsBlock(llvm::BitstreamCursor &cursor); - - /// Loads data from #ModuleSourceInfoInputBuffer. - /// - /// Returns false if there was an error. - bool readModuleSourceInfoIfPresent(); - - /// Read an on-disk decl hash table stored in - /// \c sourceinfo_block::DeclUSRSLayout format. - std::unique_ptr - readDeclUSRsTable(ArrayRef fields, StringRef blobData); - /// Recursively reads a pattern from \c DeclTypeCursor. llvm::Expected readPattern(DeclContext *owningDC); @@ -648,9 +409,6 @@ class ModuleFile llvm::Expected resolveCrossReference(serialization::ModuleID MID, uint32_t pathLen); - /// Populates TopLevelIDs for name lookup. - void buildTopLevelDeclMap(); - struct AccessorRecord { SmallVector IDs; }; @@ -664,40 +422,29 @@ class ModuleFile AccessorRecord &accessors); public: - /// Loads a module from the given memory buffer. - /// - /// \param moduleInputBuffer A memory buffer containing the serialized module - /// data. The created ModuleFile takes ownership of the buffer, even if - /// there's an error in loading. - /// \param moduleDocInputBuffer An optional memory buffer containing - /// documentation data for the module. The created ModuleFile takes ownership - /// of the buffer, even if there's an error in loading. - /// \param isFramework If true, this is treated as a framework module for - /// linking purposes. - /// \param[out] theModule The loaded module. - /// \param[out] extInfo Optionally, extra info serialized about the module. - /// \returns Whether the module was successfully loaded, or what went wrong - /// if it was not. - static serialization::ValidationInfo - load(StringRef moduleInterfacePath, - std::unique_ptr moduleInputBuffer, - std::unique_ptr moduleDocInputBuffer, - std::unique_ptr moduleSourceInfoInputBuffer, - bool isFramework, std::unique_ptr &theModule, - serialization::ExtendedValidationInfo *extInfo = nullptr) { - serialization::ValidationInfo info; - theModule.reset(new ModuleFile(std::move(moduleInputBuffer), - std::move(moduleDocInputBuffer), - std::move(moduleSourceInfoInputBuffer), - isFramework, info, extInfo)); - if (!moduleInterfacePath.empty()) - theModule->ModuleInterfacePath = moduleInterfacePath; - return info; - } + /// Constructs a new module. + explicit ModuleFile(std::shared_ptr core); // Out of line to avoid instantiation OnDiskChainedHashTable here. ~ModuleFile(); + /// The name of the module. + StringRef getName() const { + return Core->Name; + } + + /// The Swift compatibility version in use when this module was built. + const version::Version &getCompatibilityVersion() const { + return Core->CompatibilityVersion; + } + + /// Is this module file actually a .sib file? .sib files are serialized SIL at + /// arbitrary granularity and arbitrary stage; unlike serialized Swift + /// modules, which are assumed to contain canonical SIL for an entire module. + bool isSIB() const { + return Core->IsSIB; + } + /// Associates this module file with the AST node representing it. /// /// Checks that the file is compatible with the AST module it's being loaded @@ -715,13 +462,13 @@ class ModuleFile /// compiled for a different OS. Status associateWithFileContext(FileUnit *file, SourceLoc diagLoc); - /// Transfers ownership of a buffer that might contain source code where - /// other parts of the compiler could have emitted diagnostics, to keep them - /// alive even if the ModuleFile is destroyed. + /// Returns `true` if there is a buffer that might contain source code where + /// other parts of the compiler could have emitted diagnostics, to indicate + /// that the object must be kept alive as long as the diagnostics exist. /// /// Should only be called when a failure has been reported from /// ModuleFile::load or ModuleFile::associateWithFileContext. - std::unique_ptr takeBufferForDiagnostics(); + bool mayHaveDiagnosticsPointingAtBuffer() const; /// Returns the list of modules this module depends on. ArrayRef getDependencies() const { @@ -855,14 +602,14 @@ class ModuleFile void getDisplayDecls(SmallVectorImpl &results); StringRef getModuleFilename() const { - if (!ModuleInterfacePath.empty()) - return ModuleInterfacePath; + if (!Core->ModuleInterfacePath.empty()) + return Core->ModuleInterfacePath; // FIXME: This seems fragile, maybe store the filename separately ? - return ModuleInputBuffer->getBufferIdentifier(); + return Core->ModuleInputBuffer->getBufferIdentifier(); } StringRef getTargetTriple() const { - return TargetTriple; + return Core->TargetTriple; } /// AST-verify imported decls. diff --git a/lib/Serialization/ModuleFileCoreTableInfo.h b/lib/Serialization/ModuleFileCoreTableInfo.h new file mode 100644 index 0000000000000..3030d6a5f9770 --- /dev/null +++ b/lib/Serialization/ModuleFileCoreTableInfo.h @@ -0,0 +1,571 @@ +//===--- ModuleFileCoreTableInfo.h - Hash table info structures -*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_SERIALIZATION_MODULEFILECORETABLEINFO_H +#define SWIFT_SERIALIZATION_MODULEFILECORETABLEINFO_H + +#include "ModuleFileSharedCore.h" +#include "DocFormat.h" +#include "SourceInfoFormat.h" +#include "llvm/Support/DJB.h" + +namespace swift { + +/// Used to deserialize entries in the on-disk decl hash table. +class ModuleFileSharedCore::DeclTableInfo { +public: + using internal_key_type = std::pair; + using external_key_type = DeclBaseName; + using data_type = SmallVector, 8>; + using hash_value_type = uint32_t; + using offset_type = unsigned; + + internal_key_type GetInternalKey(external_key_type ID) { + if (ID.getKind() == DeclBaseName::Kind::Normal) { + return {DeclBaseName::Kind::Normal, ID.getIdentifier().str()}; + } else { + return {ID.getKind(), StringRef()}; + } + } + + hash_value_type ComputeHash(internal_key_type key) { + if (key.first == DeclBaseName::Kind::Normal) { + return llvm::djbHash(key.second, serialization::SWIFTMODULE_HASH_SEED); + } else { + return (hash_value_type)key.first; + } + } + + static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { + return lhs == rhs; + } + + static std::pair ReadKeyDataLength(const uint8_t *&data) { + using namespace llvm::support; + unsigned keyLength = endian::readNext(data); + unsigned dataLength = endian::readNext(data); + return { keyLength, dataLength }; + } + + static internal_key_type ReadKey(const uint8_t *data, unsigned length) { + using namespace swift::serialization; + using namespace llvm::support; + uint8_t kind = endian::readNext(data); + switch (kind) { + case static_cast(DeclNameKind::Normal): { + StringRef str(reinterpret_cast(data), + length - sizeof(uint8_t)); + return {DeclBaseName::Kind::Normal, str}; + } + case static_cast(DeclNameKind::Subscript): + return {DeclBaseName::Kind::Subscript, StringRef()}; + case static_cast(DeclNameKind::Destructor): + return {DeclBaseName::Kind::Destructor, StringRef()}; + default: + llvm_unreachable("Unknown DeclNameKind"); + } + } + + static data_type ReadData(internal_key_type key, const uint8_t *data, + unsigned length) { + using namespace llvm::support; + data_type result; + while (length > 0) { + uint8_t kind = *data++; + DeclID offset = endian::readNext(data); + result.push_back({ kind, offset }); + length -= 5; + } + + return result; + } +}; + +/// Used to deserialize entries in the on-disk decl hash table. +class ModuleFileSharedCore::ExtensionTableInfo { + const ModuleFileSharedCore &Core; +public: + using internal_key_type = StringRef; + using external_key_type = Identifier; + using data_type = SmallVector, 8>; + using hash_value_type = uint32_t; + using offset_type = unsigned; + + internal_key_type GetInternalKey(external_key_type ID) { + return ID.str(); + } + + hash_value_type ComputeHash(internal_key_type key) { + return llvm::djbHash(key, serialization::SWIFTMODULE_HASH_SEED); + } + + static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { + return lhs == rhs; + } + + static std::pair ReadKeyDataLength(const uint8_t *&data) { + using namespace llvm::support; + unsigned keyLength = endian::readNext(data); + unsigned dataLength = endian::readNext(data); + return { keyLength, dataLength }; + } + + static internal_key_type ReadKey(const uint8_t *data, unsigned length) { + return StringRef(reinterpret_cast(data), length); + } + + data_type ReadData(internal_key_type key, const uint8_t *data, + unsigned length) { + using namespace llvm::support; + data_type result; + const uint8_t *limit = data + length; + while (data < limit) { + DeclID offset = endian::readNext(data); + + int32_t nameIDOrLength = + endian::readNext(data); + StringRef moduleNameOrMangledBase; + if (nameIDOrLength < 0) { + StringRef moduleName = Core.getModuleNameFromID(-nameIDOrLength); + if (!moduleName.empty()) + moduleNameOrMangledBase = moduleName; + } else { + moduleNameOrMangledBase = + StringRef(reinterpret_cast(data), nameIDOrLength); + data += nameIDOrLength; + } + + result.push_back({ moduleNameOrMangledBase, offset }); + } + + return result; + } + + explicit ExtensionTableInfo(const ModuleFileSharedCore &core) : Core(core) {} +}; + +/// Used to deserialize entries in the on-disk decl hash table. +class ModuleFileSharedCore::LocalDeclTableInfo { +public: + using internal_key_type = StringRef; + using external_key_type = internal_key_type; + using data_type = DeclID; + using hash_value_type = uint32_t; + using offset_type = unsigned; + + internal_key_type GetInternalKey(external_key_type ID) { + return ID; + } + + external_key_type GetExternalKey(internal_key_type ID) { + return ID; + } + + hash_value_type ComputeHash(internal_key_type key) { + return llvm::djbHash(key, serialization::SWIFTMODULE_HASH_SEED); + } + + static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { + return lhs == rhs; + } + + static std::pair ReadKeyDataLength(const uint8_t *&data) { + using namespace llvm::support; + unsigned keyLength = endian::readNext(data); + return { keyLength, sizeof(uint32_t) }; + } + + static internal_key_type ReadKey(const uint8_t *data, unsigned length) { + return StringRef(reinterpret_cast(data), length); + } + + static data_type ReadData(internal_key_type key, const uint8_t *data, + unsigned length) { + using namespace llvm::support; + return endian::readNext(data); + } +}; + +class ModuleFileSharedCore::NestedTypeDeclsTableInfo { +public: + using internal_key_type = StringRef; + using external_key_type = Identifier; + using data_type = SmallVector, 4>; + using hash_value_type = uint32_t; + using offset_type = unsigned; + + internal_key_type GetInternalKey(external_key_type ID) { + return ID.str(); + } + + hash_value_type ComputeHash(internal_key_type key) { + return llvm::djbHash(key, serialization::SWIFTMODULE_HASH_SEED); + } + + static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { + return lhs == rhs; + } + + static std::pair ReadKeyDataLength(const uint8_t *&data) { + using namespace llvm::support; + unsigned keyLength = endian::readNext(data); + unsigned dataLength = endian::readNext(data); + return { keyLength, dataLength }; + } + + static internal_key_type ReadKey(const uint8_t *data, unsigned length) { + return StringRef(reinterpret_cast(data), length); + } + + static data_type ReadData(internal_key_type key, const uint8_t *data, + unsigned length) { + using namespace llvm::support; + data_type result; + while (length > 0) { + DeclID parentID = endian::readNext(data); + DeclID childID = endian::readNext(data); + result.push_back({ parentID, childID }); + length -= sizeof(uint32_t) * 2; + } + + return result; + } +}; + +// Indexing the members of all Decls (well, NominalTypeDecls anyway) is +// accomplished by a 2-level hashtable scheme. The outer table here maps from +// DeclBaseNames to serialization::BitOffsets of sub-tables. The sub-tables -- +// SerializedDeclMembersTables, one table per name -- map from the enclosing +// (NominalTypeDecl) DeclID to a vector of DeclIDs of members of the nominal +// with the name. See DeclMembersTableInfo below. +class ModuleFileSharedCore::DeclMemberNamesTableInfo { +public: + using internal_key_type = std::pair; + using external_key_type = DeclBaseName; + using data_type = serialization::BitOffset; + using hash_value_type = uint32_t; + using offset_type = unsigned; + + internal_key_type GetInternalKey(external_key_type ID) { + if (ID.getKind() == DeclBaseName::Kind::Normal) { + return {DeclBaseName::Kind::Normal, ID.getIdentifier().str()}; + } else { + return {ID.getKind(), StringRef()}; + } + } + + hash_value_type ComputeHash(internal_key_type key) { + if (key.first == DeclBaseName::Kind::Normal) { + return llvm::djbHash(key.second, serialization::SWIFTMODULE_HASH_SEED); + } else { + return (hash_value_type)key.first; + } + } + + static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { + return lhs == rhs; + } + + static std::pair ReadKeyDataLength(const uint8_t *&data) { + using namespace llvm::support; + unsigned keyLength = endian::readNext(data); + return { keyLength, sizeof(uint32_t) }; + } + + static internal_key_type ReadKey(const uint8_t *data, unsigned length) { + using namespace swift::serialization; + using namespace llvm::support; + uint8_t kind = endian::readNext(data); + switch (kind) { + case static_cast(DeclNameKind::Normal): { + StringRef str(reinterpret_cast(data), + length - sizeof(uint8_t)); + return {DeclBaseName::Kind::Normal, str}; + } + case static_cast(DeclNameKind::Subscript): + return {DeclBaseName::Kind::Subscript, StringRef()}; + case static_cast(DeclNameKind::Destructor): + return {DeclBaseName::Kind::Destructor, StringRef()}; + case static_cast(DeclNameKind::Constructor): + return {DeclBaseName::Kind::Constructor, StringRef()}; + default: + llvm_unreachable("Unknown DeclNameKind"); + } + } + + static data_type ReadData(internal_key_type key, const uint8_t *data, + unsigned length) { + using namespace llvm::support; + assert(length == sizeof(uint32_t)); + return endian::readNext(data); + } +}; + +// Second half of the 2-level member name lookup scheme, see +// DeclMemberNamesTableInfo above. There is one of these tables for each member +// DeclBaseName N in the module, and it maps from enclosing DeclIDs (say: each +// NominalTypeDecl T that has members named N) to the set of N-named members of +// T. In other words, there are no names in this table: the names are one level +// up, this table just maps { Owner-DeclID => [Member-DeclID, ...] }. +class ModuleFileSharedCore::DeclMembersTableInfo { +public: + using internal_key_type = uint32_t; + using external_key_type = DeclID; + using data_type = SmallVector; + using hash_value_type = uint32_t; + using offset_type = unsigned; + + internal_key_type GetInternalKey(external_key_type ID) { + return ID; + } + + hash_value_type ComputeHash(internal_key_type key) { + return llvm::hash_value(key); + } + + static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { + return lhs == rhs; + } + + static std::pair ReadKeyDataLength(const uint8_t *&data) { + using namespace llvm::support; + unsigned dataLength = endian::readNext(data); + return { sizeof(uint32_t), dataLength }; + } + + static internal_key_type ReadKey(const uint8_t *data, unsigned length) { + using namespace llvm::support; + return endian::readNext(data); + } + + static data_type ReadData(internal_key_type key, const uint8_t *data, + unsigned length) { + using namespace llvm::support; + data_type result; + while (length > 0) { + DeclID declID = endian::readNext(data); + result.push_back(declID); + length -= sizeof(uint32_t); + } + return result; + } +}; + +/// Used to deserialize entries in the on-disk Objective-C method table. +class ModuleFileSharedCore::ObjCMethodTableInfo { +public: + using internal_key_type = std::string; + using external_key_type = ObjCSelector; + using data_type = SmallVector, 8>; + using hash_value_type = uint32_t; + using offset_type = unsigned; + + internal_key_type GetInternalKey(external_key_type ID) { + llvm::SmallString<32> scratch; + return ID.getString(scratch).str(); + } + + hash_value_type ComputeHash(internal_key_type key) { + return llvm::djbHash(key, serialization::SWIFTMODULE_HASH_SEED); + } + + static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { + return lhs == rhs; + } + + static std::pair ReadKeyDataLength(const uint8_t *&data) { + using namespace llvm::support; + unsigned keyLength = endian::readNext(data); + unsigned dataLength = endian::readNext(data); + return { keyLength, dataLength }; + } + + static internal_key_type ReadKey(const uint8_t *data, unsigned length) { + return std::string(reinterpret_cast(data), length); + } + + static data_type ReadData(internal_key_type key, const uint8_t *data, + unsigned length) { + using namespace llvm::support; + const constexpr auto recordSize = sizeof(uint32_t) + 1 + sizeof(uint32_t); + data_type result; + while (length > 0) { + unsigned ownerLen = endian::readNext(data); + bool isInstanceMethod = *data++ != 0; + DeclID methodID = endian::readNext(data); + std::string ownerName((const char *)data, ownerLen); + result.push_back( + std::make_tuple(std::move(ownerName), isInstanceMethod, methodID)); + data += ownerLen; + length -= (recordSize + ownerLen); + } + + return result; + } +}; + +/// Used to deserialize entries in the on-disk derivative function configuration +/// table. +class ModuleFileSharedCore::DerivativeFunctionConfigTableInfo { +public: + using internal_key_type = StringRef; + using external_key_type = internal_key_type; + using data_type = + SmallVector, 8>; + using hash_value_type = uint32_t; + using offset_type = unsigned; + + external_key_type GetExternalKey(internal_key_type ID) { return ID; } + + internal_key_type GetInternalKey(external_key_type ID) { return ID; } + + hash_value_type ComputeHash(internal_key_type key) { + return llvm::djbHash(key, serialization::SWIFTMODULE_HASH_SEED); + } + + static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { + return lhs == rhs; + } + + static std::pair ReadKeyDataLength(const uint8_t *&data) { + using namespace llvm::support; + unsigned keyLength = endian::readNext(data); + unsigned dataLength = endian::readNext(data); + return {keyLength, dataLength}; + } + + static internal_key_type ReadKey(const uint8_t *data, unsigned length) { + return StringRef(reinterpret_cast(data), length); + } + + static data_type ReadData(internal_key_type key, const uint8_t *data, + unsigned length) { + using namespace llvm::support; + data_type result; + const uint8_t *limit = data + length; + while (data < limit) { + DeclID genSigId = endian::readNext(data); + int32_t nameLength = endian::readNext(data); + StringRef mangledName(reinterpret_cast(data), nameLength); + data += nameLength; + result.push_back({mangledName, genSigId}); + } + return result; + } +}; + +struct ModuleFileSharedCore::DeserializedCommentInfo { + SmallVector RawCommentStore; + CommentInfo Info; +}; + +class ModuleFileSharedCore::DeclCommentTableInfo { +public: + using internal_key_type = StringRef; + using external_key_type = StringRef; + using data_type = std::unique_ptr; + using hash_value_type = uint32_t; + using offset_type = unsigned; + + internal_key_type GetInternalKey(external_key_type key) { + return key; + } + + hash_value_type ComputeHash(internal_key_type key) { + assert(!key.empty()); + return llvm::djbHash(key, serialization::SWIFTDOC_HASH_SEED_5_1); + } + + static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { + return lhs == rhs; + } + + static std::pair ReadKeyDataLength(const uint8_t *&data) { + using namespace llvm::support; + unsigned keyLength = endian::readNext(data); + unsigned dataLength = endian::readNext(data); + return { keyLength, dataLength }; + } + + static internal_key_type ReadKey(const uint8_t *data, unsigned length) { + return StringRef(reinterpret_cast(data), length); + } + + data_type ReadData(internal_key_type key, const uint8_t *data, + unsigned length) { + using namespace llvm::support; + data_type result = std::make_unique(); + + { + unsigned BriefSize = endian::readNext(data); + result->Info.Brief = StringRef(reinterpret_cast(data), BriefSize); + data += BriefSize; + } + + unsigned NumComments = endian::readNext(data); + + for (unsigned i = 0; i != NumComments; ++i) { + unsigned StartColumn = + endian::readNext(data); + unsigned RawSize = endian::readNext(data); + auto RawText = StringRef(reinterpret_cast(data), RawSize); + data += RawSize; + + result->RawCommentStore.emplace_back(RawText, StartColumn); + } + result->Info.Raw = RawComment(result->RawCommentStore); + result->Info.Group = endian::readNext(data); + result->Info.SourceOrder = endian::readNext(data); + return result; + } +}; + +class ModuleFileSharedCore::DeclUSRTableInfo { +public: + using internal_key_type = StringRef; + using external_key_type = StringRef; + using data_type = uint32_t; + using hash_value_type = uint32_t; + using offset_type = unsigned; + + internal_key_type GetInternalKey(external_key_type key) { return key; } + + hash_value_type ComputeHash(internal_key_type key) { + assert(!key.empty()); + return llvm::djbHash(key, serialization::SWIFTSOURCEINFO_HASH_SEED); + } + + static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { + return lhs == rhs; + } + + static std::pair ReadKeyDataLength(const uint8_t *&data) { + using namespace llvm::support; + unsigned keyLength = endian::readNext(data); + unsigned dataLength = 4; + return { keyLength, dataLength }; + } + + static internal_key_type ReadKey(const uint8_t *data, unsigned length) { + return StringRef(reinterpret_cast(data), length); + } + + data_type ReadData(internal_key_type key, const uint8_t *data, unsigned length) { + using namespace llvm::support; + assert(length == 4); + return endian::readNext(data); + } +}; + +} // end namespace swift + +#endif diff --git a/lib/Serialization/ModuleFileSharedCore.cpp b/lib/Serialization/ModuleFileSharedCore.cpp new file mode 100644 index 0000000000000..aa0adae1f635d --- /dev/null +++ b/lib/Serialization/ModuleFileSharedCore.cpp @@ -0,0 +1,1447 @@ +//===--- ModuleFileSharedCore.cpp - Core of a serialized module -----------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#include "ModuleFileSharedCore.h" +#include "ModuleFileCoreTableInfo.h" +#include "BCReadingExtras.h" +#include "DeserializationErrors.h" +#include "swift/Strings.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/OnDiskHashTable.h" + +using namespace swift; +using namespace swift::serialization; +using namespace llvm::support; +using llvm::Expected; + +StringRef swift::getNameOfModule(const ModuleFileSharedCore *MF) { + return MF->getName(); +} + +static bool checkModuleSignature(llvm::BitstreamCursor &cursor, + ArrayRef signature) { + for (unsigned char byte : signature) { + if (cursor.AtEndOfStream()) + return false; + if (Expected maybeRead = + cursor.Read(8)) { + if (maybeRead.get() != byte) + return false; + } else { + consumeError(maybeRead.takeError()); + return false; + } + } + return true; +} + +static bool enterTopLevelModuleBlock(llvm::BitstreamCursor &cursor, + unsigned ID, + bool shouldReadBlockInfo = true) { + Expected maybeNext = cursor.advance(); + if (!maybeNext) { + // FIXME this drops the error on the floor. + consumeError(maybeNext.takeError()); + return false; + } + llvm::BitstreamEntry next = maybeNext.get(); + + if (next.Kind != llvm::BitstreamEntry::SubBlock) + return false; + + if (next.ID == llvm::bitc::BLOCKINFO_BLOCK_ID) { + if (shouldReadBlockInfo) { + if (!cursor.ReadBlockInfoBlock()) + return false; + } else { + if (cursor.SkipBlock()) + return false; + } + return enterTopLevelModuleBlock(cursor, ID, false); + } + + if (next.ID != ID) + return false; + + if (llvm::Error Err = cursor.EnterSubBlock(ID)) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); + return false; + } + + return true; +} + +/// Populate \p extendedInfo with the data from the options block. +/// +/// Returns true on success. +static bool readOptionsBlock(llvm::BitstreamCursor &cursor, + SmallVectorImpl &scratch, + ExtendedValidationInfo &extendedInfo) { + while (!cursor.AtEndOfStream()) { + Expected maybeEntry = cursor.advance(); + if (!maybeEntry) { + // FIXME this drops the error on the floor. + consumeError(maybeEntry.takeError()); + return false; + } + llvm::BitstreamEntry entry = maybeEntry.get(); + if (entry.Kind == llvm::BitstreamEntry::EndBlock) + break; + + if (entry.Kind == llvm::BitstreamEntry::Error) + return false; + + if (entry.Kind == llvm::BitstreamEntry::SubBlock) { + // Unknown metadata sub-block, possibly for use by a future version of + // the module format. + if (cursor.SkipBlock()) + return false; + continue; + } + + scratch.clear(); + StringRef blobData; + Expected maybeKind = + cursor.readRecord(entry.ID, scratch, &blobData); + if (!maybeKind) { + // FIXME this drops the error on the floor. + consumeError(maybeKind.takeError()); + return false; + } + unsigned kind = maybeKind.get(); + switch (kind) { + case options_block::SDK_PATH: + extendedInfo.setSDKPath(blobData); + break; + case options_block::XCC: + extendedInfo.addExtraClangImporterOption(blobData); + break; + case options_block::IS_SIB: + bool IsSIB; + options_block::IsSIBLayout::readRecord(scratch, IsSIB); + extendedInfo.setIsSIB(IsSIB); + break; + case options_block::IS_TESTABLE: + extendedInfo.setIsTestable(true); + break; + case options_block::ARE_PRIVATE_IMPORTS_ENABLED: + extendedInfo.setPrivateImportsEnabled(true); + break; + case options_block::IS_IMPLICIT_DYNAMIC_ENABLED: + extendedInfo.setImplicitDynamicEnabled(true); + break; + case options_block::RESILIENCE_STRATEGY: + unsigned Strategy; + options_block::ResilienceStrategyLayout::readRecord(scratch, Strategy); + extendedInfo.setResilienceStrategy(ResilienceStrategy(Strategy)); + break; + default: + // Unknown options record, possibly for use by a future version of the + // module format. + break; + } + } + + return true; +} + +static ValidationInfo +validateControlBlock(llvm::BitstreamCursor &cursor, + SmallVectorImpl &scratch, + std::pair expectedVersion, + ExtendedValidationInfo *extendedInfo) { + // The control block is malformed until we've at least read a major version + // number. + ValidationInfo result; + bool versionSeen = false; + + while (!cursor.AtEndOfStream()) { + Expected maybeEntry = cursor.advance(); + if (!maybeEntry) { + // FIXME this drops the error on the floor. + consumeError(maybeEntry.takeError()); + result.status = Status::Malformed; + return result; + } + llvm::BitstreamEntry entry = maybeEntry.get(); + if (entry.Kind == llvm::BitstreamEntry::EndBlock) + break; + + if (entry.Kind == llvm::BitstreamEntry::Error) { + result.status = Status::Malformed; + return result; + } + + if (entry.Kind == llvm::BitstreamEntry::SubBlock) { + if (entry.ID == OPTIONS_BLOCK_ID && extendedInfo) { + if (llvm::Error Err = cursor.EnterSubBlock(OPTIONS_BLOCK_ID)) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); + result.status = Status::Malformed; + return result; + } + if (!readOptionsBlock(cursor, scratch, *extendedInfo)) { + result.status = Status::Malformed; + return result; + } + } else { + // Unknown metadata sub-block, possibly for use by a future version of + // the module format. + if (cursor.SkipBlock()) { + result.status = Status::Malformed; + return result; + } + } + continue; + } + + scratch.clear(); + StringRef blobData; + Expected maybeKind = + cursor.readRecord(entry.ID, scratch, &blobData); + if (!maybeKind) { + // FIXME this drops the error on the floor. + consumeError(maybeKind.takeError()); + result.status = Status::Malformed; + return result; + } + unsigned kind = maybeKind.get(); + switch (kind) { + case control_block::METADATA: { + if (versionSeen) { + result.status = Status::Malformed; + break; + } + + uint16_t versionMajor = scratch[0]; + if (versionMajor > expectedVersion.first) + result.status = Status::FormatTooNew; + else if (versionMajor < expectedVersion.first) + result.status = Status::FormatTooOld; + else + result.status = Status::Valid; + + // Major version 0 does not have stable minor versions. + if (versionMajor == 0) { + uint16_t versionMinor = scratch[1]; + if (versionMinor != expectedVersion.second) { + if (versionMinor < expectedVersion.second) + result.status = Status::FormatTooOld; + else + result.status = Status::FormatTooNew; + } + } + + // These fields were added later; be resilient against their absence. + switch (scratch.size()) { + default: + // Add new cases here, in descending order. + case 4: + if (scratch[3] != 0) { + result.compatibilityVersion = + version::Version(blobData.substr(scratch[2]+1, scratch[3]), + SourceLoc(), nullptr); + } + LLVM_FALLTHROUGH; + case 3: + result.shortVersion = blobData.slice(0, scratch[2]); + LLVM_FALLTHROUGH; + case 2: + case 1: + case 0: + break; + } + + result.miscVersion = blobData; + versionSeen = true; + break; + } + case control_block::MODULE_NAME: + result.name = blobData; + break; + case control_block::TARGET: + result.targetTriple = blobData; + break; + default: + // Unknown metadata record, possibly for use by a future version of the + // module format. + break; + } + } + + return result; +} + +static bool validateInputBlock( + llvm::BitstreamCursor &cursor, SmallVectorImpl &scratch, + SmallVectorImpl &dependencies) { + SmallVector dependencyDirectories; + SmallString<256> dependencyFullPathBuffer; + + while (!cursor.AtEndOfStream()) { + Expected maybeEntry = cursor.advance(); + if (!maybeEntry) { + // FIXME this drops the error on the floor. + consumeError(maybeEntry.takeError()); + return true; + } + llvm::BitstreamEntry entry = maybeEntry.get(); + if (entry.Kind == llvm::BitstreamEntry::EndBlock) + break; + + if (entry.Kind == llvm::BitstreamEntry::Error) + return true; + + scratch.clear(); + StringRef blobData; + Expected maybeKind = + cursor.readRecord(entry.ID, scratch, &blobData); + if (!maybeKind) { + // FIXME this drops the error on the floor. + consumeError(maybeKind.takeError()); + return true; + } + unsigned kind = maybeKind.get(); + switch (kind) { + case input_block::FILE_DEPENDENCY: { + bool isHashBased = scratch[2] != 0; + bool isSDKRelative = scratch[3] != 0; + + StringRef path = blobData; + size_t directoryIndex = scratch[4]; + if (directoryIndex != 0) { + if (directoryIndex > dependencyDirectories.size()) + return true; + dependencyFullPathBuffer = dependencyDirectories[directoryIndex-1]; + llvm::sys::path::append(dependencyFullPathBuffer, blobData); + path = dependencyFullPathBuffer; + } + + if (isHashBased) { + dependencies.push_back( + SerializationOptions::FileDependency::hashBased( + path, isSDKRelative, scratch[0], scratch[1])); + } else { + dependencies.push_back( + SerializationOptions::FileDependency::modTimeBased( + path, isSDKRelative, scratch[0], scratch[1])); + } + break; + } + case input_block::DEPENDENCY_DIRECTORY: + dependencyDirectories.push_back(blobData); + break; + default: + // Unknown metadata record, possibly for use by a future version of the + // module format. + break; + } + } + return false; +} + + +bool serialization::isSerializedAST(StringRef data) { + StringRef signatureStr(reinterpret_cast(SWIFTMODULE_SIGNATURE), + llvm::array_lengthof(SWIFTMODULE_SIGNATURE)); + return data.startswith(signatureStr); +} + +ValidationInfo serialization::validateSerializedAST( + StringRef data, + ExtendedValidationInfo *extendedInfo, + SmallVectorImpl *dependencies) { + ValidationInfo result; + + // Check 32-bit alignment. + if (data.size() % SWIFTMODULE_ALIGNMENT != 0 || + reinterpret_cast(data.data()) % SWIFTMODULE_ALIGNMENT != 0) + return result; + + llvm::BitstreamCursor cursor(data); + SmallVector scratch; + + if (!checkModuleSignature(cursor, SWIFTMODULE_SIGNATURE) || + !enterTopLevelModuleBlock(cursor, MODULE_BLOCK_ID, false)) + return result; + + llvm::BitstreamEntry topLevelEntry; + + while (!cursor.AtEndOfStream()) { + Expected maybeEntry = + cursor.advance(AF_DontPopBlockAtEnd); + if (!maybeEntry) { + // FIXME this drops the error on the floor. + consumeError(maybeEntry.takeError()); + result.status = Status::Malformed; + return result; + } + topLevelEntry = maybeEntry.get(); + if (topLevelEntry.Kind != llvm::BitstreamEntry::SubBlock) + break; + + if (topLevelEntry.ID == CONTROL_BLOCK_ID) { + if (llvm::Error Err = cursor.EnterSubBlock(CONTROL_BLOCK_ID)) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); + result.status = Status::Malformed; + return result; + } + result = validateControlBlock(cursor, scratch, + {SWIFTMODULE_VERSION_MAJOR, + SWIFTMODULE_VERSION_MINOR}, + extendedInfo); + if (result.status == Status::Malformed) + return result; + } else if (dependencies && + result.status == Status::Valid && + topLevelEntry.ID == INPUT_BLOCK_ID) { + if (llvm::Error Err = cursor.EnterSubBlock(INPUT_BLOCK_ID)) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); + result.status = Status::Malformed; + return result; + } + if (validateInputBlock(cursor, scratch, *dependencies)) { + result.status = Status::Malformed; + return result; + } + } else { + if (cursor.SkipBlock()) { + result.status = Status::Malformed; + return result; + } + } + } + + if (topLevelEntry.Kind == llvm::BitstreamEntry::EndBlock) { + cursor.ReadBlockEnd(); + assert(cursor.GetCurrentBitNo() % CHAR_BIT == 0); + result.bytes = cursor.GetCurrentBitNo() / CHAR_BIT; + } else { + result.status = Status::Malformed; + } + + return result; +} + +std::string ModuleFileSharedCore::Dependency::getPrettyPrintedPath() const { + StringRef pathWithoutScope = RawPath; + if (isScoped()) { + size_t splitPoint = pathWithoutScope.find_last_of('\0'); + pathWithoutScope = pathWithoutScope.slice(0, splitPoint); + } + std::string output = pathWithoutScope.str(); + std::replace(output.begin(), output.end(), '\0', '.'); + return output; +} + +void ModuleFileSharedCore::fatal(llvm::Error error) { + logAllUnhandledErrors(std::move(error), llvm::errs(), + "\n*** DESERIALIZATION FAILURE (please include this " + "section in any bug report) ***\n"); + abort(); +} + +ModuleFileSharedCore::~ModuleFileSharedCore() { } + +std::unique_ptr +ModuleFileSharedCore::readDeclTable(ArrayRef fields, + StringRef blobData) const { + uint32_t tableOffset; + index_block::DeclListLayout::readRecord(fields, tableOffset); + auto base = reinterpret_cast(blobData.data()); + + using OwnedTable = std::unique_ptr; + return OwnedTable(SerializedDeclTable::Create(base + tableOffset, + base + sizeof(uint32_t), base)); +} + +std::unique_ptr +ModuleFileSharedCore::readExtensionTable(ArrayRef fields, + StringRef blobData) const { + uint32_t tableOffset; + index_block::DeclListLayout::readRecord(fields, tableOffset); + auto base = reinterpret_cast(blobData.data()); + + using OwnedTable = std::unique_ptr; + return OwnedTable(SerializedExtensionTable::Create(base + tableOffset, + base + sizeof(uint32_t), base, ExtensionTableInfo(*this))); +} + +std::unique_ptr +ModuleFileSharedCore::readLocalDeclTable(ArrayRef fields, + StringRef blobData) const { + uint32_t tableOffset; + index_block::DeclListLayout::readRecord(fields, tableOffset); + auto base = reinterpret_cast(blobData.data()); + + using OwnedTable = std::unique_ptr; + return OwnedTable(SerializedLocalDeclTable::Create(base + tableOffset, + base + sizeof(uint32_t), base)); +} + +std::unique_ptr +ModuleFileSharedCore::readNestedTypeDeclsTable(ArrayRef fields, + StringRef blobData) const { + uint32_t tableOffset; + index_block::NestedTypeDeclsLayout::readRecord(fields, tableOffset); + auto base = reinterpret_cast(blobData.data()); + + using OwnedTable = std::unique_ptr; + return OwnedTable(SerializedNestedTypeDeclsTable::Create(base + tableOffset, + base + sizeof(uint32_t), base)); +} + +std::unique_ptr +ModuleFileSharedCore::readDeclMemberNamesTable(ArrayRef fields, + StringRef blobData) const { + uint32_t tableOffset; + index_block::DeclMemberNamesLayout::readRecord(fields, tableOffset); + auto base = reinterpret_cast(blobData.data()); + + using OwnedTable = std::unique_ptr; + return OwnedTable(SerializedDeclMemberNamesTable::Create(base + tableOffset, + base + sizeof(uint32_t), base)); +} + +std::unique_ptr +ModuleFileSharedCore::readDeclMembersTable(ArrayRef fields, + StringRef blobData) const { + uint32_t tableOffset; + decl_member_tables_block::DeclMembersLayout::readRecord(fields, + tableOffset); + auto base = reinterpret_cast(blobData.data()); + + using OwnedTable = std::unique_ptr; + return OwnedTable(SerializedDeclMembersTable::Create(base + tableOffset, + base + sizeof(uint32_t), base)); +} + +std::unique_ptr +ModuleFileSharedCore::readObjCMethodTable(ArrayRef fields, + StringRef blobData) const { + uint32_t tableOffset; + index_block::ObjCMethodTableLayout::readRecord(fields, tableOffset); + auto base = reinterpret_cast(blobData.data()); + + using OwnedTable = std::unique_ptr; + return OwnedTable( + SerializedObjCMethodTable::Create(base + tableOffset, + base + sizeof(uint32_t), base)); +} + +std::unique_ptr +ModuleFileSharedCore::readDerivativeFunctionConfigTable( + ArrayRef fields, StringRef blobData) const { + uint32_t tableOffset; + index_block::DerivativeFunctionConfigTableLayout::readRecord(fields, + tableOffset); + auto base = reinterpret_cast(blobData.data()); + + using OwnedTable = std::unique_ptr; + return OwnedTable(SerializedDerivativeFunctionConfigTable::Create( + base + tableOffset, base + sizeof(uint32_t), base)); +} + +bool ModuleFileSharedCore::readIndexBlock(llvm::BitstreamCursor &cursor) { + if (llvm::Error Err = cursor.EnterSubBlock(INDEX_BLOCK_ID)) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); + return false; + } + + SmallVector scratch; + StringRef blobData; + + while (!cursor.AtEndOfStream()) { + Expected maybeEntry = cursor.advance(); + if (!maybeEntry) { + // FIXME this drops the error on the floor. + consumeError(maybeEntry.takeError()); + return false; + } + llvm::BitstreamEntry entry = maybeEntry.get(); + switch (entry.Kind) { + case llvm::BitstreamEntry::EndBlock: + return true; + + case llvm::BitstreamEntry::Error: + return false; + + case llvm::BitstreamEntry::SubBlock: + if (entry.ID == DECL_MEMBER_TABLES_BLOCK_ID) { + DeclMemberTablesCursor = cursor; + if (llvm::Error Err = DeclMemberTablesCursor.EnterSubBlock( + DECL_MEMBER_TABLES_BLOCK_ID)) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); + return false; + } + llvm::BitstreamEntry subentry; + do { + // Scan forward, to load the cursor with any abbrevs we'll need while + // seeking inside this block later. + Expected maybeEntry = + DeclMemberTablesCursor.advance( + llvm::BitstreamCursor::AF_DontPopBlockAtEnd); + if (!maybeEntry) { + // FIXME this drops the error on the floor. + consumeError(maybeEntry.takeError()); + return false; + } + subentry = maybeEntry.get(); + } while (!DeclMemberTablesCursor.AtEndOfStream() && + subentry.Kind != llvm::BitstreamEntry::Record && + subentry.Kind != llvm::BitstreamEntry::EndBlock); + } + if (cursor.SkipBlock()) + return false; + break; + + case llvm::BitstreamEntry::Record: + scratch.clear(); + blobData = {}; + Expected maybeKind = + cursor.readRecord(entry.ID, scratch, &blobData); + if (!maybeKind) { + // FIXME this drops the error on the floor. + consumeError(maybeKind.takeError()); + return false; + } + unsigned kind = maybeKind.get(); + + switch (kind) { + case index_block::DECL_OFFSETS: + assert(blobData.empty()); + allocateBuffer(Decls, scratch); + break; + case index_block::TYPE_OFFSETS: + assert(blobData.empty()); + allocateBuffer(Types, scratch); + break; + case index_block::CLANG_TYPE_OFFSETS: + assert(blobData.empty()); + allocateBuffer(ClangTypes, scratch); + break; + case index_block::IDENTIFIER_OFFSETS: + assert(blobData.empty()); + allocateBuffer(Identifiers, scratch); + break; + case index_block::TOP_LEVEL_DECLS: + TopLevelDecls = readDeclTable(scratch, blobData); + break; + case index_block::OPERATORS: + OperatorDecls = readDeclTable(scratch, blobData); + break; + case index_block::PRECEDENCE_GROUPS: + PrecedenceGroupDecls = readDeclTable(scratch, blobData); + break; + case index_block::EXTENSIONS: + ExtensionDecls = readExtensionTable(scratch, blobData); + break; + case index_block::CLASS_MEMBERS_FOR_DYNAMIC_LOOKUP: + ClassMembersForDynamicLookup = readDeclTable(scratch, blobData); + break; + case index_block::OPERATOR_METHODS: + OperatorMethodDecls = readDeclTable(scratch, blobData); + break; + case index_block::OBJC_METHODS: + ObjCMethods = readObjCMethodTable(scratch, blobData); + break; + case index_block::DERIVATIVE_FUNCTION_CONFIGURATIONS: + DerivativeFunctionConfigurations = + readDerivativeFunctionConfigTable(scratch, blobData); + break; + case index_block::ENTRY_POINT: + assert(blobData.empty()); + setEntryPointClassID(scratch.front()); + break; + case index_block::ORDERED_TOP_LEVEL_DECLS: + allocateBuffer(OrderedTopLevelDecls, scratch); + break; + case index_block::LOCAL_TYPE_DECLS: + LocalTypeDecls = readLocalDeclTable(scratch, blobData); + break; + case index_block::OPAQUE_RETURN_TYPE_DECLS: + OpaqueReturnTypeDecls = readLocalDeclTable(scratch, blobData); + break; + case index_block::NESTED_TYPE_DECLS: + NestedTypeDecls = readNestedTypeDeclsTable(scratch, blobData); + break; + case index_block::DECL_MEMBER_NAMES: + DeclMemberNames = readDeclMemberNamesTable(scratch, blobData); + break; + case index_block::LOCAL_DECL_CONTEXT_OFFSETS: + assert(blobData.empty()); + allocateBuffer(LocalDeclContexts, scratch); + break; + case index_block::GENERIC_SIGNATURE_OFFSETS: + assert(blobData.empty()); + allocateBuffer(GenericSignatures, scratch); + break; + case index_block::SUBSTITUTION_MAP_OFFSETS: + assert(blobData.empty()); + allocateBuffer(SubstitutionMaps, scratch); + break; + case index_block::NORMAL_CONFORMANCE_OFFSETS: + assert(blobData.empty()); + allocateBuffer(NormalConformances, scratch); + break; + case index_block::SIL_LAYOUT_OFFSETS: + assert(blobData.empty()); + allocateBuffer(SILLayouts, scratch); + break; + + default: + // Unknown index kind, which this version of the compiler won't use. + break; + } + break; + } + } + + return false; +} + +std::unique_ptr +ModuleFileSharedCore::readDeclCommentTable(ArrayRef fields, + StringRef blobData) const { + if (fields.empty() || blobData.empty()) + return nullptr; + uint32_t tableOffset = static_cast(fields.front()); + auto base = reinterpret_cast(blobData.data()); + + return std::unique_ptr( + SerializedDeclCommentTable::Create(base + tableOffset, + base + sizeof(uint32_t), base)); +} + +std::unique_ptr +ModuleFileSharedCore::readGroupTable(ArrayRef Fields, + StringRef BlobData) const { + auto pMap = std::make_unique>(); + auto Data = reinterpret_cast(BlobData.data()); + unsigned GroupCount = endian::readNext(Data); + for (unsigned I = 0; I < GroupCount; ++I) { + auto RawSize = endian::readNext(Data); + auto RawText = StringRef(reinterpret_cast(Data), RawSize); + Data += RawSize; + (*pMap)[I] = RawText; + } + return std::unique_ptr(pMap.release()); +} + +bool ModuleFileSharedCore::readCommentBlock(llvm::BitstreamCursor &cursor) { + if (llvm::Error Err = cursor.EnterSubBlock(COMMENT_BLOCK_ID)) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); + return false; + } + + SmallVector scratch; + StringRef blobData; + + while (!cursor.AtEndOfStream()) { + Expected maybeEntry = cursor.advance(); + if (!maybeEntry) { + // FIXME this drops the error on the floor. + consumeError(maybeEntry.takeError()); + return false; + } + llvm::BitstreamEntry entry = maybeEntry.get(); + switch (entry.Kind) { + case llvm::BitstreamEntry::EndBlock: + return true; + + case llvm::BitstreamEntry::Error: + return false; + + case llvm::BitstreamEntry::SubBlock: + // Unknown sub-block, which this version of the compiler won't use. + if (cursor.SkipBlock()) + return false; + break; + + case llvm::BitstreamEntry::Record: + scratch.clear(); + Expected maybeKind = + cursor.readRecord(entry.ID, scratch, &blobData); + if (!maybeKind) { + // FIXME this drops the error on the floor. + consumeError(maybeKind.takeError()); + return false; + } + unsigned kind = maybeKind.get(); + + switch (kind) { + case comment_block::DECL_COMMENTS: + DeclCommentTable = readDeclCommentTable(scratch, blobData); + break; + case comment_block::GROUP_NAMES: + GroupNamesMap = readGroupTable(scratch, blobData); + break; + default: + // Unknown index kind, which this version of the compiler won't use. + break; + } + break; + } + } + + return false; +} + +static Optional getActualLibraryKind(unsigned rawKind) { + auto stableKind = static_cast(rawKind); + if (stableKind != rawKind) + return None; + + switch (stableKind) { + case serialization::LibraryKind::Library: + return swift::LibraryKind::Library; + case serialization::LibraryKind::Framework: + return swift::LibraryKind::Framework; + } + + // If there's a new case value in the module file, ignore it. + return None; +} + +static Optional +getActualImportControl(unsigned rawValue) { + // We switch on the raw value rather than the enum in order to handle future + // values. + switch (rawValue) { + case static_cast(serialization::ImportControl::Normal): + return ModuleDecl::ImportFilterKind::Private; + case static_cast(serialization::ImportControl::Exported): + return ModuleDecl::ImportFilterKind::Public; + case static_cast(serialization::ImportControl::ImplementationOnly): + return ModuleDecl::ImportFilterKind::ImplementationOnly; + default: + return None; + } +} + +bool ModuleFileSharedCore::readModuleDocIfPresent() { + if (!this->ModuleDocInputBuffer) + return true; + + llvm::BitstreamCursor docCursor{ModuleDocInputBuffer->getMemBufferRef()}; + if (!checkModuleSignature(docCursor, SWIFTDOC_SIGNATURE) || + !enterTopLevelModuleBlock(docCursor, MODULE_DOC_BLOCK_ID)) { + return false; + } + + SmallVector scratch; + llvm::BitstreamEntry topLevelEntry; + + bool hasValidControlBlock = false; + ValidationInfo info; + + while (!docCursor.AtEndOfStream()) { + Expected maybeEntry = + docCursor.advance(AF_DontPopBlockAtEnd); + if (!maybeEntry) { + // FIXME this drops the error on the floor. + consumeError(maybeEntry.takeError()); + return false; + } + topLevelEntry = maybeEntry.get(); + if (topLevelEntry.Kind != llvm::BitstreamEntry::SubBlock) + break; + + switch (topLevelEntry.ID) { + case CONTROL_BLOCK_ID: { + if (llvm::Error Err = docCursor.EnterSubBlock(CONTROL_BLOCK_ID)) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); + return false; + } + + info = validateControlBlock(docCursor, scratch, + {SWIFTDOC_VERSION_MAJOR, + SWIFTDOC_VERSION_MINOR}, + /*extendedInfo*/nullptr); + if (info.status != Status::Valid) + return false; + // Check that the swiftdoc is actually for this module. + if (info.name != Name) + return false; + hasValidControlBlock = true; + break; + } + + case COMMENT_BLOCK_ID: { + if (!hasValidControlBlock || !readCommentBlock(docCursor)) + return false; + break; + } + + default: + // Unknown top-level block, possibly for use by a future version of the + // module format. + if (docCursor.SkipBlock()) + return false; + break; + } + } + + if (topLevelEntry.Kind != llvm::BitstreamEntry::EndBlock) + return false; + + return true; +} + +std::unique_ptr +ModuleFileSharedCore::readDeclUSRsTable(ArrayRef fields, + StringRef blobData) const { + if (fields.empty() || blobData.empty()) + return nullptr; + uint32_t tableOffset = static_cast(fields.front()); + auto base = reinterpret_cast(blobData.data()); + return std::unique_ptr( + SerializedDeclUSRTable::Create(base + tableOffset, base + sizeof(uint32_t), + base)); +} + +bool ModuleFileSharedCore::readDeclLocsBlock(llvm::BitstreamCursor &cursor) { + if (llvm::Error Err = cursor.EnterSubBlock(CONTROL_BLOCK_ID)) { + consumeError(std::move(Err)); + return false; + } + + SmallVector scratch; + StringRef blobData; + + while (!cursor.AtEndOfStream()) { + Expected entry = cursor.advance(); + if (!entry) { + consumeError(entry.takeError()); + return false; + } + switch (entry->Kind) { + case llvm::BitstreamEntry::EndBlock: + return true; + + case llvm::BitstreamEntry::Error: + return false; + + case llvm::BitstreamEntry::SubBlock: + // Unknown sub-block, which this version of the compiler won't use. + if (cursor.SkipBlock()) + return false; + break; + + case llvm::BitstreamEntry::Record: + scratch.clear(); + Expected kind = + cursor.readRecord(entry->ID, scratch, &blobData); + if (!kind) { + consumeError(kind.takeError()); + return false; + } + switch (*kind) { + case decl_locs_block::BASIC_DECL_LOCS: + BasicDeclLocsData = blobData; + break; + case decl_locs_block::TEXT_DATA: + SourceLocsTextData = blobData; + break; + case decl_locs_block::DECL_USRS: + DeclUSRsTable = readDeclUSRsTable(scratch, blobData); + break; + case decl_locs_block::DOC_RANGES: + DocRangesData = blobData; + break; + default: + // Unknown index kind, which this version of the compiler won't use. + break; + } + break; + } + } + + return false; +} + +bool ModuleFileSharedCore::readModuleSourceInfoIfPresent() { + if (!this->ModuleSourceInfoInputBuffer) + return true; + + llvm::BitstreamCursor infoCursor{ + ModuleSourceInfoInputBuffer->getMemBufferRef()}; + if (!checkModuleSignature(infoCursor, SWIFTSOURCEINFO_SIGNATURE) || + !enterTopLevelModuleBlock(infoCursor, MODULE_SOURCEINFO_BLOCK_ID)) { + return false; + } + + SmallVector scratch; + + bool hasValidControlBlock = false; + ValidationInfo info; + unsigned kind = llvm::BitstreamEntry::Error; + + while (!infoCursor.AtEndOfStream()) { + Expected topLevelEntry = + infoCursor.advance(AF_DontPopBlockAtEnd); + if (!topLevelEntry) { + consumeError(topLevelEntry.takeError()); + return false; + } + kind = topLevelEntry->Kind; + if (kind != llvm::BitstreamEntry::SubBlock) + break; + + switch (topLevelEntry->ID) { + case CONTROL_BLOCK_ID: { + if (llvm::Error Err = infoCursor.EnterSubBlock(CONTROL_BLOCK_ID)) { + consumeError(std::move(Err)); + return false; + } + info = validateControlBlock(infoCursor, scratch, + {SWIFTSOURCEINFO_VERSION_MAJOR, + SWIFTSOURCEINFO_VERSION_MINOR}, + /*extendedInfo*/nullptr); + if (info.status != Status::Valid) + return false; + // Check that the swiftsourceinfo is actually for this module. + if (info.name != Name) + return false; + hasValidControlBlock = true; + break; + } + + case DECL_LOCS_BLOCK_ID: { + if (!hasValidControlBlock || !readDeclLocsBlock(infoCursor)) + return false; + break; + } + + default: + // Unknown top-level block, possibly for use by a future version of the + // module format. + if (infoCursor.SkipBlock()) + return false; + break; + } + } + + if (kind != llvm::BitstreamEntry::EndBlock) + return false; + + return true; +} + +StringRef ModuleFileSharedCore::getModuleNameFromID(ModuleID MID) const { + if (MID < NUM_SPECIAL_IDS) { + switch (static_cast(static_cast(MID))) { + case BUILTIN_MODULE_ID: + return BUILTIN_NAME; + case CURRENT_MODULE_ID: + return Name; + case OBJC_HEADER_MODULE_ID: + return CLANG_HEADER_MODULE_NAME; + case SUBSCRIPT_ID: + case CONSTRUCTOR_ID: + case DESTRUCTOR_ID: + llvm_unreachable("Modules cannot be named with special names"); + case NUM_SPECIAL_IDS: + llvm_unreachable("implementation detail only"); + } + } + return getIdentifierText(MID); +} + +StringRef ModuleFileSharedCore::getIdentifierText(IdentifierID IID) const { + if (IID == 0) + return StringRef(); + + assert(IID >= NUM_SPECIAL_IDS); + + size_t rawID = IID - NUM_SPECIAL_IDS; + assert(rawID < Identifiers.size() && "invalid identifier ID"); + auto offset = Identifiers[rawID]; + + assert(!IdentifierData.empty() && "no identifier data in module"); + + StringRef rawStrPtr = IdentifierData.substr(offset); + size_t terminatorOffset = rawStrPtr.find('\0'); + assert(terminatorOffset != StringRef::npos && + "unterminated identifier string data"); + return rawStrPtr.slice(0, terminatorOffset); +} + +ModuleFileSharedCore::ModuleFileSharedCore( + std::unique_ptr moduleInputBuffer, + std::unique_ptr moduleDocInputBuffer, + std::unique_ptr moduleSourceInfoInputBuffer, + bool isFramework, serialization::ValidationInfo &info, + serialization::ExtendedValidationInfo *extInfo) + : ModuleInputBuffer(std::move(moduleInputBuffer)), + ModuleDocInputBuffer(std::move(moduleDocInputBuffer)), + ModuleSourceInfoInputBuffer(std::move(moduleSourceInfoInputBuffer)) { + assert(!hasError()); + Bits.IsFramework = isFramework; + + PrettyStackTraceModuleFileCore stackEntry(*this); + + llvm::BitstreamCursor cursor{ModuleInputBuffer->getMemBufferRef()}; + + if (!checkModuleSignature(cursor, SWIFTMODULE_SIGNATURE) || + !enterTopLevelModuleBlock(cursor, MODULE_BLOCK_ID)) { + info.status = error(Status::Malformed); + return; + } + + // Future-proofing: make sure we validate the control block before we try to + // read any other blocks. + bool hasValidControlBlock = false; + SmallVector scratch; + + llvm::BitstreamEntry topLevelEntry; + + while (!cursor.AtEndOfStream()) { + Expected maybeEntry = + cursor.advance(AF_DontPopBlockAtEnd); + if (!maybeEntry) { + // FIXME this drops the error diagnostic on the floor. + consumeError(maybeEntry.takeError()); + info.status = error(Status::Malformed); + return; + } + topLevelEntry = maybeEntry.get(); + if (topLevelEntry.Kind != llvm::BitstreamEntry::SubBlock) + break; + + switch (topLevelEntry.ID) { + case CONTROL_BLOCK_ID: { + if (llvm::Error Err = cursor.EnterSubBlock(CONTROL_BLOCK_ID)) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); + info.status = error(Status::Malformed); + return; + } + + info = validateControlBlock(cursor, scratch, + {SWIFTMODULE_VERSION_MAJOR, + SWIFTMODULE_VERSION_MINOR}, + extInfo); + if (info.status != Status::Valid) { + error(info.status); + return; + } + Name = info.name; + TargetTriple = info.targetTriple; + CompatibilityVersion = info.compatibilityVersion; + IsSIB = extInfo->isSIB(); + MiscVersion = info.miscVersion; + + hasValidControlBlock = true; + break; + } + + case INPUT_BLOCK_ID: { + if (!hasValidControlBlock) { + info.status = error(Status::Malformed); + return; + } + + if (llvm::Error Err = cursor.EnterSubBlock(INPUT_BLOCK_ID)) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); + info.status = error(Status::Malformed); + return; + } + + Expected maybeNext = cursor.advance(); + if (!maybeNext) { + // FIXME this drops the error on the floor. + consumeError(maybeNext.takeError()); + info.status = error(Status::Malformed); + return; + } + llvm::BitstreamEntry next = maybeNext.get(); + while (next.Kind == llvm::BitstreamEntry::Record) { + scratch.clear(); + StringRef blobData; + Expected maybeKind = + cursor.readRecord(next.ID, scratch, &blobData); + if (!maybeKind) { + // FIXME this drops the error on the floor. + consumeError(maybeKind.takeError()); + info.status = error(Status::Malformed); + return; + } + unsigned kind = maybeKind.get(); + switch (kind) { + case input_block::IMPORTED_MODULE: { + unsigned rawImportControl; + bool scoped; + bool hasSPI; + input_block::ImportedModuleLayout::readRecord(scratch, + rawImportControl, + scoped, hasSPI); + auto importKind = getActualImportControl(rawImportControl); + if (!importKind) { + // We don't know how to import this dependency. + info.status = error(Status::Malformed); + return; + } + + StringRef spiBlob; + if (hasSPI) { + scratch.clear(); + + llvm::BitstreamEntry entry = + fatalIfUnexpected(cursor.advance(AF_DontPopBlockAtEnd)); + unsigned recordID = fatalIfUnexpected( + cursor.readRecord(entry.ID, scratch, &spiBlob)); + assert(recordID == input_block::IMPORTED_MODULE_SPIS); + input_block::ImportedModuleLayoutSPI::readRecord(scratch); + (void) recordID; + } else { + spiBlob = StringRef(); + } + + Dependencies.push_back( + {blobData, spiBlob, importKind.getValue(), scoped}); + break; + } + case input_block::LINK_LIBRARY: { + uint8_t rawKind; + bool shouldForceLink; + input_block::LinkLibraryLayout::readRecord(scratch, rawKind, + shouldForceLink); + if (auto libKind = getActualLibraryKind(rawKind)) + LinkLibraries.push_back({blobData, *libKind, shouldForceLink}); + // else ignore the dependency...it'll show up as a linker error. + break; + } + case input_block::IMPORTED_HEADER: { + assert(!importedHeaderInfo.fileSize && "only one header allowed"); + bool exported; + input_block::ImportedHeaderLayout::readRecord(scratch, + exported, importedHeaderInfo.fileSize, + importedHeaderInfo.fileModTime); + Dependencies.push_back(Dependency::forHeader(blobData, exported)); + break; + } + case input_block::IMPORTED_HEADER_CONTENTS: { + assert(Dependencies.back().isHeader() && "must follow header record"); + assert(importedHeaderInfo.contents.empty() && + "contents seen already"); + importedHeaderInfo.contents = blobData; + break; + } + case input_block::SEARCH_PATH: { + bool isFramework; + bool isSystem; + input_block::SearchPathLayout::readRecord(scratch, isFramework, + isSystem); + SearchPaths.push_back({blobData, isFramework, isSystem}); + break; + } + case input_block::MODULE_INTERFACE_PATH: { + ModuleInterfacePath = blobData; + break; + } + default: + // Unknown input kind, possibly for use by a future version of the + // module format. + // FIXME: Should we warn about this? + break; + } + + maybeNext = cursor.advance(); + if (!maybeNext) { + // FIXME this drops the error on the floor. + consumeError(maybeNext.takeError()); + info.status = error(Status::Malformed); + return; + } + next = maybeNext.get(); + } + + if (next.Kind != llvm::BitstreamEntry::EndBlock) + info.status = error(Status::Malformed); + + break; + } + + case DECLS_AND_TYPES_BLOCK_ID: { + if (!hasValidControlBlock) { + info.status = error(Status::Malformed); + return; + } + + // The decls-and-types block is lazily loaded. Save the cursor and load + // any abbrev records at the start of the block. + DeclTypeCursor = cursor; + if (llvm::Error Err = + DeclTypeCursor.EnterSubBlock(DECLS_AND_TYPES_BLOCK_ID)) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); + info.status = error(Status::Malformed); + return; + } + + Expected maybeCursor = DeclTypeCursor.advance(); + if (!maybeCursor) { + // FIXME this drops the error on the floor. + consumeError(maybeCursor.takeError()); + info.status = error(Status::Malformed); + return; + } + if (maybeCursor.get().Kind == llvm::BitstreamEntry::Error) + info.status = error(Status::Malformed); + + // With the main cursor, skip over the block and continue. + if (cursor.SkipBlock()) { + info.status = error(Status::Malformed); + return; + } + break; + } + + case IDENTIFIER_DATA_BLOCK_ID: { + if (!hasValidControlBlock) { + info.status = error(Status::Malformed); + return; + } + + if (llvm::Error Err = cursor.EnterSubBlock(IDENTIFIER_DATA_BLOCK_ID)) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); + info.status = error(Status::Malformed); + return; + } + + Expected maybeNext = + cursor.advanceSkippingSubblocks(); + if (!maybeNext) { + // FIXME this drops the error on the floor. + consumeError(maybeNext.takeError()); + info.status = error(Status::Malformed); + return; + } + llvm::BitstreamEntry next = maybeNext.get(); + while (next.Kind == llvm::BitstreamEntry::Record) { + scratch.clear(); + StringRef blobData; + Expected maybeKind = + cursor.readRecord(next.ID, scratch, &blobData); + if (!maybeKind) { + // FIXME this drops the error on the floor. + consumeError(maybeKind.takeError()); + info.status = error(Status::Malformed); + return; + } + unsigned kind = maybeKind.get(); + + switch (kind) { + case identifier_block::IDENTIFIER_DATA: + assert(scratch.empty()); + IdentifierData = blobData; + break; + default: + // Unknown identifier data, which this version of the compiler won't + // use. + break; + } + + maybeNext = cursor.advanceSkippingSubblocks(); + if (!maybeNext) { + // FIXME this drops the error on the floor. + consumeError(maybeNext.takeError()); + info.status = error(Status::Malformed); + return; + } + next = maybeNext.get(); + } + + if (next.Kind != llvm::BitstreamEntry::EndBlock) { + info.status = error(Status::Malformed); + return; + } + + break; + } + + case INDEX_BLOCK_ID: { + if (!hasValidControlBlock || !readIndexBlock(cursor)) { + info.status = error(Status::Malformed); + return; + } + break; + } + + case SIL_INDEX_BLOCK_ID: { + // Save the cursor. + SILIndexCursor = cursor; + if (llvm::Error Err = SILIndexCursor.EnterSubBlock(SIL_INDEX_BLOCK_ID)) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); + info.status = error(Status::Malformed); + return; + } + + // With the main cursor, skip over the block and continue. + if (cursor.SkipBlock()) { + info.status = error(Status::Malformed); + return; + } + break; + } + + case SIL_BLOCK_ID: { + // Save the cursor. + SILCursor = cursor; + if (llvm::Error Err = SILCursor.EnterSubBlock(SIL_BLOCK_ID)) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); + info.status = error(Status::Malformed); + return; + } + + // With the main cursor, skip over the block and continue. + if (cursor.SkipBlock()) { + info.status = error(Status::Malformed); + return; + } + break; + } + + default: + // Unknown top-level block, possibly for use by a future version of the + // module format. + if (cursor.SkipBlock()) { + info.status = error(Status::Malformed); + return; + } + break; + } + } + + if (topLevelEntry.Kind != llvm::BitstreamEntry::EndBlock) { + info.status = error(Status::Malformed); + return; + } + // Read source info file. + readModuleSourceInfoIfPresent(); + if (!readModuleDocIfPresent()) { + info.status = error(Status::MalformedDocumentation); + return; + } +} diff --git a/lib/Serialization/ModuleFileSharedCore.h b/lib/Serialization/ModuleFileSharedCore.h new file mode 100644 index 0000000000000..f7be1d18b9746 --- /dev/null +++ b/lib/Serialization/ModuleFileSharedCore.h @@ -0,0 +1,499 @@ +//===--- ModuleFileSharedCore.h - Core of a serialized module ---*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_SERIALIZATION_MODULEFILECORE_H +#define SWIFT_SERIALIZATION_MODULEFILECORE_H + +#include "ModuleFormat.h" +#include "swift/AST/LinkLibrary.h" +#include "swift/AST/Module.h" +#include "swift/Serialization/Validation.h" +#include "llvm/Bitstream/BitstreamReader.h" + +namespace llvm { + template class OnDiskIterableChainedHashTable; +} + +namespace swift { + +/// Serialized core data of a module. The difference with `ModuleFile` is that +/// `ModuleFileSharedCore` provides immutable data and is independent of a +/// particular ASTContext. It is designed to be able to be shared across +/// multiple `ModuleFile`s of different `ASTContext`s in a thread-safe manner. +/// +/// It is **important** to preserve the following properties for +/// `ModuleFileSharedCore`: +/// * a `ModuleFile` should access its assigned `ModuleFileSharedCore` as +/// immutable and thread-safe +/// * `ModuleFileSharedCore` should be Independent of an `ASTContext` object. +class ModuleFileSharedCore { + friend class ModuleFile; + using DeclID = serialization::DeclID; + using Status = serialization::Status; + + /// The module file data. + std::unique_ptr ModuleInputBuffer; + std::unique_ptr ModuleDocInputBuffer; + std::unique_ptr ModuleSourceInfoInputBuffer; + + /// The cursor used to lazily load things from the file. + llvm::BitstreamCursor DeclTypeCursor; + + llvm::BitstreamCursor SILCursor; + llvm::BitstreamCursor SILIndexCursor; + llvm::BitstreamCursor DeclMemberTablesCursor; + + /// The name of the module. + StringRef Name; + + /// The target the module was built for. + StringRef TargetTriple; + + /// The name of the module interface this module was compiled from. + /// + /// Empty if this module didn't come from an interface file. + StringRef ModuleInterfacePath; + + /// The Swift compatibility version in use when this module was built. + version::Version CompatibilityVersion; + + /// The data blob containing all of the module's identifiers. + StringRef IdentifierData; + + /// Is this module file actually a .sib file? .sib files are serialized SIL at + /// arbitrary granularity and arbitrary stage; unlike serialized Swift + /// modules, which are assumed to contain canonical SIL for an entire module. + bool IsSIB = false; + + // Full blob from the misc. version field of the metadata block. This should + // include the version string of the compiler that built the module. + StringRef MiscVersion; + +public: + /// Represents another module that has been imported as a dependency. + class Dependency { + public: + const StringRef RawPath; + const StringRef RawSPIs; + + private: + using ImportFilterKind = ModuleDecl::ImportFilterKind; + const unsigned RawImportControl : 2; + const unsigned IsHeader : 1; + const unsigned IsScoped : 1; + + static unsigned rawControlFromKind(ImportFilterKind importKind) { + return llvm::countTrailingZeros(static_cast(importKind)); + } + ImportFilterKind getImportControl() const { + return static_cast(1 << RawImportControl); + } + + Dependency(StringRef path, StringRef spiGroups, bool isHeader, + ImportFilterKind importControl, bool isScoped) + : RawPath(path), + RawSPIs(spiGroups), + RawImportControl(rawControlFromKind(importControl)), + IsHeader(isHeader), + IsScoped(isScoped) { + assert(llvm::countPopulation(static_cast(importControl)) == 1 && + "must be a particular filter option, not a bitset"); + assert(getImportControl() == importControl && "not enough bits"); + } + + public: + Dependency(StringRef path, StringRef spiGroups, + ImportFilterKind importControl, bool isScoped) + : Dependency(path, spiGroups, false, importControl, isScoped) {} + + static Dependency forHeader(StringRef headerPath, bool exported) { + auto importControl = + exported ? ImportFilterKind::Public : ImportFilterKind::Private; + return Dependency(headerPath, StringRef(), true, importControl, false); + } + + bool isExported() const { + return getImportControl() == ImportFilterKind::Public; + } + bool isImplementationOnly() const { + return getImportControl() == ImportFilterKind::ImplementationOnly; + } + + bool isHeader() const { return IsHeader; } + bool isScoped() const { return IsScoped; } + + std::string getPrettyPrintedPath() const; + }; + +private: + /// All modules this module depends on. + SmallVector Dependencies; + + struct SearchPath { + StringRef Path; + bool IsFramework; + bool IsSystem; + }; + /// Search paths this module may provide. + /// + /// This is not intended for use by frameworks, but may show up in debug + /// modules. + std::vector SearchPaths; + + /// Info for the (lone) imported header for this module. + struct { + off_t fileSize; + time_t fileModTime; + StringRef contents; + } importedHeaderInfo = {}; + + /// All of this module's link-time dependencies. + SmallVector LinkLibraries; + +public: + using RawBitOffset = uint64_t; + +private: + /// An allocator for buffers owned by the file. + llvm::BumpPtrAllocator Allocator; + + /// Allocates a buffer using #Allocator and initializes it with the contents + /// of the container \p rawData, then stores it in \p buffer. + /// + /// \p buffer is passed as an argument rather than returned so that the + /// element type can be inferred. + template + void allocateBuffer(MutableArrayRef &buffer, const RawData &rawData); + + /// Allocates a buffer using #Allocator and initializes it with the contents + /// of the container \p rawData, then stores it in \p buffer. + /// + /// \p buffer is passed as an argument rather than returned so that the + /// element type can be inferred. + template + void allocateBuffer(ArrayRef &buffer, const RawData &rawData) { + assert(buffer.empty()); + MutableArrayRef result; + allocateBuffer(result, rawData); + buffer = result; + } + + /// Decls referenced by this module. + ArrayRef Decls; + + /// Local DeclContexts referenced by this module. + ArrayRef LocalDeclContexts; + + /// Normal protocol conformances referenced by this module. + ArrayRef NormalConformances; + + /// SILLayouts referenced by this module. + ArrayRef SILLayouts; + + /// Types referenced by this module. + ArrayRef Types; + + /// Clang types referenced by this module. + ArrayRef ClangTypes; + + /// Generic signatures referenced by this module. + ArrayRef GenericSignatures; + + /// Substitution maps referenced by this module. + ArrayRef SubstitutionMaps; + + /// Identifiers referenced by this module. + ArrayRef Identifiers; + + class DeclTableInfo; + using SerializedDeclTable = + llvm::OnDiskIterableChainedHashTable; + + class ExtensionTableInfo; + using SerializedExtensionTable = + llvm::OnDiskIterableChainedHashTable; + + class LocalDeclTableInfo; + using SerializedLocalDeclTable = + llvm::OnDiskIterableChainedHashTable; + + using OpaqueReturnTypeDeclTableInfo = LocalDeclTableInfo; + using SerializedOpaqueReturnTypeDeclTable = + llvm::OnDiskIterableChainedHashTable; + + class NestedTypeDeclsTableInfo; + using SerializedNestedTypeDeclsTable = + llvm::OnDiskIterableChainedHashTable; + + class DeclMemberNamesTableInfo; + using SerializedDeclMemberNamesTable = + llvm::OnDiskIterableChainedHashTable; + + class DeclMembersTableInfo; + using SerializedDeclMembersTable = + llvm::OnDiskIterableChainedHashTable; + + std::unique_ptr TopLevelDecls; + std::unique_ptr OperatorDecls; + std::unique_ptr PrecedenceGroupDecls; + std::unique_ptr ClassMembersForDynamicLookup; + std::unique_ptr OperatorMethodDecls; + std::unique_ptr ExtensionDecls; + std::unique_ptr LocalTypeDecls; + std::unique_ptr OpaqueReturnTypeDecls; + std::unique_ptr NestedTypeDecls; + std::unique_ptr DeclMemberNames; + + class ObjCMethodTableInfo; + using SerializedObjCMethodTable = + llvm::OnDiskIterableChainedHashTable; + + std::unique_ptr ObjCMethods; + + ArrayRef OrderedTopLevelDecls; + + class DeclCommentTableInfo; + using SerializedDeclCommentTable = + llvm::OnDiskIterableChainedHashTable; + struct DeserializedCommentInfo; + + using GroupNameTable = const llvm::DenseMap; + + std::unique_ptr GroupNamesMap; + std::unique_ptr DeclCommentTable; + + class DeclUSRTableInfo; + using SerializedDeclUSRTable = + llvm::OnDiskIterableChainedHashTable; + std::unique_ptr DeclUSRsTable; + + class DerivativeFunctionConfigTableInfo; + using SerializedDerivativeFunctionConfigTable = + llvm::OnDiskIterableChainedHashTable; + std::unique_ptr + DerivativeFunctionConfigurations; + + /// A blob of 0 terminated string segments referenced in \c SourceLocsTextData + StringRef SourceLocsTextData; + + /// An array of fixed size source location data for each USR appearing in + /// \c DeclUSRsTable. + StringRef BasicDeclLocsData; + + /// An array of fixed-size location data for each `SingleRawComment` piece + /// of declaration's documentation `RawComment`s. + StringRef DocRangesData; + + struct ModuleBits { + /// The decl ID of the main class in this module file, if it has one. + unsigned EntryPointDeclID : 31; + + /// Whether or not this module file comes from a context that had a main + /// entry point. + unsigned HasEntryPoint : 1; + + /// Whether this module file comes from a framework. + unsigned IsFramework : 1; + + /// Whether an error has been detected setting up this module file. + unsigned HasError : 1; + + // Explicitly pad out to the next word boundary. + unsigned : 0; + } Bits = {}; + static_assert(sizeof(ModuleBits) <= 8, "The bit set should be small"); + + bool hasError() const { + return Bits.HasError; + } + + void setEntryPointClassID(serialization::DeclID DID) { + Bits.HasEntryPoint = true; + Bits.EntryPointDeclID = DID; + assert(Bits.EntryPointDeclID == DID && "not enough bits for DeclID"); + } + + /// Constructs a new module and validates it. + ModuleFileSharedCore(std::unique_ptr moduleInputBuffer, + std::unique_ptr moduleDocInputBuffer, + std::unique_ptr moduleSourceInfoInputBuffer, + bool isFramework, serialization::ValidationInfo &info, + serialization::ExtendedValidationInfo *extInfo); + + /// Change the status of the current module. + Status error(Status issue) { + assert(issue != Status::Valid); + Bits.HasError = true; + return issue; + } + + /// Emits one last diagnostic, logs the error, and then aborts for the stack + /// trace. + LLVM_ATTRIBUTE_NORETURN static void fatal(llvm::Error error); + void fatalIfNotSuccess(llvm::Error error) { + if (error) + fatal(std::move(error)); + } + template T fatalIfUnexpected(llvm::Expected expected) { + if (expected) + return std::move(expected.get()); + fatal(expected.takeError()); + } + + /// Read an on-disk decl hash table stored in index_block::DeclListLayout + /// format. + std::unique_ptr + readDeclTable(ArrayRef fields, StringRef blobData) const; + + /// Read an on-disk local decl hash table stored in + /// index_block::DeclListLayout format. + std::unique_ptr + readLocalDeclTable(ArrayRef fields, StringRef blobData) const; + + /// Read an on-disk Objective-C method table stored in + /// index_block::ObjCMethodTableLayout format. + std::unique_ptr + readObjCMethodTable(ArrayRef fields, StringRef blobData) const; + + /// Read an on-disk local decl hash table stored in + /// index_block::ExtensionTableLayout format. + std::unique_ptr + readExtensionTable(ArrayRef fields, StringRef blobData) const; + + /// Read an on-disk local decl hash table stored in + /// index_block::NestedTypeDeclsLayout format. + std::unique_ptr + readNestedTypeDeclsTable(ArrayRef fields, StringRef blobData) const; + + /// Read an on-disk local decl-name hash table stored in + /// index_block::DeclMemberNamesLayout format. + std::unique_ptr + readDeclMemberNamesTable(ArrayRef fields, StringRef blobData) const; + + /// Read an on-disk local decl-members hash table stored in + /// index_block::DeclMembersLayout format. + std::unique_ptr + readDeclMembersTable(ArrayRef fields, StringRef blobData) const; + + /// Read an on-disk derivative function configuration table stored in + /// index_block::DerivativeFunctionConfigTableLayout format. + std::unique_ptr + readDerivativeFunctionConfigTable(ArrayRef fields, + StringRef blobData) const; + + /// Reads the index block, which contains global tables. + /// + /// Returns false if there was an error. + bool readIndexBlock(llvm::BitstreamCursor &cursor); + + /// Read an on-disk decl hash table stored in + /// \c comment_block::DeclCommentListLayout format. + std::unique_ptr + readDeclCommentTable(ArrayRef fields, StringRef blobData) const; + + std::unique_ptr + readGroupTable(ArrayRef fields, StringRef blobData) const; + + /// Reads the comment block, which contains USR to comment mappings. + /// + /// Returns false if there was an error. + bool readCommentBlock(llvm::BitstreamCursor &cursor); + + /// Loads data from #ModuleDocInputBuffer. + /// + /// Returns false if there was an error. + bool readModuleDocIfPresent(); + + /// Reads the source loc block, which contains USR to decl location mapping. + /// + /// Returns false if there was an error. + bool readDeclLocsBlock(llvm::BitstreamCursor &cursor); + + /// Loads data from #ModuleSourceInfoInputBuffer. + /// + /// Returns false if there was an error. + bool readModuleSourceInfoIfPresent(); + + /// Read an on-disk decl hash table stored in + /// \c sourceinfo_block::DeclUSRSLayout format. + std::unique_ptr + readDeclUSRsTable(ArrayRef fields, StringRef blobData) const; + + /// Returns the appropriate module name for the given ID. + StringRef getModuleNameFromID(serialization::ModuleID MID) const; + + /// Convenience method to retrieve the text of the name with the given ID. + /// Asserts that the name with this ID is not special. + StringRef getIdentifierText(serialization::IdentifierID IID) const; + +public: + /// Loads a module from the given memory buffer. + /// + /// \param moduleInputBuffer A memory buffer containing the serialized module + /// data. The created ModuleFile takes ownership of the buffer, even if + /// there's an error in loading. + /// \param moduleDocInputBuffer An optional memory buffer containing + /// documentation data for the module. The created ModuleFile takes ownership + /// of the buffer, even if there's an error in loading. + /// \param isFramework If true, this is treated as a framework module for + /// linking purposes. + /// \param[out] theModule The loaded module. + /// \param[out] extInfo Optionally, extra info serialized about the module. + /// \returns Whether the module was successfully loaded, or what went wrong + /// if it was not. + static serialization::ValidationInfo + load(StringRef moduleInterfacePath, + std::unique_ptr moduleInputBuffer, + std::unique_ptr moduleDocInputBuffer, + std::unique_ptr moduleSourceInfoInputBuffer, + bool isFramework, std::shared_ptr &theModule, + serialization::ExtendedValidationInfo *extInfo = nullptr) { + serialization::ValidationInfo info; + auto *core = new ModuleFileSharedCore( + std::move(moduleInputBuffer), std::move(moduleDocInputBuffer), + std::move(moduleSourceInfoInputBuffer), isFramework, info, extInfo); + if (!moduleInterfacePath.empty()) + core->ModuleInterfacePath = moduleInterfacePath; + theModule.reset(core); + return info; + } + + // Out of line to avoid instantiation OnDiskChainedHashTable here. + ~ModuleFileSharedCore(); + + /// The name of the module. + StringRef getName() const { + return Name; + } + + /// Returns the list of modules this module depends on. + ArrayRef getDependencies() const { + return Dependencies; + } +}; + +template +void ModuleFileSharedCore::allocateBuffer(MutableArrayRef &buffer, + const RawData &rawData) { + assert(buffer.empty() && "reallocating deserialized buffer"); + if (rawData.empty()) + return; + + void *rawBuffer = Allocator.Allocate(sizeof(T) * rawData.size(), alignof(T)); + buffer = llvm::makeMutableArrayRef(static_cast(rawBuffer), + rawData.size()); + std::uninitialized_copy(rawData.begin(), rawData.end(), buffer.begin()); +} + +} // end namespace swift + +#endif diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index a746312e141cc..3aded479fe5e2 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -12,6 +12,7 @@ #include "swift/Serialization/SerializedModuleLoader.h" #include "ModuleFile.h" +#include "ModuleFileSharedCore.h" #include "swift/AST/ASTContext.h" #include "swift/AST/DiagnosticsSema.h" #include "swift/AST/ModuleDependencies.h" @@ -364,11 +365,11 @@ llvm::ErrorOr SerializedModuleLoaderBase::scanModuleFile( return moduleBuf.getError(); // Load the module file without validation. - std::unique_ptr loadedModuleFile; + std::shared_ptr loadedModuleFile; bool isFramework = false; serialization::ExtendedValidationInfo extInfo; serialization::ValidationInfo loadInfo = - ModuleFile::load(modulePath.str(), + ModuleFileSharedCore::load(modulePath.str(), std::move(moduleBuf.get()), nullptr, nullptr, @@ -675,14 +676,17 @@ FileUnit *SerializedModuleLoaderBase::loadAST( serialization::ExtendedValidationInfo extendedInfo; std::unique_ptr loadedModuleFile; + std::shared_ptr loadedModuleFileCore; serialization::ValidationInfo loadInfo = - ModuleFile::load(moduleInterfacePath, + ModuleFileSharedCore::load(moduleInterfacePath, std::move(moduleInputBuffer), std::move(moduleDocInputBuffer), std::move(moduleSourceInfoInputBuffer), - isFramework, loadedModuleFile, + isFramework, loadedModuleFileCore, &extendedInfo); if (loadInfo.status == serialization::Status::Valid) { + loadedModuleFile = + std::make_unique(std::move(loadedModuleFileCore)); M.setResilienceStrategy(extendedInfo.getResilienceStrategy()); // We've loaded the file. Now try to bring it into the AST. @@ -717,16 +721,19 @@ FileUnit *SerializedModuleLoaderBase::loadAST( // From here on is the failure path. - // Even though the module failed to load, it's possible its contents include - // a source buffer that need to survive because it's already been used for - // diagnostics. - if (auto orphanedBuffer = loadedModuleFile->takeBufferForDiagnostics()) - OrphanedMemoryBuffers.push_back(std::move(orphanedBuffer)); - if (diagLoc) serialization::diagnoseSerializedASTLoadFailure( Ctx, *diagLoc, loadInfo, extendedInfo, moduleBufferID, moduleDocBufferID, loadedModuleFile.get(), M.getName()); + + // Even though the module failed to load, it's possible its contents include + // a source buffer that need to survive because it's already been used for + // diagnostics. + // Note this is only necessary in case a bridging header failed to load + // during the `associateWithFileContext()` call. + if (loadedModuleFile && loadedModuleFile->mayHaveDiagnosticsPointingAtBuffer()) + OrphanedModuleFiles.push_back(std::move(loadedModuleFile)); + return nullptr; } @@ -794,20 +801,20 @@ void swift::serialization::diagnoseSerializedASTLoadFailure( Ctx.LangOpts.DebuggerSupport)) { return false; } - return duplicates.insert(dependency.RawPath).second; + return duplicates.insert(dependency.Core.RawPath).second; }); // FIXME: only show module part of RawAccessPath assert(!missing.empty() && "unknown missing dependency?"); if (missing.size() == 1) { Ctx.Diags.diagnose(diagLoc, diag::serialization_missing_single_dependency, - missing.front().getPrettyPrintedPath()); + missing.front().Core.getPrettyPrintedPath()); } else { llvm::SmallString<64> missingNames; missingNames += '\''; interleave(missing, [&](const ModuleFile::Dependency &next) { - missingNames += next.getPrettyPrintedPath(); + missingNames += next.Core.getPrettyPrintedPath(); }, [&] { missingNames += "', '"; }); missingNames += '\''; @@ -841,7 +848,7 @@ void swift::serialization::diagnoseSerializedASTLoadFailure( // hard because we're discovering this /while/ resolving imports, which // means the problematic modules haven't been recorded yet. Ctx.Diags.diagnose(diagLoc, diag::serialization_circular_dependency, - circularDependencyIter->getPrettyPrintedPath(), + circularDependencyIter->Core.getPrettyPrintedPath(), ModuleName); break; } @@ -1106,7 +1113,7 @@ void SerializedASTFile::collectLinkLibraries( } bool SerializedASTFile::isSIB() const { - return File.IsSIB; + return File.isSIB(); } bool SerializedASTFile::hadLoadError() const { diff --git a/stdlib/public/runtime/Private.h b/stdlib/public/runtime/Private.h index d337409524f37..21c8e2906f104 100644 --- a/stdlib/public/runtime/Private.h +++ b/stdlib/public/runtime/Private.h @@ -103,7 +103,8 @@ class TypeInfo { // value here. # define SWIFT_ISA_MASK 0xfffffffffffffff8ULL # elif __arm64__ -# if __has_feature(ptrauth_calls) +// ARM64 simulators always use the ARM64e mask. +# if __has_feature(ptrauth_calls) || TARGET_OS_SIMULATOR # define SWIFT_ISA_MASK 0x007ffffffffffff8ULL # else # if TARGET_OS_OSX diff --git a/test/Constraints/operator.swift b/test/Constraints/operator.swift index 4be7e87ba780e..cfb249e6e3722 100644 --- a/test/Constraints/operator.swift +++ b/test/Constraints/operator.swift @@ -293,3 +293,9 @@ func rdar_62054241() { // expected-note@-1 {{found candidate with type '(Foo, Foo) -> Bool'}} } } + +// SR-11399 - Operator returning IUO doesn't implicitly unwrap +postfix operator ^^^ +postfix func ^^^ (lhs: Int) -> Int! { 0 } + +let x: Int = 1^^^ diff --git a/test/IRGen/abitypes.swift b/test/IRGen/abitypes.swift index 0158278f8a8f7..e62790d288d3c 100644 --- a/test/IRGen/abitypes.swift +++ b/test/IRGen/abitypes.swift @@ -17,7 +17,7 @@ import Foundation // arm64e-ios: [[ARM64E_MYRECT:%.*]] = type { float, float, float, float } // arm64-tvos: [[ARM64_MYRECT:%.*]] = type { float, float, float, float } // armv7k-watchos: [[ARMV7K_MYRECT:%.*]] = type { float, float, float, float } -// arm64-macosx: [[ARM64E_MYRECT:%.*]] = type { float, float, float, float } +// arm64-macosx: [[ARM64_MYRECT:%.*]] = type { float, float, float, float } class Foo { // x86_64-macosx: define hidden swiftcc { float, float, float, float } @"$s8abitypes3FooC3bar{{[_0-9a-zA-Z]*}}F"(%T8abitypes3FooC* swiftself %0) {{.*}} { diff --git a/test/Interop/Cxx/operators/Inputs/member-out-of-line.cpp b/test/Interop/Cxx/operators/Inputs/member-out-of-line.cpp new file mode 100644 index 0000000000000..339c9f906c254 --- /dev/null +++ b/test/Interop/Cxx/operators/Inputs/member-out-of-line.cpp @@ -0,0 +1,5 @@ +#include "member-out-of-line.h" + +IntBox IntBox::operator+(IntBox rhs) const { + return IntBox{.value = value + rhs.value}; +} diff --git a/test/Interop/Cxx/operators/Inputs/member-out-of-line.h b/test/Interop/Cxx/operators/Inputs/member-out-of-line.h new file mode 100644 index 0000000000000..e0fd1262467a5 --- /dev/null +++ b/test/Interop/Cxx/operators/Inputs/member-out-of-line.h @@ -0,0 +1,9 @@ +#ifndef TEST_INTEROP_CXX_OPERATORS_INPUTS_MEMBER_OUT_OF_LINE_H +#define TEST_INTEROP_CXX_OPERATORS_INPUTS_MEMBER_OUT_OF_LINE_H + +struct IntBox { + int value; + IntBox operator+(IntBox rhs) const; +}; + +#endif diff --git a/test/Interop/Cxx/operators/Inputs/module.modulemap b/test/Interop/Cxx/operators/Inputs/module.modulemap index a811dbe61fa0e..53d2dd71feb62 100644 --- a/test/Interop/Cxx/operators/Inputs/module.modulemap +++ b/test/Interop/Cxx/operators/Inputs/module.modulemap @@ -2,6 +2,10 @@ module MemberInline { header "member-inline.h" } +module MemberOutOfLine { + header "member-out-of-line.h" +} + module NonMemberInline { header "non-member-inline.h" } diff --git a/test/Interop/Cxx/operators/member-out-of-line-irgen.swift b/test/Interop/Cxx/operators/member-out-of-line-irgen.swift new file mode 100644 index 0000000000000..7dd42207629df --- /dev/null +++ b/test/Interop/Cxx/operators/member-out-of-line-irgen.swift @@ -0,0 +1,11 @@ +// RUN: %target-swift-emit-ir %s -I %S/Inputs -enable-cxx-interop | %FileCheck %s +// +// We can't yet call member functions correctly on Windows (SR-13129). +// XFAIL: OS=windows-msvc + +import MemberOutOfLine + +public func add(_ lhs: inout IntBox, _ rhs: IntBox) -> IntBox { lhs + rhs } + +// CHECK: call {{i32|i64}} [[NAME:@_ZNK6IntBoxplES_]](%struct.IntBox* %{{[0-9]+}}, {{i32|\[1 x i32\]|i64|%struct.IntBox\* byval align 4}} %{{[0-9]+}}) +// CHECK: declare {{(dso_local )?}}{{i32|i64}} [[NAME]](%struct.IntBox*, {{i32|\[1 x i32\]|i64|%struct.IntBox\* byval\(%struct.IntBox\) align 4}}) diff --git a/test/Interop/Cxx/operators/member-out-of-line-silgen.swift b/test/Interop/Cxx/operators/member-out-of-line-silgen.swift new file mode 100644 index 0000000000000..a3aa540ddc18d --- /dev/null +++ b/test/Interop/Cxx/operators/member-out-of-line-silgen.swift @@ -0,0 +1,16 @@ +// RUN: %target-swift-emit-sil %s -I %S/Inputs -enable-cxx-interop | %FileCheck %s +// +// We can't yet call member functions correctly on Windows (SR-13129). +// XFAIL: OS=windows-msvc + +import MemberOutOfLine + +public func add(_ lhs: inout IntBox, _ rhs: IntBox) -> IntBox { lhs + rhs } + +// CHECK: bb0([[LHS:%.*]] : $*IntBox, [[RHS:%.*]] : $IntBox): +// CHECK: [[ACCESS:%.*]] = begin_access [modify] [static] [[LHS]] : $*IntBox +// CHECK: [[FUNC:%.*]] = function_ref [[NAME:@_ZNK6IntBoxplES_]] : $@convention(c) (@inout IntBox, IntBox) -> IntBox +// CHECK: apply [[FUNC]]([[ACCESS]], [[RHS]]) : $@convention(c) (@inout IntBox, IntBox) -> IntBox +// CHECK: end_access [[ACCESS]] : $*IntBox + +// CHECK: sil [clang IntBox."+"] [[NAME]] : $@convention(c) (@inout IntBox, IntBox) -> IntBox diff --git a/test/Interop/Cxx/operators/member-out-of-line.swift b/test/Interop/Cxx/operators/member-out-of-line.swift new file mode 100644 index 0000000000000..7cbc313a495bb --- /dev/null +++ b/test/Interop/Cxx/operators/member-out-of-line.swift @@ -0,0 +1,26 @@ +// RUN: %empty-directory(%t) +// RUN: %target-clang -c %S/Inputs/member-out-of-line.cpp -I %S/Inputs -o %t/member-out-of-line.o -std=c++17 +// RUN: %target-build-swift %s -I %S/Inputs -o %t/member-out-of-line %t/member-out-of-line.o -Xfrontend -enable-cxx-interop +// RUN: %target-codesign %t/member-out-of-line +// RUN: %target-run %t/member-out-of-line +// +// REQUIRES: executable_test +// +// We can't yet call member functions correctly on Windows (SR-13129). +// XFAIL: OS=windows-msvc + +import MemberOutOfLine +import StdlibUnittest + +var OperatorsTestSuite = TestSuite("Operators") + +OperatorsTestSuite.test("plus") { + var lhs = IntBox(value: 42) + let rhs = IntBox(value: 23) + + let result = lhs + rhs + + expectEqual(65, result.value) +} + +runAllTests() diff --git a/test/SILOptimizer/globalopt_ossa.sil b/test/SILOptimizer/globalopt_ossa.sil new file mode 100644 index 0000000000000..43b946993d734 --- /dev/null +++ b/test/SILOptimizer/globalopt_ossa.sil @@ -0,0 +1,55 @@ +// RUN: %target-sil-opt -enable-sil-verify-all %s -global-opt | %FileCheck %s + +sil_stage canonical + +import Builtin +import Swift + +private var testGlobal: Int64 + +sil_global private @globalinit_33_00F4D2139E6BDDFEC71E5005B67B5674_token0 : $Builtin.Word + +sil_global private @$s4test10testGlobalSivp : $Int64 + +sil private [ossa] @globalinit_33_00F4D2139E6BDDFEC71E5005B67B5674_func0 : $@convention(c) () -> () { +bb0: + alloc_global @$s4test10testGlobalSivp + %1 = global_addr @$s4test10testGlobalSivp : $*Int64 + %2 = integer_literal $Builtin.Int64, 27 + %3 = struct $Int64 (%2 : $Builtin.Int64) + store %3 to [trivial] %1 : $*Int64 + %5 = tuple () + return %5 : $() +} + +sil hidden [global_init] [ossa] @$s4test10testGlobalSivau : $@convention(thin) () -> Builtin.RawPointer { +bb0: + %0 = global_addr @globalinit_33_00F4D2139E6BDDFEC71E5005B67B5674_token0 : $*Builtin.Word + %1 = address_to_pointer %0 : $*Builtin.Word to $Builtin.RawPointer + %2 = function_ref @globalinit_33_00F4D2139E6BDDFEC71E5005B67B5674_func0 : $@convention(c) () -> () + %3 = builtin "once"(%1 : $Builtin.RawPointer, %2 : $@convention(c) () -> ()) : $() + %4 = global_addr @$s4test10testGlobalSivp : $*Int64 + %5 = address_to_pointer %4 : $*Int64 to $Builtin.RawPointer + return %5 : $Builtin.RawPointer +} + +// CHECK-LABEL: sil [ossa] @dont_propagate_global_with_multiple_writes +// CHECK: [[V:%[0-9]+]] = load +// CHECK: return [[V]] +// CHECK: } // end sil function 'dont_propagate_global_with_multiple_writes' +sil [ossa] @dont_propagate_global_with_multiple_writes : $@convention(thin) (Int64) -> Int64 { +bb0(%0 : $Int64): + %2 = function_ref @$s4test10testGlobalSivau : $@convention(thin) () -> Builtin.RawPointer + %3 = apply %2() : $@convention(thin) () -> Builtin.RawPointer + %4 = pointer_to_address %3 : $Builtin.RawPointer to [strict] $*Int64 + %5 = integer_literal $Builtin.Int64, 42 + %6 = struct $Int64 (%5 : $Builtin.Int64) + %7 = begin_access [modify] [dynamic] [no_nested_conflict] %4 : $*Int64 + store %6 to [trivial] %7 : $*Int64 + end_access %7 : $*Int64 + %33 = begin_access [read] [dynamic] [no_nested_conflict] %4 : $*Int64 + %35 = load [trivial] %33 : $*Int64 + end_access %33 : $*Int64 + return %35 : $Int64 +} + diff --git a/test/SILOptimizer/globalopt_trivial_nontrivial.sil b/test/SILOptimizer/globalopt_trivial_nontrivial.sil new file mode 100644 index 0000000000000..3625c10946211 --- /dev/null +++ b/test/SILOptimizer/globalopt_trivial_nontrivial.sil @@ -0,0 +1,133 @@ +// RUN: %target-sil-opt -enable-sil-verify-all %s -global-opt | %FileCheck %s + +// This tests GlobalOpt of a trivial global variable +// Loads of trivial global variable initialized with a constant is replaced with the constant in GlobalOpt +// This also tests GlobalOpt to be a no-op for a non-trivial global variable used in the same way +// The difference in GlobalOpt for trivial v/s non-trivial values is shown in $bartrivial and $barnontrivial + +sil_stage canonical + +import Builtin +import Swift +import SwiftShims + +public struct TStruct { + let x: Int32 + init(x: Int32) +} + +let trivialglobal: TStruct + +public class TClass { + final let x: Int32 + init(x: Int32) + deinit +} + +let nontrivialglobal: TClass + +// CHECK-LABEL: sil_global hidden [let] @$trivialglobal : $TStruct = { +// CHECK: [[CONST:%.*]] = integer_literal $Builtin.Int32, 10 +// CHECK: [[INT:%.*]] = struct $Int32 ([[CONST]] : $Builtin.Int32) +// CHECK: %initval = struct $TStruct ([[INT]] : $Int32) +sil_global private @globalinit_trivialglobal_token : $Builtin.Word + +sil_global hidden [let] @$trivialglobal : $TStruct + +sil_global private @globalinit_nontrivialglobal_token : $Builtin.Word + +sil_global hidden [let] @$nontrivialglobal : $TClass + +sil private @globalinit_trivialglobal_func : $@convention(c) () -> () { +bb0: + alloc_global @$trivialglobal + %1 = global_addr @$trivialglobal : $*TStruct + %2 = integer_literal $Builtin.Int32, 10 + %3 = struct $Int32 (%2 : $Builtin.Int32) + %4 = struct $TStruct (%3 : $Int32) + store %4 to %1 : $*TStruct + %6 = tuple () + return %6 : $() +} + +// CHECK-LABEL: sil hidden [global_init] @$trivialglobal_unsafemutableaddressor : +// CHECK: [[GLOBL:%.*]] = global_addr @$trivialglobal : $*TStruct +// CHECK: [[GLOBL_ADDR:%.*]] = address_to_pointer [[GLOBL]] : $*TStruct to $Builtin.RawPointer +// CHECK: return [[GLOBL_ADDR]] : $Builtin.RawPointer +// CHECK: } // end sil function '$trivialglobal_unsafemutableaddressor' +sil hidden [global_init] @$trivialglobal_unsafemutableaddressor : $@convention(thin) () -> Builtin.RawPointer { +bb0: + %0 = global_addr @globalinit_trivialglobal_token : $*Builtin.Word + %1 = address_to_pointer %0 : $*Builtin.Word to $Builtin.RawPointer + %2 = function_ref @globalinit_trivialglobal_func : $@convention(c) () -> () + %3 = builtin "once"(%1 : $Builtin.RawPointer, %2 : $@convention(c) () -> ()) : $() + %4 = global_addr @$trivialglobal : $*TStruct + %5 = address_to_pointer %4 : $*TStruct to $Builtin.RawPointer + return %5 : $Builtin.RawPointer +} + +// $bartrivial's access to the trivial global variable via the accessor is optimized to the rhs of the init value + +// CHECK-LABEL: sil hidden [noinline] @$bartrivial : +// CHECK: [[CONST:%.*]] = integer_literal $Builtin.Int32, 10 +// CHECK: [[INT:%.*]] = struct $Int32 ([[CONST]] : $Builtin.Int32) +// CHECK: return [[INT]] : $Int32 +// CHECK-LABEL: } // end sil function '$bartrivial' +sil hidden [noinline] @$bartrivial : $@convention(thin) () -> Int32 { +bb0: + %0 = function_ref @$trivialglobal_unsafemutableaddressor : $@convention(thin) () -> Builtin.RawPointer + %1 = apply %0() : $@convention(thin) () -> Builtin.RawPointer + %2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*TStruct + %3 = struct_element_addr %2 : $*TStruct, #TStruct.x + %4 = load %3 : $*Int32 + return %4 : $Int32 +} + +// CHECK-LABEL: sil private @globalinit_nontrivialglobal_func : +// CHECK: alloc_global @$nontrivialglobal +// CHECK: [[GLOBL_ADDR:%.*]] = global_addr @$nontrivialglobal : $*TClass +// CHECK: [[REF:%.*]] = alloc_ref $TClass +// CHECK: store [[REF]] to [[GLOBL_ADDR]] : $*TClass +// CHECK: } // end sil function 'globalinit_nontrivialglobal_func' +sil private @globalinit_nontrivialglobal_func : $@convention(c) () -> () { +bb0: + alloc_global @$nontrivialglobal + %1 = global_addr @$nontrivialglobal : $*TClass + %2 = integer_literal $Builtin.Int32, 10 + %3 = struct $Int32 (%2 : $Builtin.Int32) + %4 = alloc_ref $TClass + %7 = ref_element_addr %4 : $TClass, #TClass.x + store %3 to %7 : $*Int32 + store %4 to %1 : $*TClass + %10 = tuple () + return %10 : $() +} + +sil hidden [global_init] @$nontrivialglobal_unsafemutableaccessor : $@convention(thin) () -> Builtin.RawPointer { +bb0: + %0 = global_addr @globalinit_nontrivialglobal_token : $*Builtin.Word + %1 = address_to_pointer %0 : $*Builtin.Word to $Builtin.RawPointer + %2 = function_ref @globalinit_nontrivialglobal_func : $@convention(c) () -> () + %3 = builtin "once"(%1 : $Builtin.RawPointer, %2 : $@convention(c) () -> ()) : $() + %4 = global_addr @$nontrivialglobal : $*TClass + %5 = address_to_pointer %4 : $*TClass to $Builtin.RawPointer + return %5 : $Builtin.RawPointer +} + +// $barnontrivial's access to the non-trivial global variable does not get optimized away + +// CHECK-LABEL: sil hidden [noinline] @$barnontrivial : +// CHECK: [[FUNC_REF:%.*]] = function_ref @$nontrivialglobal_unsafemutableaccessor : +// CHECK: [[APPLY:%.*]] = apply [[FUNC_REF]]() : +// CHECK-LABEL: } // end sil function '$barnontrivial' +sil hidden [noinline] @$barnontrivial : $@convention(thin) () -> Int32 { +bb0: + %0 = function_ref @$nontrivialglobal_unsafemutableaccessor : $@convention(thin) () -> Builtin.RawPointer + %1 = apply %0() : $@convention(thin) () -> Builtin.RawPointer + %2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*TClass + %3 = load %2 : $*TClass + %4 = ref_element_addr %3 : $TClass, #TClass.x + %5 = load %4 : $*Int32 + return %5 : $Int32 +} + diff --git a/test/SILOptimizer/globalopt_trivial_nontrivial_ossa.sil b/test/SILOptimizer/globalopt_trivial_nontrivial_ossa.sil new file mode 100644 index 0000000000000..182210cb2671e --- /dev/null +++ b/test/SILOptimizer/globalopt_trivial_nontrivial_ossa.sil @@ -0,0 +1,128 @@ +// RUN: %target-sil-opt -enable-sil-verify-all %s -global-opt | %FileCheck %s +sil_stage canonical + +import Builtin +import Swift +import SwiftShims + +public struct TStruct { + let x: Int32 + init(x: Int32) +} + +let trivialglobal: TStruct + +public class TClass { + final let x: Int32 + init(x: Int32) + deinit +} + +let nontrivialglobal: TClass + +// CHECK-LABEL: sil_global hidden [let] @$trivialglobal : $TStruct = { +// CHECK: [[CONST:%.*]] = integer_literal $Builtin.Int32, 10 +// CHECK: [[INT:%.*]] = struct $Int32 ([[CONST]] : $Builtin.Int32) +// CHECK: %initval = struct $TStruct ([[INT]] : $Int32) +sil_global private @globalinit_trivialglobal_token : $Builtin.Word + +sil_global hidden [let] @$trivialglobal : $TStruct + +sil_global private @globalinit_nontrivialglobal_token : $Builtin.Word + +sil_global hidden [let] @$nontrivialglobal : $TClass + +sil private [ossa] @globalinit_trivialglobal_func : $@convention(c) () -> () { +bb0: + alloc_global @$trivialglobal + %1 = global_addr @$trivialglobal : $*TStruct + %2 = integer_literal $Builtin.Int32, 10 + %3 = struct $Int32 (%2 : $Builtin.Int32) + %4 = struct $TStruct (%3 : $Int32) + store %4 to [trivial] %1 : $*TStruct + %6 = tuple () + return %6 : $() +} + +// CHECK-LABEL: sil hidden [global_init] [ossa] @$trivialglobal_unsafemutableaddressor : +// CHECK: [[GLOBL:%.*]] = global_addr @$trivialglobal : $*TStruct +// CHECK: [[GLOBL_ADDR:%.*]] = address_to_pointer [[GLOBL]] : $*TStruct to $Builtin.RawPointer +// CHECK: return [[GLOBL_ADDR]] : $Builtin.RawPointer +// CHECK: } // end sil function '$trivialglobal_unsafemutableaddressor' +sil hidden [global_init] [ossa] @$trivialglobal_unsafemutableaddressor : $@convention(thin) () -> Builtin.RawPointer { +bb0: + %0 = global_addr @globalinit_trivialglobal_token : $*Builtin.Word + %1 = address_to_pointer %0 : $*Builtin.Word to $Builtin.RawPointer + %2 = function_ref @globalinit_trivialglobal_func : $@convention(c) () -> () + %3 = builtin "once"(%1 : $Builtin.RawPointer, %2 : $@convention(c) () -> ()) : $() + %4 = global_addr @$trivialglobal : $*TStruct + %5 = address_to_pointer %4 : $*TStruct to $Builtin.RawPointer + return %5 : $Builtin.RawPointer +} + +// CHECK-LABEL: sil hidden [noinline] [ossa] @$bartrivial : +// CHECK: [[CONST:%.*]] = integer_literal $Builtin.Int32, 10 +// CHECK: [[INT:%.*]] = struct $Int32 ([[CONST]] : $Builtin.Int32) +// CHECK: return [[INT]] : $Int32 +// CHECK-LABEL: } // end sil function '$bartrivial' +sil hidden [noinline] [ossa] @$bartrivial : $@convention(thin) () -> Int32 { +bb0: + %0 = function_ref @$trivialglobal_unsafemutableaddressor : $@convention(thin) () -> Builtin.RawPointer + %1 = apply %0() : $@convention(thin) () -> Builtin.RawPointer + %2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*TStruct + %3 = struct_element_addr %2 : $*TStruct, #TStruct.x + %4 = load [trivial] %3 : $*Int32 + return %4 : $Int32 +} + +// CHECK-LABEL: sil private [ossa] @globalinit_nontrivialglobal_func : +// CHECK: alloc_global @$nontrivialglobal +// CHECK: [[GLOBL_ADDR:%.*]] = global_addr @$nontrivialglobal : $*TClass +// CHECK: [[REF:%.*]] = alloc_ref $TClass +// CHECK: store [[REF]] to [init] [[GLOBL_ADDR]] : $*TClass +// CHECK: } // end sil function 'globalinit_nontrivialglobal_func' +sil private [ossa] @globalinit_nontrivialglobal_func : $@convention(c) () -> () { +bb0: + alloc_global @$nontrivialglobal + %1 = global_addr @$nontrivialglobal : $*TClass + %2 = integer_literal $Builtin.Int32, 10 + %3 = struct $Int32 (%2 : $Builtin.Int32) + %4 = alloc_ref $TClass + %5 = begin_borrow %4 : $TClass + %6 = ref_element_addr %5 : $TClass, #TClass.x + store %3 to [trivial] %6 : $*Int32 + end_borrow %5 : $TClass + store %4 to [init] %1 : $*TClass + %10 = tuple () + return %10 : $() +} + +sil hidden [global_init] [ossa] @$nontrivialglobal_unsafemutableaccessor : $@convention(thin) () -> Builtin.RawPointer { +bb0: + %0 = global_addr @globalinit_nontrivialglobal_token : $*Builtin.Word + %1 = address_to_pointer %0 : $*Builtin.Word to $Builtin.RawPointer + %2 = function_ref @globalinit_nontrivialglobal_func : $@convention(c) () -> () + %3 = builtin "once"(%1 : $Builtin.RawPointer, %2 : $@convention(c) () -> ()) : $() + %4 = global_addr @$nontrivialglobal : $*TClass + %5 = address_to_pointer %4 : $*TClass to $Builtin.RawPointer + return %5 : $Builtin.RawPointer +} + +// CHECK-LABEL: sil hidden [noinline] [ossa] @$barnontrivial : +// CHECK: [[FUNC_REF:%.*]] = function_ref @$nontrivialglobal_unsafemutableaccessor : +// CHECK: [[APPLY:%.*]] = apply [[FUNC_REF]]() : +// CHECK-LABEL: } // end sil function '$barnontrivial' +sil hidden [noinline] [ossa] @$barnontrivial : $@convention(thin) () -> Int32 { +bb0: + %0 = function_ref @$nontrivialglobal_unsafemutableaccessor : $@convention(thin) () -> Builtin.RawPointer + %1 = apply %0() : $@convention(thin) () -> Builtin.RawPointer + %2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*TClass + %3 = load [copy] %2 : $*TClass + %3b = begin_borrow %3 : $TClass + %4 = ref_element_addr %3b : $TClass, #TClass.x + %5 = load [trivial] %4 : $*Int32 + end_borrow %3b : $TClass + destroy_value %3 : $TClass + return %5 : $Int32 +} + diff --git a/utils/build-script b/utils/build-script index c0493460bc626..043b0df37bc0e 100755 --- a/utils/build-script +++ b/utils/build-script @@ -354,16 +354,15 @@ def apply_default_arguments(toolchain, args): # Filter out any macOS stdlib deployment targets that are not supported # by the macOS SDK. - if platform.system() == "Darwin": - targets = StdlibDeploymentTarget.get_targets_by_name( - args.stdlib_deployment_targets) - args.stdlib_deployment_targets = [ - target.name - for target in targets - if (target.platform.is_darwin and - target.platform.sdk_supports_architecture( - target.arch, args.darwin_xcrun_toolchain)) - ] + targets = StdlibDeploymentTarget.get_targets_by_name( + args.stdlib_deployment_targets) + args.stdlib_deployment_targets = [ + target.name + for target in targets + if (not target.platform.is_darwin or + target.platform.sdk_supports_architecture( + target.arch, args.darwin_xcrun_toolchain)) + ] # Include the Darwin module-only architectures in the CMake options. if args.swift_darwin_module_archs: