Skip to content

Commit 4625f4a

Browse files
authored
Merge pull request #41958 from slavapestov/type-matcher-opaque-archetype
AST: TypeMatcher needs to recurse into OpaqueTypeArchetypeTypes
2 parents 4e99cca + 02e4027 commit 4625f4a

File tree

4 files changed

+88
-11
lines changed

4 files changed

+88
-11
lines changed

include/swift/AST/TypeMatcher.h

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,8 @@ class TypeMatcher {
181181

182182
bool visitReferenceStorageType(CanReferenceStorageType firstStorage,
183183
Type secondType, Type sugaredFirstType) {
184-
auto _secondStorage = secondType->getCanonicalType();
185-
if (firstStorage->getKind() == _secondStorage->getKind()) {
186-
auto secondStorage = cast<ReferenceStorageType>(_secondStorage);
184+
if (firstStorage->getKind() == secondType->getDesugaredType()->getKind()) {
185+
auto secondStorage = secondType->castTo<ReferenceStorageType>();
187186
return this->visit(firstStorage.getReferentType(),
188187
secondStorage->getReferentType(),
189188
sugaredFirstType->castTo<ReferenceStorageType>()
@@ -195,9 +194,8 @@ class TypeMatcher {
195194

196195
bool visitNominalType(CanNominalType firstNominal,
197196
Type secondType, Type sugaredFirstType) {
198-
auto _secondNominal = secondType->getCanonicalType();
199-
if (firstNominal->getKind() == _secondNominal->getKind()) {
200-
auto secondNominal = cast<NominalType>(_secondNominal);
197+
if (firstNominal->getKind() == secondType->getDesugaredType()->getKind()) {
198+
auto secondNominal = secondType->castTo<NominalType>();
201199
if (firstNominal->getDecl() != secondNominal->getDecl())
202200
return mismatch(firstNominal.getPointer(), secondNominal,
203201
sugaredFirstType);
@@ -216,9 +214,8 @@ class TypeMatcher {
216214

217215
bool visitAnyMetatypeType(CanAnyMetatypeType firstMeta,
218216
Type secondType, Type sugaredFirstType) {
219-
auto _secondMeta = secondType->getCanonicalType();
220-
if (firstMeta->getKind() == _secondMeta->getKind()) {
221-
auto secondMeta = cast<AnyMetatypeType>(_secondMeta);
217+
if (firstMeta->getKind() == secondType->getDesugaredType()->getKind()) {
218+
auto secondMeta = secondType->castTo<AnyMetatypeType>();
222219
return this->visit(firstMeta.getInstanceType(),
223220
secondMeta->getInstanceType(),
224221
sugaredFirstType->castTo<AnyMetatypeType>()
@@ -229,7 +226,41 @@ class TypeMatcher {
229226
}
230227

231228
TRIVIAL_CASE(ModuleType)
232-
TRIVIAL_CASE(ArchetypeType)
229+
230+
bool visitArchetypeType(CanArchetypeType firstArchetype,
231+
Type secondType,
232+
Type sugaredFirstType) {
233+
if (auto firstOpaqueArchetype = dyn_cast<OpaqueTypeArchetypeType>(firstArchetype)) {
234+
if (auto secondOpaqueArchetype = secondType->getAs<OpaqueTypeArchetypeType>()) {
235+
if (firstOpaqueArchetype->getDecl() == secondOpaqueArchetype->getDecl()) {
236+
auto firstSubMap = firstOpaqueArchetype->getSubstitutions();
237+
auto secondSubMap = secondOpaqueArchetype->getSubstitutions();
238+
assert(firstSubMap.getReplacementTypes().size() ==
239+
secondSubMap.getReplacementTypes().size());
240+
241+
for (unsigned i : indices(firstSubMap.getReplacementTypes())) {
242+
auto firstSubstType = firstSubMap.getReplacementTypes()[i];
243+
auto secondSubstType = secondSubMap.getReplacementTypes()[i];
244+
245+
if (!this->visit(firstSubstType->getCanonicalType(),
246+
secondSubstType, firstSubstType))
247+
return false;
248+
}
249+
250+
return true;
251+
}
252+
}
253+
}
254+
255+
// FIXME: Once OpenedArchetypeType stores substitutions, do something
256+
// similar to the above.
257+
258+
if (firstArchetype->isEqual(secondType))
259+
return true;
260+
261+
262+
return mismatch(firstArchetype.getPointer(), secondType, sugaredFirstType);
263+
}
233264

234265
bool visitDynamicSelfType(CanDynamicSelfType firstDynamicSelf,
235266
Type secondType,

lib/AST/RequirementMachine/Symbol.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,8 @@ void Symbol::dump(llvm::raw_ostream &out) const {
658658

659659
PrintOptions opts;
660660
opts.AlternativeTypeNames = &substitutionNames;
661+
opts.OpaqueReturnTypePrinting =
662+
PrintOptions::OpaqueReturnTypePrintingMode::StableReference;
661663

662664
switch (getKind()) {
663665
case Kind::Name:

test/Generics/opaque_archetype_concrete_requirement.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,5 @@ protocol HasRecursiveP {
7777

7878
extension HasRecursiveP where T == DefinesRecursiveP.T {}
7979
// expected-error@-1 {{cannot build rewrite system for generic signature; rule length limit exceeded}}
80-
// expected-note@-2 {{failed rewrite rule is τ_0_0.[HasRecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[concrete: ((((((((((some RecursiveP).T).T).T).T).T).T).T).T).T).T] => τ_0_0.[HasRecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T]}}
80+
// expected-note@-2 {{failed rewrite rule is τ_0_0.[HasRecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[concrete: (((((((((@_opaqueReturnTypeOf("$s37opaque_archetype_concrete_requirement17DefinesRecursivePV1tQrvp", 0) __.T).T).T).T).T).T).T).T).T).T] => τ_0_0.[HasRecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T].[RecursiveP:T]}}
8181

test/Generics/sr16040.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: %target-swift-frontend -typecheck %s -disable-availability-checking -debug-generic-signatures 2>&1 | %FileCheck %s
2+
3+
public protocol View {
4+
associatedtype Body : View
5+
var body: Body { get }
6+
}
7+
8+
public struct Text : View {
9+
public init(_: String) {}
10+
public var body: Self { return self }
11+
}
12+
13+
public protocol DisplayableValue {}
14+
15+
public protocol SingleValueDisplay: View {
16+
associatedtype DisplayedValue
17+
init (_ singleValue: DisplayedValue)
18+
var displayedValue: DisplayedValue { get }
19+
}
20+
21+
// CHECK-LABEL: .RawDisplayableValue@
22+
// CHECK-NEXT: Requirement signature: <Self where Self : DisplayableValue, Self == Self.[RawDisplayableValue]RawDisplay.[SingleValueDisplay]DisplayedValue, Self.[RawDisplayableValue]RawDisplay : SingleValueDisplay>
23+
public protocol RawDisplayableValue: DisplayableValue {
24+
associatedtype RawDisplay: SingleValueDisplay
25+
where RawDisplay.DisplayedValue == Self
26+
}
27+
28+
// CHECK-LABEL: .RawTextDisplayableValue@
29+
// CHECK-NEXT: Requirement signature: <Self where Self : CustomStringConvertible, Self : RawDisplayableValue, Self.[RawDisplayableValue]RawDisplay == RawTextDisplay<Self>>
30+
public protocol RawTextDisplayableValue: RawDisplayableValue
31+
where Self: CustomStringConvertible,
32+
RawDisplay == RawTextDisplay<Self> { }
33+
34+
public struct RawTextDisplay <Value: CustomStringConvertible>: SingleValueDisplay {
35+
public var displayedValue: Value
36+
37+
public init (_ singleValue: Value) {
38+
self.displayedValue = singleValue
39+
}
40+
41+
public var body: some View {
42+
Text(displayedValue.description)
43+
}
44+
}

0 commit comments

Comments
 (0)