Skip to content
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
6 changes: 3 additions & 3 deletions include/swift/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -1340,9 +1340,9 @@ class TypeExpr : public Expr {
TypeDecl *Decl);

/// Create a \c TypeExpr for a member \c TypeDecl of the given parent
/// \c DeclRefTypeRepr.
static TypeExpr *createForMemberDecl(DeclRefTypeRepr *ParentTR,
DeclNameLoc NameLoc, TypeDecl *Decl);
/// \c TypeRepr.
static TypeExpr *createForMemberDecl(TypeRepr *ParentTR, DeclNameLoc NameLoc,
TypeDecl *Decl);

/// Create a \c TypeExpr from an \c DeclRefTypeRepr with the given arguments
/// applied at the specified location.
Expand Down
29 changes: 17 additions & 12 deletions lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2224,24 +2224,29 @@ TypeExpr *TypeExpr::createForMemberDecl(DeclNameLoc ParentNameLoc,
return new (C) TypeExpr(TR);
}

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

// Create a new list of components.
SmallVector<IdentTypeRepr *, 2> Components;
if (auto *MemberTR = dyn_cast<MemberTypeRepr>(ParentTR)) {
auto MemberComps = MemberTR->getMemberComponents();
Components.append(MemberComps.begin(), MemberComps.end());
}

// Add a new component for the member we just found.
auto *NewComp = new (C) SimpleIdentTypeRepr(NameLoc, Decl->createNameRef());
NewComp->setValue(Decl, nullptr);
Components.push_back(NewComp);

auto *TR =
MemberTypeRepr::create(C, ParentTR->getBaseComponent(), Components);
TypeRepr *TR = nullptr;
if (auto *DeclRefTR = dyn_cast<DeclRefTypeRepr>(ParentTR)) {
// Create a new list of components.
SmallVector<IdentTypeRepr *, 4> Components;
if (auto *MemberTR = dyn_cast<MemberTypeRepr>(ParentTR)) {
auto MemberComps = MemberTR->getMemberComponents();
Components.append(MemberComps.begin(), MemberComps.end());
}

Components.push_back(NewComp);
TR = MemberTypeRepr::create(C, DeclRefTR->getBaseComponent(), Components);
} else {
TR = MemberTypeRepr::create(C, ParentTR, NewComp);
}

return new (C) TypeExpr(TR);
}

Expand Down
50 changes: 24 additions & 26 deletions lib/Sema/PreCheckExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1429,33 +1429,31 @@ TypeExpr *PreCheckExpression::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) {
}

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

