Skip to content

Commit 363b66a

Browse files
committed
Fully Qualify the Parent Type When Diagnosing Missing Member Types
Use the FullyQualified<Type> abstraction from the prior commit plus DescriptiveDeclKind to give a bit more information when issuing a missing member type diagnostic during type resolution.
1 parent b3843af commit 363b66a

19 files changed

+63
-46
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,8 @@ NOTE(invalid_redecl_implicit_wrapper,none,
802802
ERROR(ambiguous_type_base,none,
803803
"%0 is ambiguous for type lookup in this context", (DeclNameRef))
804804
ERROR(invalid_member_type,none,
805-
"%0 is not a member type of %1", (DeclNameRef, Type))
805+
"%0 is not a member type of %1 %2",
806+
(DeclNameRef, DescriptiveDeclKind, FullyQualified<Type>))
806807
ERROR(invalid_member_type_suggest,none,
807808
"%0 does not have a member type named %1; did you mean %2?",
808809
(Type, DeclNameRef, DeclName))

lib/Sema/TypeCheckType.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,17 @@ Type TypeResolution::mapTypeIntoContext(Type type) const {
153153
llvm_unreachable("unhandled stage");
154154
}
155155

156+
// FIXME: It would be nice to have a 'DescriptiveTypeKind' abstraction instead.
157+
static DescriptiveDeclKind describeDeclOfType(Type t) {
158+
if (!t) {
159+
return DescriptiveDeclKind::Type;
160+
}
161+
if (auto *NTD = t->getAnyNominal()) {
162+
return NTD->getDescriptiveKind();
163+
}
164+
return DescriptiveDeclKind::Type;
165+
}
166+
156167
Type TypeResolution::resolveDependentMemberType(
157168
Type baseTy, DeclContext *DC,
158169
SourceRange baseRange,
@@ -211,8 +222,9 @@ Type TypeResolution::resolveDependentMemberType(
211222
if (!singleType) {
212223
auto name = ref->getNameRef();
213224
auto nameLoc = ref->getNameLoc();
214-
ctx.Diags.diagnose(nameLoc, diag::invalid_member_type, name, baseTy)
215-
.highlight(baseRange);
225+
const auto kind = describeDeclOfType(baseTy);
226+
ctx.Diags.diagnose(nameLoc, diag::invalid_member_type, name, kind, baseTy)
227+
.highlight(baseRange);
216228
corrections.noteAllCandidates();
217229

218230
return ErrorType::get(ctx);
@@ -1160,8 +1172,10 @@ static Type diagnoseUnknownType(TypeResolution resolution,
11601172

11611173
// Qualified lookup case.
11621174
if (!parentType->mayHaveMembers()) {
1163-
diags.diagnose(comp->getNameLoc(), diag::invalid_member_type,
1164-
comp->getNameRef(), parentType)
1175+
const auto kind = describeDeclOfType(parentType);
1176+
diags
1177+
.diagnose(comp->getNameLoc(), diag::invalid_member_type,
1178+
comp->getNameRef(), kind, parentType)
11651179
.highlight(parentRange);
11661180
return ErrorType::get(ctx);
11671181
}
@@ -1214,9 +1228,11 @@ static Type diagnoseUnknownType(TypeResolution resolution,
12141228
parentType)
12151229
.highlight(parentRange);
12161230
} else {
1217-
diags.diagnose(comp->getNameLoc(), diag::invalid_member_type,
1218-
comp->getNameRef(), parentType)
1219-
.highlight(parentRange);
1231+
const auto kind = describeDeclOfType(parentType);
1232+
diags
1233+
.diagnose(comp->getNameLoc(), diag::invalid_member_type,
1234+
comp->getNameRef(), kind, parentType)
1235+
.highlight(parentRange);
12201236
// Note where the type was defined, this can help diagnose if the user
12211237
// expected name lookup to find a module when there's a conflicting type.
12221238
if (auto typeDecl = parentType->getNominalOrBoundGenericNominal()) {

test/AutoDiff/Sema/differentiable_attr_type_checking.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ class Super: Differentiable {
632632
// TODO(TF-632): Fix "'TangentVector' is not a member type of 'Self'" diagnostic.
633633
// The underlying error should appear instead:
634634
// "covariant 'Self' can only appear at the top level of method result type".
635-
// expected-error @+1 2 {{'TangentVector' is not a member type of 'Self'}}
635+
// expected-error @+1 2 {{'TangentVector' is not a member type of type 'Self'}}
636636
func vjpDynamicSelfResult() -> (Self, (Self.TangentVector) -> Self.TangentVector) {
637637
return (self, { $0 })
638638
}

test/Constraints/invalid_archetype_constraint.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ struct A2<T> : P {
1919
typealias Element = T
2020
}
2121

22-
func toA<S: Empty, AT:P>(_ s: S) -> AT where AT.Element == S.Generator.Element { // expected-error{{'Generator' is not a member type of 'S'}}
22+
func toA<S: Empty, AT:P>(_ s: S) -> AT where AT.Element == S.Generator.Element { // expected-error{{'Generator' is not a member type of type 'S'}}
2323
return AT()
2424
}

test/Constraints/invalid_constraint_lookup.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ protocol _Collection {
2525
protocol Collection : _Collection, Sequence {
2626
subscript(i: Index) -> Iterator.Element {get set }
2727
}
28-
func insertionSort<C: Mutable> (_ elements: inout C, i: C.Index) { // expected-error {{cannot find type 'Mutable' in scope}} expected-error {{'Index' is not a member type of 'C'}}
29-
var x: C.Iterator.Element = elements[i] // expected-error {{'Iterator' is not a member type of 'C'}}
28+
func insertionSort<C: Mutable> (_ elements: inout C, i: C.Index) { // expected-error {{cannot find type 'Mutable' in scope}} expected-error {{'Index' is not a member type of type 'C'}}
29+
var x: C.Iterator.Element = elements[i] // expected-error {{'Iterator' is not a member type of type 'C'}}
3030
}

test/Constraints/same_types.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func test8b<T: Barrable, U: Barrable>(_ t: T, u: U)
141141
}
142142

143143
// rdar://problem/19137463
144-
func rdar19137463<T>(_ t: T) where T.a == T {} // expected-error{{'a' is not a member type of 'T'}}
144+
func rdar19137463<T>(_ t: T) where T.a == T {} // expected-error{{'a' is not a member type of type 'T'}}
145145
rdar19137463(1)
146146

147147

test/Generics/associated_type_typo.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,4 @@ class D {
7979
typealias BElement = Int // expected-note{{did you mean 'BElement'?}}
8080
}
8181

82-
func typoSuperclass2<T : D>(_: T, _: T.Element) { } // expected-error{{'Element' is not a member type of 'T'}}
82+
func typoSuperclass2<T : D>(_: T, _: T.Element) { } // expected-error{{'Element' is not a member type of type 'T'}}

test/Generics/function_defs.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ func sameTypeEq<T>(_: T) where T = T {} // expected-error{{use '==' for same-typ
290290

291291
func badTypeConformance1<T>(_: T) where Int : EqualComparable {} // expected-error{{type 'Int' in conformance requirement does not refer to a generic parameter or associated type}}
292292

293-
func badTypeConformance2<T>(_: T) where T.Blarg : EqualComparable { } // expected-error{{'Blarg' is not a member type of 'T'}}
293+
func badTypeConformance2<T>(_: T) where T.Blarg : EqualComparable { } // expected-error{{'Blarg' is not a member type of type 'T'}}
294294

295295
func badTypeConformance3<T>(_: T) where (T) -> () : EqualComparable { }
296296
// expected-error@-1{{type '(T) -> ()' in conformance requirement does not refer to a generic parameter or associated type}}

test/Generics/generic_types.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ struct XParam<T> { // expected-note{{'XParam' declared here}}
199199
}
200200
}
201201

202-
var xp : XParam<Int>.T = Int() // expected-error{{'T' is not a member type of 'XParam<Int>'}}
202+
var xp : XParam<Int>.T = Int() // expected-error{{'T' is not a member type of generic struct 'generic_types.XParam<Swift.Int>'}}
203203

204204
// Diagnose failure to meet a superclass requirement.
205205
class X1 { }
@@ -237,11 +237,11 @@ class Bottom<T : Bottom<Top>> {}
237237
// Invalid inheritance clause
238238

239239
struct UnsolvableInheritance1<T : T.A> {}
240-
// expected-error@-1 {{'A' is not a member type of 'T'}}
240+
// expected-error@-1 {{'A' is not a member type of type 'T'}}
241241

242242
struct UnsolvableInheritance2<T : U.A, U : T.A> {}
243-
// expected-error@-1 {{'A' is not a member type of 'U'}}
244-
// expected-error@-2 {{'A' is not a member type of 'T'}}
243+
// expected-error@-1 {{'A' is not a member type of type 'U'}}
244+
// expected-error@-2 {{'A' is not a member type of type 'T'}}
245245

246246
enum X7<T> where X7.X : G { case X } // expected-error{{enum case 'X' is not a member type of 'X7<T>'}}
247247
// expected-error@-1{{cannot find type 'G' in scope}}

test/Generics/invalid.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func badDiagnostic3() {
7979
// Crash with missing nested type inside concrete type
8080
class OuterGeneric<T> {
8181
class InnerGeneric<U> where U:OuterGeneric<T.NoSuchType> {
82-
// expected-error@-1 {{'NoSuchType' is not a member type of 'T'}}
82+
// expected-error@-1 {{'NoSuchType' is not a member type of type 'T'}}
8383
func method() {
8484
_ = method
8585
}
@@ -107,10 +107,10 @@ class P<N> {
107107

108108
// SR-5579
109109
protocol Foo {
110-
associatedtype Bar where Bar.Nonsense == Int // expected-error{{'Nonsense' is not a member type of 'Self.Bar'}}
110+
associatedtype Bar where Bar.Nonsense == Int // expected-error{{'Nonsense' is not a member type of type 'Self.Bar'}}
111111
}
112112

113-
protocol Wibble : Foo where Bar.EvenMoreNonsense == Int { } // expected-error{{'EvenMoreNonsense' is not a member type of 'Self.Bar'}}
113+
protocol Wibble : Foo where Bar.EvenMoreNonsense == Int { } // expected-error{{'EvenMoreNonsense' is not a member type of type 'Self.Bar'}}
114114

115115
// rdar://45271500 - failure to emit a diagnostic
116116
enum Cat<A> {}

test/Interop/Cxx/class/access-specifiers-typechecker.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ v.PrivateMemberVar = 1 // expected-error {{value of type 'PublicPrivate' has no
3030
PublicPrivate.PrivateStaticMemberVar = 1 // expected-error {{'PublicPrivate' has no member 'PrivateStaticMemberVar'}}
3131
v.privateMemberFunc() // expected-error {{value of type 'PublicPrivate' has no member 'privateMemberFunc'}}
3232

33-
var privateTypedefVar: PublicPrivate.PrivateTypedef // expected-error {{'PrivateTypedef' is not a member type of 'PublicPrivate'}}
34-
var privateStructVar: PublicPrivate.PrivateStruct // expected-error {{'PrivateStruct' is not a member type of 'PublicPrivate'}}
35-
var privateEnumVar: PublicPrivate.PrivateEnum // expected-error {{'PrivateEnum' is not a member type of 'PublicPrivate'}}
33+
var privateTypedefVar: PublicPrivate.PrivateTypedef // expected-error {{'PrivateTypedef' is not a member type of struct 'AccessSpecifiers.PublicPrivate'}}
34+
var privateStructVar: PublicPrivate.PrivateStruct // expected-error {{'PrivateStruct' is not a member type of struct 'AccessSpecifiers.PublicPrivate'}}
35+
var privateEnumVar: PublicPrivate.PrivateEnum // expected-error {{'PrivateEnum' is not a member type of struct 'AccessSpecifiers.PublicPrivate'}}
3636
// TODO: PrivateEnumValue1 and PrivateAnonymousEnumValue1 give the expected
3737
// error, but only because these types of enums (private or public) aren't
3838
// currently imported at all. Once that is fixed, remove this TODO.
3939
print(PublicPrivate.PrivateEnumValue1) // expected-error {{'PublicPrivate' has no member 'PrivateEnumValue1'}}
4040
print(PublicPrivate.PrivateAnonymousEnumValue1) // expected-error {{'PublicPrivate' has no member 'PrivateAnonymousEnumValue1'}}
41-
var privateClosedEnumVar: PublicPrivate.PrivateClosedEnum // expected-error {{'PrivateClosedEnum' is not a member type of 'PublicPrivate'}}
42-
var privateOpenEnumVar: PublicPrivate.PrivateOpenEnum // expected-error {{'PrivateOpenEnum' is not a member type of 'PublicPrivate'}}
43-
var privateFlagEnumVar: PublicPrivate.PrivateFlagEnum // expected-error {{'PrivateFlagEnum' is not a member type of 'PublicPrivate'}}
41+
var privateClosedEnumVar: PublicPrivate.PrivateClosedEnum // expected-error {{'PrivateClosedEnum' is not a member type of struct 'AccessSpecifiers.PublicPrivate'}}
42+
var privateOpenEnumVar: PublicPrivate.PrivateOpenEnum // expected-error {{'PrivateOpenEnum' is not a member type of struct 'AccessSpecifiers.PublicPrivate'}}
43+
var privateFlagEnumVar: PublicPrivate.PrivateFlagEnum // expected-error {{'PrivateFlagEnum' is not a member type of struct 'AccessSpecifiers.PublicPrivate'}}

test/Sema/diag_module_conflict_with_type.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import SecondModule
1616

1717
public func f(_ x: ModuleType.MyStruct) {}
1818

19-
// CHECK: error: 'MyStruct' is not a member type of 'ModuleType'
19+
// CHECK: error: 'MyStruct' is not a member type of struct 'SecondModule.ModuleType'
2020
// CHECK: SecondModule.ModuleType:1:15: note: 'ModuleType' declared here
2121
// CHECK: public struct ModuleType {
2222
// CHECK: ^

test/decl/nested/type_in_function.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ struct OuterGenericStruct<A> {
128128
func genericFunction<T>(t: T) {
129129
class First : Second<T>.UnknownType { }
130130
// expected-error@-1 {{type 'First' cannot be nested in generic function 'genericFunction(t:)'}}
131-
// expected-error@-2 {{'UnknownType' is not a member type of 'Second<T>'}}
131+
// expected-error@-2 {{'UnknownType' is not a member type of generic class 'type_in_function.Second<T>'}}
132132
class Second<T> : Second { } // expected-note{{'Second' declared here}}
133133
// expected-error@-1 {{type 'Second' cannot be nested in generic function 'genericFunction(t:)'}}
134134
// expected-error@-2 {{'Second' inherits from itself}}

test/decl/protocol/recursive_requirement.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ struct Epsilon<T: Alpha, // expected-note{{conformance constraint 'U': 'Gamma' i
8282
// expected-warning@-1{{redundant conformance constraint 'T': 'Alpha'}}
8383
U: Gamma> // expected-warning{{redundant conformance constraint 'U': 'Gamma'}}
8484
// expected-note@-1{{conformance constraint 'T': 'Alpha' implied here}}
85-
where T.Beta == U, // expected-error{{'Beta' is not a member type of 'T'}}
86-
U.Delta == T {} // expected-error{{'Delta' is not a member type of 'U'}}
85+
where T.Beta == U, // expected-error{{'Beta' is not a member type of type 'T'}}
86+
U.Delta == T {} // expected-error{{'Delta' is not a member type of type 'U'}}
8787

8888
// -----
8989

test/decl/protocol/special/coding/class_codable_member_type_lookup.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,10 @@ struct NonSynthesizedClass : Codable { // expected-note 4 {{'NonSynthesizedClass
184184

185185
// Qualified type lookup should clearly fail -- we shouldn't get a synthesized
186186
// type here.
187-
public func qualifiedFoo(_ key: NonSynthesizedClass.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of 'NonSynthesizedClass'}}
188-
internal func qualifiedBar(_ key: NonSynthesizedClass.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of 'NonSynthesizedClass'}}
189-
fileprivate func qualfiedBaz(_ key: NonSynthesizedClass.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of 'NonSynthesizedClass'}}
190-
private func qualifiedQux(_ key: NonSynthesizedClass.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of 'NonSynthesizedClass'}}
187+
public func qualifiedFoo(_ key: NonSynthesizedClass.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'class_codable_member_type_lookup.NonSynthesizedClass'}}
188+
internal func qualifiedBar(_ key: NonSynthesizedClass.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'class_codable_member_type_lookup.NonSynthesizedClass'}}
189+
fileprivate func qualfiedBaz(_ key: NonSynthesizedClass.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'class_codable_member_type_lookup.NonSynthesizedClass'}}
190+
private func qualifiedQux(_ key: NonSynthesizedClass.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'class_codable_member_type_lookup.NonSynthesizedClass'}}
191191

192192
// Unqualified lookups should find the public top-level CodingKeys type.
193193
public func unqualifiedFoo(_ key: CodingKeys) { print(CodingKeys.topLevel) }

test/decl/protocol/special/coding/struct_codable_member_type_lookup.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,10 @@ struct NonSynthesizedStruct : Codable { // expected-note 4 {{'NonSynthesizedStru
184184

185185
// Qualified type lookup should clearly fail -- we shouldn't get a synthesized
186186
// type here.
187-
public func qualifiedFoo(_ key: NonSynthesizedStruct.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of 'NonSynthesizedStruct'}}
188-
internal func qualifiedBar(_ key: NonSynthesizedStruct.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of 'NonSynthesizedStruct'}}
189-
fileprivate func qualfiedBaz(_ key: NonSynthesizedStruct.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of 'NonSynthesizedStruct'}}
190-
private func qualifiedQux(_ key: NonSynthesizedStruct.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of 'NonSynthesizedStruct'}}
187+
public func qualifiedFoo(_ key: NonSynthesizedStruct.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'struct_codable_member_type_lookup.NonSynthesizedStruct'}}
188+
internal func qualifiedBar(_ key: NonSynthesizedStruct.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'struct_codable_member_type_lookup.NonSynthesizedStruct'}}
189+
fileprivate func qualfiedBaz(_ key: NonSynthesizedStruct.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'struct_codable_member_type_lookup.NonSynthesizedStruct'}}
190+
private func qualifiedQux(_ key: NonSynthesizedStruct.CodingKeys) {} // expected-error {{'CodingKeys' is not a member type of struct 'struct_codable_member_type_lookup.NonSynthesizedStruct'}}
191191

