Skip to content

Make sure protocol witness errors don't leave the conformance context #16489

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -1498,7 +1498,7 @@ ERROR(witness_argument_name_mismatch,none,
"%select{method|initializer}0 %1 has different argument labels from those "
"required by protocol %2 (%3)", (bool, DeclName, Type, DeclName))
ERROR(witness_initializer_not_required,none,
"initializer requirement %0 can only be satisfied by a `required` "
"initializer requirement %0 can only be satisfied by a 'required' "
"initializer in%select{| the definition of}1 non-final class %2",
(DeclName, bool, Type))
ERROR(witness_initializer_failability,none,
Expand All @@ -1520,12 +1520,12 @@ NOTE(witness_self_weaken_same_type,none,
"consider weakening the same-type requirement %0 == %1 to a superclass "
"requirement", (Type, Type))
ERROR(witness_requires_dynamic_self,none,
"method %0 in non-final class %1 must return `Self` to conform to "
"method %0 in non-final class %1 must return 'Self' to conform to "
"protocol %2",
(DeclName, Type, Type))
ERROR(witness_requires_class_implementation,none,
"method %0 in non-final class %1 cannot be implemented in a "
"protocol extension because it returns `Self` and has associated type "
"protocol extension because it returns 'Self' and has associated type "
"requirements",
(DeclName, Type))
ERROR(witness_not_accessible_proto,none,
Expand Down Expand Up @@ -1553,6 +1553,9 @@ ERROR(type_witness_objc_generic_parameter,none,
"type %0 involving Objective-C type parameter%select{| %1}2 cannot be "
"used for associated type %3 of protocol %4",
(Type, Type, bool, DeclName, DeclName))
NOTE(witness_fix_access,none,
"mark the %0 as '%select{%error|fileprivate|internal|public|%error}1' to "
"satisfy the requirement", (DescriptiveDeclKind, AccessLevel))

ERROR(protocol_refine_access,none,
"%select{protocol must be declared %select{"
Expand Down Expand Up @@ -3395,10 +3398,10 @@ WARNING(objc_inference_swift3_objc_derived,none,
"deprecated", ())

NOTE(objc_inference_swift3_addobjc,none,
"add `@objc` to continue exposing an Objective-C entry point (Swift 3 "
"add '@objc' to continue exposing an Objective-C entry point (Swift 3 "
"behavior)", ())
NOTE(objc_inference_swift3_addnonobjc,none,
"add `@nonobjc` to suppress the Objective-C entry point (Swift 4 "
"add '@nonobjc' to suppress the Objective-C entry point (Swift 4 "
"behavior)", ())

ERROR(objc_for_generic_class,none,
Expand Down Expand Up @@ -3793,9 +3796,6 @@ ERROR(availability_protocol_requires_version,
NOTE(availability_protocol_requirement_here, none,
"protocol requirement here", ())

NOTE(availability_conformance_introduced_here, none,
"conformance introduced here", ())

// This doesn't display as an availability diagnostic, but it's
// implemented there and fires when these subscripts are marked
// unavailable, so it seems appropriate to put it here.
Expand Down
3 changes: 3 additions & 0 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2250,6 +2250,9 @@ bool swift::fixDeclarationName(InFlightDiagnostic &diag, ValueDecl *decl,
bool swift::fixDeclarationObjCName(InFlightDiagnostic &diag, ValueDecl *decl,
Optional<ObjCSelector> targetNameOpt,
bool ignoreImpliedName) {
if (decl->isImplicit())
return false;

// Subscripts cannot be renamed, so handle them directly.
if (isa<SubscriptDecl>(decl)) {
diag.fixItInsert(decl->getAttributeInsertionLoc(/*forModifier=*/false),
Expand Down
3 changes: 3 additions & 0 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2095,6 +2095,9 @@ bool ValueDecl::canInferObjCFromRequirement(ValueDecl *requirement) {
}

SourceLoc ValueDecl::getAttributeInsertionLoc(bool forModifier) const {
if (isImplicit())
return SourceLoc();

if (auto var = dyn_cast<VarDecl>(this)) {
// [attrs] var ...
// The attributes are part of the VarDecl, but the 'var' is part of the PBD.
Expand Down
265 changes: 181 additions & 84 deletions lib/Sema/TypeCheckProtocol.cpp

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions test/ClangImporter/objc_generics_conformance.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ extension GenericClass : WithAssocOther {
typealias Other = [T] // expected-error{{type 'GenericClass<T>.Other' involving Objective-C type parameter 'T' cannot be used for associated type 'Other' of protocol 'WithAssocOther'}}
}

protocol WithAssocSeparate {
associatedtype Separate
}

extension GenericClass {
typealias Separate = T // expected-note {{'Separate' declared here}}
}
extension GenericClass : WithAssocSeparate { // expected-error {{type 'GenericClass<T>.Separate' involving Objective-C type parameter 'T' cannot be used for associated type 'Separate' of protocol 'WithAssocSeparate'}}
}

protocol WithAssocElement {
associatedtype Element
}
Expand Down
69 changes: 37 additions & 32 deletions test/Compatibility/accessibility.swift

Large diffs are not rendered by default.

13 changes: 9 additions & 4 deletions test/Compatibility/accessibility_private.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,21 @@ protocol VeryImportantProto {
}

private struct VIPPrivateType : VeryImportantProto {
private typealias Assoc = Int // expected-error {{type alias 'Assoc' must be as accessible as its enclosing type because it matches a requirement in protocol 'VeryImportantProto'}}
private typealias Assoc = Int // expected-error {{type alias 'Assoc' must be as accessible as its enclosing type because it matches a requirement in protocol 'VeryImportantProto'}} {{none}}
// expected-note@-1 {{mark the type alias as 'fileprivate' to satisfy the requirement}} {{3-10=fileprivate}}
var value: Int
}

private struct VIPPrivateProp : VeryImportantProto {
typealias Assoc = Int
private var value: Int // expected-error {{property 'value' must be as accessible as its enclosing type because it matches a requirement in protocol 'VeryImportantProto'}} {{3-10=fileprivate}}
private var value: Int // expected-error {{property 'value' must be as accessible as its enclosing type because it matches a requirement in protocol 'VeryImportantProto'}} {{none}}
// expected-note@-1 {{mark the var as 'fileprivate' to satisfy the requirement}} {{3-10=fileprivate}}
}

private struct VIPPrivateSetProp : VeryImportantProto {
typealias Assoc = Int
private(set) var value: Int // expected-error {{setter for property 'value' must be as accessible as its enclosing type because it matches a requirement in protocol 'VeryImportantProto'}} {{3-10=fileprivate}}
private(set) var value: Int // expected-error {{setter for property 'value' must be as accessible as its enclosing type because it matches a requirement in protocol 'VeryImportantProto'}} {{none}}
// expected-note@-1 {{mark the var as 'fileprivate' to satisfy the requirement}} {{3-10=fileprivate}}
}

private class VIPPrivateSetBase {
Expand All @@ -140,9 +143,11 @@ private class VIPPrivateSetSub : VIPPrivateSetBase, VeryImportantProto { // expe
}

private class VIPPrivateSetPropBase {
private(set) var value: Int = 0 // expected-error {{setter for property 'value' must be as accessible as its enclosing type because it matches a requirement in protocol 'VeryImportantProto'}} {{3-10=fileprivate}}
private(set) var value: Int = 0
// expected-note@-1 {{mark the var as 'fileprivate' to satisfy the requirement}} {{3-10=fileprivate}}
}
private class VIPPrivateSetPropSub : VIPPrivateSetPropBase, VeryImportantProto {
// expected-error@-1 {{setter for property 'value' must be as accessible as its enclosing type because it matches a requirement in protocol 'VeryImportantProto'}} {{none}}
typealias Assoc = Int
}

Expand Down
9 changes: 6 additions & 3 deletions test/NameBinding/accessibility.swift
Original file line number Diff line number Diff line change
Expand Up @@ -132,19 +132,22 @@ func privateInOtherFile() {}

#if !ACCESS_DISABLED
struct ConformerByTypeAlias : TypeProto {
private typealias TheType = Int // expected-error {{type alias 'TheType' must be declared internal because it matches a requirement in internal protocol 'TypeProto'}} {{3-10=internal}}
private typealias TheType = Int // expected-error {{type alias 'TheType' must be declared internal because it matches a requirement in internal protocol 'TypeProto'}} {{none}}
// expected-note@-1 {{mark the type alias as 'internal' to satisfy the requirement}} {{3-10=internal}}
}

struct ConformerByLocalType : TypeProto {
private struct TheType {} // expected-error {{struct 'TheType' must be declared internal because it matches a requirement in internal protocol 'TypeProto'}} {{3-10=internal}}
private struct TheType {} // expected-error {{struct 'TheType' must be declared internal because it matches a requirement in internal protocol 'TypeProto'}} {{none}}
// expected-note@-1 {{mark the struct as 'internal' to satisfy the requirement}} {{3-10=internal}}
}

private struct PrivateConformerByLocalType : TypeProto {
struct TheType {} // okay
}

private struct PrivateConformerByLocalTypeBad : TypeProto {
private struct TheType {} // expected-error {{struct 'TheType' must be as accessible as its enclosing type because it matches a requirement in protocol 'TypeProto'}} {{3-10=fileprivate}}
private struct TheType {} // expected-error {{struct 'TheType' must be as accessible as its enclosing type because it matches a requirement in protocol 'TypeProto'}} {{none}}
// expected-note@-1 {{mark the struct as 'fileprivate' to satisfy the requirement}} {{3-10=fileprivate}}
}
#endif

Expand Down
Loading