Skip to content

Commit 268f6e2

Browse files
committed
[Diagnostics] Improve the diagnostics for invalid associatedtype or
typealias access on existential types by mentioning the base type in the error message.
1 parent 8713d78 commit 268f6e2

File tree

6 files changed

+17
-15
lines changed

6 files changed

+17
-15
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2465,11 +2465,13 @@ WARNING(append_interpolation_access_control,none,
24652465

24662466
// Protocols and existentials
24672467
ERROR(assoc_type_outside_of_protocol,none,
2468-
"associated type %0 can only be used with a concrete type or "
2469-
"generic parameter base", (DeclNameRef))
2468+
"cannot access associated type %0 from %1; use a concrete type or "
2469+
"generic parameter base instead",
2470+
(DeclNameRef, Type))
24702471
ERROR(typealias_outside_of_protocol,none,
2471-
"type alias %0 can only be used with a concrete type or "
2472-
"generic parameter base", (DeclNameRef))
2472+
"cannot access type alias %0 from %1; use a concrete type or "
2473+
"generic parameter base instead",
2474+
(DeclNameRef, Type))
24732475

24742476
ERROR(objc_protocol_inherits_non_objc_protocol,none,
24752477
"@objc protocol %0 cannot refine non-@objc protocol %1", (Type, Type))

lib/Sema/CSDiagnostics.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4405,10 +4405,10 @@ bool AllowTypeOrInstanceMemberFailure::diagnoseAsError() {
44054405
// static members doesn't make a whole lot of sense
44064406
if (isa<TypeAliasDecl>(Member)) {
44074407
Diag.emplace(
4408-
emitDiagnostic(diag::typealias_outside_of_protocol, Name));
4408+
emitDiagnostic(diag::typealias_outside_of_protocol, Name, instanceTy));
44094409
} else if (isa<AssociatedTypeDecl>(Member)) {
44104410
Diag.emplace(
4411-
emitDiagnostic(diag::assoc_type_outside_of_protocol, Name));
4411+
emitDiagnostic(diag::assoc_type_outside_of_protocol, Name, instanceTy));
44124412
} else if (isa<ConstructorDecl>(Member)) {
44134413
Diag.emplace(
44144414
emitDiagnostic(diag::construct_protocol_by_name, instanceTy));

lib/Sema/TypeCheckType.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,12 +1656,12 @@ static Type resolveNestedIdentTypeComponent(TypeResolution resolution,
16561656

16571657
case TypeChecker::UnsupportedMemberTypeAccessKind::TypeAliasOfExistential:
16581658
diags.diagnose(comp->getNameLoc(), diag::typealias_outside_of_protocol,
1659-
comp->getNameRef());
1659+
comp->getNameRef(), parentTy);
16601660
return ErrorType::get(ctx);
16611661

16621662
case TypeChecker::UnsupportedMemberTypeAccessKind::AssociatedTypeOfExistential:
16631663
diags.diagnose(comp->getNameLoc(), diag::assoc_type_outside_of_protocol,
1664-
comp->getNameRef());
1664+
comp->getNameRef(), parentTy);
16651665
return ErrorType::get(ctx);
16661666
}
16671667

test/decl/typealias/associated_types.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@ protocol BaseProto {
44
associatedtype AssocTy
55
}
66
var a: BaseProto.AssocTy = 4
7-
// expected-error@-1{{associated type 'AssocTy' can only be used with a concrete type or generic parameter base}}
7+
// expected-error@-1{{cannot access associated type 'AssocTy' from 'BaseProto'; use a concrete type or generic parameter base instead}}
88

99
var a = BaseProto.AssocTy.self
10-
// expected-error@-1{{associated type 'AssocTy' can only be used with a concrete type or generic parameter base}}
10+
// expected-error@-1{{cannot access associated type 'AssocTy' from 'BaseProto'; use a concrete type or generic parameter base instead}}
1111

1212
protocol DerivedProto : BaseProto {
1313
func associated() -> AssocTy // no-warning
1414

1515
func existential() -> BaseProto.AssocTy
16-
// expected-error@-1{{associated type 'AssocTy' can only be used with a concrete type or generic parameter base}}
16+
// expected-error@-1{{cannot access associated type 'AssocTy' from 'BaseProto'; use a concrete type or generic parameter base instead}}
1717
}
1818

1919

test/decl/typealias/protocol.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ struct T5 : P5 {
176176
var a: P5.T1 // OK
177177

178178
// Invalid -- cannot represent associated type of existential
179-
var v2: P5.T2 // expected-error {{type alias 'T2' can only be used with a concrete type or generic parameter base}}
180-
var v3: P5.X // expected-error {{type alias 'X' can only be used with a concrete type or generic parameter base}}
179+
var v2: P5.T2 // expected-error {{cannot access type alias 'T2' from 'P5'; use a concrete type or generic parameter base instead}}
180+
var v3: P5.X // expected-error {{cannot access type alias 'X' from 'P5'; use a concrete type or generic parameter base instead}}
181181

182182
// Unqualified reference to typealias from a protocol conformance
183183
var v4: T1 // OK
@@ -188,7 +188,7 @@ struct T5 : P5 {
188188
var v7: T5.T2 // OK
189189

190190
var v8 = P6.A.self
191-
var v9 = P6.B.self // expected-error {{type alias 'B' can only be used with a concrete type or generic parameter base}}
191+
var v9 = P6.B.self // expected-error {{cannot access type alias 'B' from 'P6'; use a concrete type or generic parameter base instead}}
192192
}
193193

194194
// Unqualified lookup finds typealiases in protocol extensions

test/type/subclass_composition.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ func dependentMemberTypes<T : BaseIntAndP2>(
322322
_: T.FullyConcrete,
323323

324324
_: BaseIntAndP2.DependentInConcreteConformance, // FIXME expected-error {{}}
325-
_: BaseIntAndP2.DependentProtocol, // expected-error {{type alias 'DependentProtocol' can only be used with a concrete type or generic parameter base}}
325+
_: BaseIntAndP2.DependentProtocol, // expected-error {{cannot access type alias 'DependentProtocol' from 'BaseIntAndP2' (aka 'Base<Int> & P2'); use a concrete type or generic parameter base instead}}
326326
_: BaseIntAndP2.DependentClass,
327327
_: BaseIntAndP2.FullyConcrete) {}
328328

0 commit comments

Comments
 (0)