192192
// Unqualified lookups should find the public top-level CodingKeys type.
193193
public func unqualifiedFoo(_ key: CodingKeys) { print(CodingKeys.topLevel) }

test/decl/typealias/dependent_types.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@ struct GenericStruct<T> { // expected-note 3{{generic type 'GenericStruct' decla
3434
func methodTwo() -> MetaAlias {}
3535

3636
func methodOne() -> Alias.BadType {}
37-
// expected-error@-1 {{'BadType' is not a member type of 'GenericStruct<T>.Alias'}}
37+
// expected-error@-1 {{'BadType' is not a member type of type 'dependent_types.GenericStruct<T>.Alias'}}
3838
func methodTwo() -> MetaAlias.BadType {}
39-
// expected-error@-1 {{'BadType' is not a member type of 'GenericStruct<T>.MetaAlias'}}
39+
// expected-error@-1 {{'BadType' is not a member type of type 'dependent_types.GenericStruct<T>.MetaAlias'}}
4040

4141
var propertyOne: Alias.BadType
42-
// expected-error@-1 {{'BadType' is not a member type of 'GenericStruct<T>.Alias' (aka 'T')}}
42+
// expected-error@-1 {{'BadType' is not a member type of type 'dependent_types.GenericStruct<T>.Alias' (aka 'T')}}
4343
var propertyTwo: MetaAlias.BadType
44-
// expected-error@-1 {{'BadType' is not a member type of 'GenericStruct<T>.MetaAlias' (aka 'T.Type')}}
44+
// expected-error@-1 {{'BadType' is not a member type of type 'dependent_types.GenericStruct<T>.MetaAlias' (aka 'T.Type')}}
4545
}
4646

4747
// This was accepted in Swift 3.0 and sort of worked... but we can't

validation-test/compiler_crashers_2_fixed/0159-rdar40009245.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
protocol P {
44
associatedtype A : P where A.X == Self
5-
// expected-error@-1{{'X' is not a member type of 'Self.A}}
5+
// expected-error@-1{{'X' is not a member type of type 'Self.A'}}
66
associatedtype X : P where P.A == Self
77
// expected-error@-1{{associated type 'A' can only be used with a concrete type or generic parameter base}}
88
}

validation-test/compiler_crashers_fixed/00053-std-function-func-swift-type-subst.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@
1010

1111
// Issue found by https://github.com/julasamer (julasamer)
1212

13-
struct c<d, e: b> where d.c == e { // expected-error {{cannot find type 'b' in scope}} expected-error {{'c' is not a member type of 'd'}}
13+
struct c<d, e: b> where d.c == e { // expected-error {{cannot find type 'b' in scope}} expected-error {{'c' is not a member type of type 'd'}}
1414
}

0 commit comments

Comments
 (0)