if (BaseTy->mayHaveMembers()) {
// See if there is a member type with this name.
auto Result =
TypeChecker::lookupMemberType(DC, BaseTy, Name,
defaultMemberLookupOptions);

// If there is no nested type with this name, we have a lookup of
// a non-type member, so leave the expression as-is.
if (Result.size() == 1) {
return TypeExpr::createForMemberDecl(DeclRefTR, UDE->getNameLoc(),
Result.front().Member);
}
// Resolve the TypeRepr to get the base type for the lookup.
const auto BaseTy = TypeResolution::resolveContextualType(
InnerTypeRepr, DC, TypeResolverContext::InExpression,
[](auto unboundTy) {
// FIXME: Don't let unbound generic types escape type resolution.
// For now, just return the unbound generic type.
return unboundTy;
},
// FIXME: Don't let placeholder types escape type resolution.
// For now, just return the placeholder type.
PlaceholderType::get,
// TypeExpr pack elements are opened in CSGen.
/*packElementOpener*/ nullptr);

if (BaseTy->mayHaveMembers()) {
// See if there is a member type with this name.
auto Result = TypeChecker::lookupMemberType(DC, BaseTy, Name,
defaultMemberLookupOptions);

// If there is no nested type with this name, we have a lookup of
// a non-type member, so leave the expression as-is.
if (Result.size() == 1) {
return TypeExpr::createForMemberDecl(InnerTypeRepr, UDE->getNameLoc(),
Result.front().Member);
}
}

Expand Down
7 changes: 1 addition & 6 deletions lib/Sema/TypeCheckRuntimeMetadataAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,7 @@ static TypeRepr *buildTypeRepr(DeclContext *typeContext,
// Reverse the components to form a valid outer-to-inner name sequence.
std::reverse(components.begin(), components.end());

TypeRepr *typeRepr = nullptr;
if (components.size() == 1) {
typeRepr = components.front();
} else {
typeRepr = MemberTypeRepr::create(ctx, components);
}
TypeRepr *typeRepr = MemberTypeRepr::create(ctx, components);

if (forMetatype)
return new (ctx) MetatypeTypeRepr(typeRepr, /*MetaLoc=*/SourceLoc());
Expand Down
70 changes: 3 additions & 67 deletions test/Parse/type_expr.swift
Original file line number Diff line number Diff line change
Expand Up @@ -344,18 +344,10 @@ func compositionType() {

CheckType<P1 & P2>.matches(((P1) & (P2)).self)
CheckType<P1 & P2>.matches((Foo.P1 & Foo.P2).self)
// FIXME: Teach Sema to recognize this type expression.
// 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')}}
CheckType<P1 & P2>.matches(((Foo).P1 & (Foo).P2).self)
CheckType<P1 & P2>.matches((Gen<Foo>.P1 & Gen<Foo>.P2).self)
// FIXME: Teach Sema to recognize this type expression.
// 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')}}
CheckType<P1 & P2>.matches((Foo?.P1 & Foo?.P2).self)
// FIXME: Teach Sema to recognize this type expression.
// 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')}}
CheckType<P1 & P2>.matches(([Foo].P1 & [Foo].P2).self)
// FIXME: Teach Sema to recognize this type expression.
// 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')}}
CheckType<P1 & P2>.matches(([Int : Foo].P1 & [Int : Foo].P2).self)
}

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

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

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

CheckType<(Gen<Foo>.Bar, Gen<Foo>.Bar)>.matches((Gen<Foo>.Bar, Gen<Foo>.Bar).self)
// FIXME: Teach Sema to recognize this type expression.
// 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'}}
CheckType<(Foo, Foo)>.matches((Foo?.Wrapped, Foo?.Wrapped).self)
// FIXME: Teach Sema to recognize this type expression.
// 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'}}
CheckType<(Foo, Foo)>.matches(([Foo].Element, [Foo].Element).self)
// FIXME: Teach Sema to recognize this type expression.
// 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'}}
CheckType<(Foo, Foo)>.matches(([Int : Foo].Value, [Int : Foo].Value).self)

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

// Trade exhaustivity for one complex test case.
// FIXME: Replace this with the next test once we make it succeed.
CheckType<
(
(Gen<Foo>.Bar) -> P1 & P2,
Expand All @@ -411,24 +394,7 @@ func tupleType() {
)
>.matches(
(
(Gen<Foo>.Bar) -> (P1) & Optional<Foo>.P2,
(Foo.Bar, [Int : Foo?].Type),
[Gen<Foo>.Bar],
Array<Foo.Bar.Baz>.Element
).self
)

// FIXME: Teach Sema to recognize this type expression.
CheckType<
(
(Gen<Foo>.Bar) -> P1 & P2,
(Foo.Bar, [Int : Foo?].Type),
[Gen<Foo>.Bar],
Foo.Bar.Baz
)
>.matches(
( // 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'}}
(Gen<Foo>.Bar) -> (P1) & Foo?.P2, // expected-error {{expected type after '->'}}
(Gen<Foo>.Bar) -> (P1) & Foo?.P2,
(Foo.Bar, [Int : Foo?].Type),
[(Gen<Foo>).Bar],
[Foo.Bar.Baz].Element
Expand Down Expand Up @@ -466,8 +432,6 @@ func functionType() {
CheckType<(Foo) -> Foo>.matches((((Foo)) -> (Foo)).self)

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

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

CheckType<(Gen<Foo>.Bar) -> Gen<Foo>.Bar>.matches(((Gen<Foo>.Bar) -> Gen<Foo>.Bar).self)
// FIXME: Teach Sema to recognize this type expression.
// expected-error@+1 {{expected type before '->'}} expected-error@+1 {{expected type after '->'}}
CheckType<(Foo) -> Foo>.matches(((Foo?.Wrapped) -> Foo?.Wrapped).self)
// FIXME: Teach Sema to recognize this type expression.
// expected-error@+1 {{expected type before '->'}} expected-error@+1 {{expected type after '->'}}
CheckType<(Foo) -> Foo>.matches((([Foo].Element) -> [Foo].Element).self)
// FIXME: Teach Sema to recognize this type expression.
// expected-error@+1 {{expected type before '->'}} expected-error@+1 {{expected type after '->'}}
CheckType<(Foo) -> Foo>.matches((([Int : Foo].Value) -> [Int : Foo].Value).self)

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

// Trade exhaustivity for one complex test case.
// FIXME: Replace this with the next test once we make it succeed.
CheckType<
(
P1 & P2,
Expand All @@ -507,33 +464,12 @@ func functionType() {
>.matches(
(
(
(P1) & Optional<Foo>.P2,
Gen<Foo>.Bar,
(Foo, [Int : Foo?].Type)
) -> (
[Foo.Bar]
) -> Array<Foo>.Element
).self
)

// FIXME: Teach Sema to recognize this type expression.
CheckType<
(
P1 & P2,
Gen<Foo>.Bar,
(Foo, [Int : Foo?].Type)
) -> (
[Foo.Bar]
) -> Foo
>.matches(
(
( // expected-error {{expected type before '->'}}
(P1) & Foo?.P2,
Gen<Foo>.Bar,
(Foo, [Int : Foo?].Type)
) -> (
[(Foo).Bar] // expected-error {{expected type before '->'}}
) -> [Foo].Element // expected-error {{expected type after '->'}}
[(Foo).Bar]
) -> [Foo].Element
).self
)
}
Expand Down
4 changes: 2 additions & 2 deletions test/SILGen/default_arguments.swift
Original file line number Diff line number Diff line change
Expand Up @@ -446,11 +446,11 @@ enum E {
// CHECK-LABEL: sil hidden [ossa] @$s17default_arguments1EO4testyyFZ : $@convention(method) (@thin E.Type) -> ()
static func test() {
// CHECK: function_ref @$s17default_arguments1EO6ResultV4name9platformsAESS_SaySiGtcfcfA0_ : $@convention(thin) () -> @owned Array<Int>
// CHECK: function_ref @$s17default_arguments1EO4testyyFZAC6ResultVSS_SaySiGtcfu_ : $@convention(thin) (@guaranteed String, @guaranteed Array<Int>) -> @owned E.Result
// CHECK: function_ref @$s17default_arguments1EO6ResultV4name9platformsAESS_SaySiGtcfC : $@convention(method) (@owned String, @owned Array<Int>, @thin E.Result.Type) -> @owned E.Result

// CHECK-LABEL: sil private [ossa] @$s17default_arguments1EO4testyyFZAC6ResultVSS_SaySiGtcfu_ : $@convention(thin) (@guaranteed String, @guaranteed Array<Int>) -> @owned E.Result
var result = Self.Result(name: "")
}
// CHECK: end sil function '$s17default_arguments1EO4testyyFZ'
}
Comment on lines 447 to 454
Copy link
Collaborator Author

@AnthonyLatsis AnthonyLatsis Feb 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minus a thunk here because Self.Result is now folded into a type expression. It used to not because TypeExpr::createForMemberDecl accepted only a DeclRefTypeRepr parent, and Self in expression context becomes a FixedTypeRepr, not an identifier type representation.


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