Skip to content

Commit 107ae6d

Browse files
Merge pull request #63784 from AnthonyLatsis/sugar-type-members-4
PreCheckExpr: Recognize non-identifier type qualifiers in type expressions
2 parents 9e94cb9 + a0d1b43 commit 107ae6d

File tree

6 files changed

+50
-116
lines changed

6 files changed

+50
-116
lines changed

include/swift/AST/Expr.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,9 +1340,9 @@ class TypeExpr : public Expr {
13401340
TypeDecl *Decl);
13411341

13421342
/// Create a \c TypeExpr for a member \c TypeDecl of the given parent
1343-
/// \c DeclRefTypeRepr.
1344-
static TypeExpr *createForMemberDecl(DeclRefTypeRepr *ParentTR,
1345-
DeclNameLoc NameLoc, TypeDecl *Decl);
1343+
/// \c TypeRepr.
1344+
static TypeExpr *createForMemberDecl(TypeRepr *ParentTR, DeclNameLoc NameLoc,
1345+
TypeDecl *Decl);
13461346

13471347
/// Create a \c TypeExpr from an \c DeclRefTypeRepr with the given arguments
13481348
/// applied at the specified location.

lib/AST/Expr.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2224,24 +2224,29 @@ TypeExpr *TypeExpr::createForMemberDecl(DeclNameLoc ParentNameLoc,
22242224
return new (C) TypeExpr(TR);
22252225
}
22262226

2227-
TypeExpr *TypeExpr::createForMemberDecl(DeclRefTypeRepr *ParentTR,
2228-
DeclNameLoc NameLoc, TypeDecl *Decl) {
2227+
TypeExpr *TypeExpr::createForMemberDecl(TypeRepr *ParentTR, DeclNameLoc NameLoc,
2228+
TypeDecl *Decl) {
22292229
ASTContext &C = Decl->getASTContext();
22302230

2231-
// Create a new list of components.
2232-
SmallVector<IdentTypeRepr *, 2> Components;
2233-
if (auto *MemberTR = dyn_cast<MemberTypeRepr>(ParentTR)) {
2234-
auto MemberComps = MemberTR->getMemberComponents();
2235-
Components.append(MemberComps.begin(), MemberComps.end());
2236-
}
2237-
22382231
// Add a new component for the member we just found.
22392232
auto *NewComp = new (C) SimpleIdentTypeRepr(NameLoc, Decl->createNameRef());
22402233
NewComp->setValue(Decl, nullptr);
2241-
Components.push_back(NewComp);
22422234

2243-
auto *TR =
2244-
MemberTypeRepr::create(C, ParentTR->getBaseComponent(), Components);
2235+
TypeRepr *TR = nullptr;
2236+
if (auto *DeclRefTR = dyn_cast<DeclRefTypeRepr>(ParentTR)) {
2237+
// Create a new list of components.
2238+
SmallVector<IdentTypeRepr *, 4> Components;
2239+
if (auto *MemberTR = dyn_cast<MemberTypeRepr>(ParentTR)) {
2240+
auto MemberComps = MemberTR->getMemberComponents();
2241+
Components.append(MemberComps.begin(), MemberComps.end());
2242+
}
2243+
2244+
Components.push_back(NewComp);
2245+
TR = MemberTypeRepr::create(C, DeclRefTR->getBaseComponent(), Components);
2246+
} else {
2247+
TR = MemberTypeRepr::create(C, ParentTR, NewComp);
2248+
}
2249+
22452250
return new (C) TypeExpr(TR);
22462251
}
22472252

lib/Sema/PreCheckExpr.cpp

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,33 +1429,31 @@ TypeExpr *PreCheckExpression::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) {
14291429
}
14301430

14311431
// Fold 'T.U' into a nested type.
1432-
if (auto *DeclRefTR = dyn_cast<DeclRefTypeRepr>(InnerTypeRepr)) {
1433-
// Resolve the TypeRepr to get the base type for the lookup.
1434-
const auto BaseTy = TypeResolution::resolveContextualType(
1435-
InnerTypeRepr, DC, TypeResolverContext::InExpression,
1436-
[](auto unboundTy) {
1437-
// FIXME: Don't let unbound generic types escape type resolution.
1438-
// For now, just return the unbound generic type.
1439-
return unboundTy;
1440-
},
1441-
// FIXME: Don't let placeholder types escape type resolution.
1442-
// For now, just return the placeholder type.
1443-
PlaceholderType::get,
1444-
// TypeExpr pack elements are opened in CSGen.
1445-
/*packElementOpener*/ nullptr);
14461432

1447-
if (BaseTy->mayHaveMembers()) {
1448-
// See if there is a member type with this name.
1449-
auto Result =
1450-
TypeChecker::lookupMemberType(DC, BaseTy, Name,
1451-
defaultMemberLookupOptions);
1452-
1453-
// If there is no nested type with this name, we have a lookup of
1454-
// a non-type member, so leave the expression as-is.
1455-
if (Result.size() == 1) {
1456-
return TypeExpr::createForMemberDecl(DeclRefTR, UDE->getNameLoc(),
1457-
Result.front().Member);
1458-
}
1433+
// Resolve the TypeRepr to get the base type for the lookup.
1434+
const auto BaseTy = TypeResolution::resolveContextualType(
1435+
InnerTypeRepr, DC, TypeResolverContext::InExpression,
1436+
[](auto unboundTy) {
1437+
// FIXME: Don't let unbound generic types escape type resolution.
1438+
// For now, just return the unbound generic type.
1439+
return unboundTy;
1440+
},
1441+
// FIXME: Don't let placeholder types escape type resolution.
1442+
// For now, just return the placeholder type.
1443+
PlaceholderType::get,
1444+
// TypeExpr pack elements are opened in CSGen.
1445+
/*packElementOpener*/ nullptr);
1446+
1447+
if (BaseTy->mayHaveMembers()) {
1448+
// See if there is a member type with this name.
1449+
auto Result = TypeChecker::lookupMemberType(DC, BaseTy, Name,
1450+
defaultMemberLookupOptions);
1451+
1452+
// If there is no nested type with this name, we have a lookup of
1453+
// a non-type member, so leave the expression as-is.
1454+
if (Result.size() == 1) {
1455+
return TypeExpr::createForMemberDecl(InnerTypeRepr, UDE->getNameLoc(),
1456+
Result.front().Member);
14591457
}
14601458
}
14611459

lib/Sema/TypeCheckRuntimeMetadataAttr.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,7 @@ static TypeRepr *buildTypeRepr(DeclContext *typeContext,
7878
// Reverse the components to form a valid outer-to-inner name sequence.
7979
std::reverse(components.begin(), components.end());
8080

81-
TypeRepr *typeRepr = nullptr;
82-
if (components.size() == 1) {
83-
typeRepr = components.front();
84-
} else {
85-
typeRepr = MemberTypeRepr::create(ctx, components);
86-
}
81+
TypeRepr *typeRepr = MemberTypeRepr::create(ctx, components);
8782

8883
if (forMetatype)
8984
return new (ctx) MetatypeTypeRepr(typeRepr, /*MetaLoc=*/SourceLoc());

test/Parse/type_expr.swift

Lines changed: 3 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -344,18 +344,10 @@ func compositionType() {
344344

345345
CheckType<P1 & P2>.matches(((P1) & (P2)).self)
346346
CheckType<P1 & P2>.matches((Foo.P1 & Foo.P2).self)
347-
// FIXME: Teach Sema to recognize this type expression.
348-
// expected-error@+1 {{binary operator '&' cannot be applied to operands of type '(any (Foo).P1).Type' (aka '(any P1).Type') and '(any (Foo).P2).Type' (aka '(any P2).Type')}}
349347
CheckType<P1 & P2>.matches(((Foo).P1 & (Foo).P2).self)
350348
CheckType<P1 & P2>.matches((Gen<Foo>.P1 & Gen<Foo>.P2).self)
351-
// FIXME: Teach Sema to recognize this type expression.
352-
// expected-error@+1 {{binary operator '&' cannot be applied to operands of type '(any Optional<Foo>.P1).Type' (aka '(any P1).Type') and '(any Optional<Foo>.P2).Type' (aka '(any P2).Type')}}
353349
CheckType<P1 & P2>.matches((Foo?.P1 & Foo?.P2).self)
354-
// FIXME: Teach Sema to recognize this type expression.
355-
// expected-error@+1 {{binary operator '&' cannot be applied to operands of type '(any Array<Foo>.P1).Type' (aka '(any P1).Type') and '(any Array<Foo>.P2).Type' (aka '(any P2).Type')}}
356350
CheckType<P1 & P2>.matches(([Foo].P1 & [Foo].P2).self)
357-
// FIXME: Teach Sema to recognize this type expression.
358-
// expected-error@+1 {{binary operator '&' cannot be applied to operands of type '(any Dictionary<Int, Foo>.P1).Type' (aka '(any P1).Type') and '(any Dictionary<Int, Foo>.P2).Type' (aka '(any P2).Type')}}
359351
CheckType<P1 & P2>.matches(([Int : Foo].P1 & [Int : Foo].P2).self)
360352
}
361353

@@ -375,8 +367,6 @@ func tupleType() {
375367
CheckType<(Foo, Foo)>.matches(((Foo), (Foo)).self)
376368

377369
CheckType<(Foo.Bar, Foo.Bar)>.matches((Foo.Bar, Foo.Bar).self)
378-
// FIXME: Teach Sema to recognize this type expression.
379-
// expected-error@+1 {{cannot convert value of type '((Foo).Bar.Type, (Foo).Bar.Type)' to expected argument type '(Foo.Bar, Foo.Bar).Type'}}
380370
CheckType<(Foo.Bar, Foo.Bar)>.matches(((Foo).Bar, (Foo).Bar).self)
381371

382372
CheckType<(Gen<Foo>, Gen<Foo>)>.matches((Gen<Foo>, Gen<Foo>).self)
@@ -385,14 +375,8 @@ func tupleType() {
385375
CheckType<([Int : Foo], [Int : Foo])>.matches(([Int : Foo], [Int : Foo]).self)
386376

387377
CheckType<(Gen<Foo>.Bar, Gen<Foo>.Bar)>.matches((Gen<Foo>.Bar, Gen<Foo>.Bar).self)
388-
// FIXME: Teach Sema to recognize this type expression.
389-
// expected-error@+1 {{cannot convert value of type '(Optional<Foo>.Wrapped.Type, Optional<Foo>.Wrapped.Type)' (aka '(Foo.Type, Foo.Type)') to expected argument type '(Foo, Foo).Type'}}
390378
CheckType<(Foo, Foo)>.matches((Foo?.Wrapped, Foo?.Wrapped).self)
391-
// FIXME: Teach Sema to recognize this type expression.
392-
// expected-error@+1 {{cannot convert value of type '(Array<Foo>.Element.Type, Array<Foo>.Element.Type)' (aka '(Foo.Type, Foo.Type)') to expected argument type '(Foo, Foo).Type'}}
393379
CheckType<(Foo, Foo)>.matches(([Foo].Element, [Foo].Element).self)
394-
// FIXME: Teach Sema to recognize this type expression.
395-
// expected-error@+1 {{cannot convert value of type '(Dictionary<Int, Foo>.Value.Type, Dictionary<Int, Foo>.Value.Type)' (aka '(Foo.Type, Foo.Type)') to expected argument type '(Foo, Foo).Type'}}
396380
CheckType<(Foo, Foo)>.matches(([Int : Foo].Value, [Int : Foo].Value).self)
397381

398382
CheckType<(Foo.Type, Foo.Type)>.matches((Foo.Type, Foo.Type).self)
@@ -401,7 +385,6 @@ func tupleType() {
401385
CheckType<(P1 & P2, P1 & P2)>.matches((P1 & P2, P1 & P2).self)
402386

403387
// Trade exhaustivity for one complex test case.
404-
// FIXME: Replace this with the next test once we make it succeed.
405388
CheckType<
406389
(
407390
(Gen<Foo>.Bar) -> P1 & P2,
@@ -411,24 +394,7 @@ func tupleType() {
411394
)
412395
>.matches(
413396
(
414-
(Gen<Foo>.Bar) -> (P1) & Optional<Foo>.P2,
415-
(Foo.Bar, [Int : Foo?].Type),
416-
[Gen<Foo>.Bar],
417-
Array<Foo.Bar.Baz>.Element
418-
).self
419-
)
420-
421-
// FIXME: Teach Sema to recognize this type expression.
422-
CheckType<
423-
(
424-
(Gen<Foo>.Bar) -> P1 & P2,
425-
(Foo.Bar, [Int : Foo?].Type),
426-
[Gen<Foo>.Bar],
427-
Foo.Bar.Baz
428-
)
429-
>.matches(
430-
( // expected-error {{cannot convert value of type '(_.Type, (Foo.Bar, Dictionary<Int, Optional<Foo>>.Type).Type, Array<(Gen<Foo>).Bar.Type>, Array<Foo.Bar.Baz>.Element.Type)' (aka '(_.Type, (Foo.Bar, Dictionary<Int, Optional<Foo>>.Type).Type, Array<(Gen<Foo>).Bar.Type>, Foo.Bar.Baz.Type)') to expected argument type '((Gen<Foo>.Bar) -> any P1 & P2, (Foo.Bar, [Int : Foo?].Type), [Gen<Foo>.Bar], Foo.Bar.Baz).Type'}}
431-
(Gen<Foo>.Bar) -> (P1) & Foo?.P2, // expected-error {{expected type after '->'}}
397+
(Gen<Foo>.Bar) -> (P1) & Foo?.P2,
432398
(Foo.Bar, [Int : Foo?].Type),
433399
[(Gen<Foo>).Bar],
434400
[Foo.Bar.Baz].Element
@@ -466,8 +432,6 @@ func functionType() {
466432
CheckType<(Foo) -> Foo>.matches((((Foo)) -> (Foo)).self)
467433

468434
CheckType<(Foo.Bar) -> Foo.Bar>.matches(((Foo.Bar) -> Foo.Bar).self)
469-
// FIXME: Teach Sema to recognize this type expression.
470-
// expected-error@+1 {{expected type before '->'}} expected-error@+1 {{expected type after '->'}}
471435
CheckType<(Foo.Bar) -> Foo.Bar>.matches((((Foo).Bar) -> (Foo).Bar).self)
472436

473437
CheckType<(Gen<Foo>) -> Gen<Foo>>.matches(((Gen<Foo>) -> Gen<Foo>).self)
@@ -476,14 +440,8 @@ func functionType() {
476440
CheckType<([Int : Foo]) -> [Int : Foo]>.matches((([Int : Foo]) -> [Int : Foo]).self)
477441

478442
CheckType<(Gen<Foo>.Bar) -> Gen<Foo>.Bar>.matches(((Gen<Foo>.Bar) -> Gen<Foo>.Bar).self)
479-
// FIXME: Teach Sema to recognize this type expression.
480-
// expected-error@+1 {{expected type before '->'}} expected-error@+1 {{expected type after '->'}}
481443
CheckType<(Foo) -> Foo>.matches(((Foo?.Wrapped) -> Foo?.Wrapped).self)
482-
// FIXME: Teach Sema to recognize this type expression.
483-
// expected-error@+1 {{expected type before '->'}} expected-error@+1 {{expected type after '->'}}
484444
CheckType<(Foo) -> Foo>.matches((([Foo].Element) -> [Foo].Element).self)
485-
// FIXME: Teach Sema to recognize this type expression.
486-
// expected-error@+1 {{expected type before '->'}} expected-error@+1 {{expected type after '->'}}
487445
CheckType<(Foo) -> Foo>.matches((([Int : Foo].Value) -> [Int : Foo].Value).self)
488446

489447
CheckType<(Foo.Type) -> Foo.Type>.matches(((Foo.Type) -> Foo.Type).self)
@@ -495,7 +453,6 @@ func functionType() {
495453
.matches(((P1 & P2) -> (P3 & P2) -> P1 & Any).self)
496454

497455
// Trade exhaustivity for one complex test case.
498-
// FIXME: Replace this with the next test once we make it succeed.
499456
CheckType<
500457
(
501458
P1 & P2,
@@ -507,33 +464,12 @@ func functionType() {
507464
>.matches(
508465
(
509466
(
510-
(P1) & Optional<Foo>.P2,
511-
Gen<Foo>.Bar,
512-
(Foo, [Int : Foo?].Type)
513-
) -> (
514-
[Foo.Bar]
515-
) -> Array<Foo>.Element
516-
).self
517-
)
518-
519-
// FIXME: Teach Sema to recognize this type expression.
520-
CheckType<
521-
(
522-
P1 & P2,
523-
Gen<Foo>.Bar,
524-
(Foo, [Int : Foo?].Type)
525-
) -> (
526-
[Foo.Bar]
527-
) -> Foo
528-
>.matches(
529-
(
530-
( // expected-error {{expected type before '->'}}
531467
(P1) & Foo?.P2,
532468
Gen<Foo>.Bar,
533469
(Foo, [Int : Foo?].Type)
534470
) -> (
535-
[(Foo).Bar] // expected-error {{expected type before '->'}}
536-
) -> [Foo].Element // expected-error {{expected type after '->'}}
471+
[(Foo).Bar]
472+
) -> [Foo].Element
537473
).self
538474
)
539475
}

test/SILGen/default_arguments.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,11 +446,11 @@ enum E {
446446
// CHECK-LABEL: sil hidden [ossa] @$s17default_arguments1EO4testyyFZ : $@convention(method) (@thin E.Type) -> ()
447447
static func test() {
448448
// CHECK: function_ref @$s17default_arguments1EO6ResultV4name9platformsAESS_SaySiGtcfcfA0_ : $@convention(thin) () -> @owned Array<Int>
449-
// CHECK: function_ref @$s17default_arguments1EO4testyyFZAC6ResultVSS_SaySiGtcfu_ : $@convention(thin) (@guaranteed String, @guaranteed Array<Int>) -> @owned E.Result
449+
// CHECK: function_ref @$s17default_arguments1EO6ResultV4name9platformsAESS_SaySiGtcfC : $@convention(method) (@owned String, @owned Array<Int>, @thin E.Result.Type) -> @owned E.Result
450450

451-
// CHECK-LABEL: sil private [ossa] @$s17default_arguments1EO4testyyFZAC6ResultVSS_SaySiGtcfu_ : $@convention(thin) (@guaranteed String, @guaranteed Array<Int>) -> @owned E.Result
452451
var result = Self.Result(name: "")
453452
}
453+
// CHECK: end sil function '$s17default_arguments1EO4testyyFZ'
454454
}
455455

456456
// FIXME: Arguably we shouldn't allow calling a constructor like this, as

0 commit comments

Comments
 (0)