@@ -132,9 +132,7 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
132132 //
133133 // This occurs when a pair of rules are inherited from the property map
134134 // entry for this key's suffix.
135- auto pair = std::make_pair (concreteRuleID, conformanceRuleID);
136- auto found = ConcreteConformances.find (pair);
137- if (found != ConcreteConformances.end ())
135+ if (!checkRulePairOnce (concreteRuleID, conformanceRuleID))
138136 continue ;
139137
140138 // FIXME: Either remove the ModuleDecl entirely from conformance lookup,
@@ -164,40 +162,44 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
164162 continue ;
165163 }
166164
167- // FIXME: Maybe this can happen if the concrete type is an
168- // opaque result type?
169- assert (!conformance.isAbstract ());
170-
171- // Save this conformance for later.
172- auto *concrete = conformance.getConcrete ();
173- auto inserted = ConcreteConformances.insert (
174- std::make_pair (pair, concrete));
175- assert (inserted.second );
176- (void ) inserted;
177-
178165 auto concreteConformanceSymbol = Symbol::forConcreteConformance (
179166 concreteType, substitutions, proto, Context);
180167
181168 recordConcreteConformanceRule (concreteRuleID, conformanceRuleID,
182169 requirementKind, concreteConformanceSymbol);
183170
171+ // This is disabled by default because we fail to produce a convergent
172+ // rewrite system if the opaque archetype has infinitely-recursive
173+ // nested types. Fixing this requires a better representation for
174+ // concrete conformances in the rewrite system.
175+ if (conformance.isAbstract () &&
176+ !Context.getASTContext ().LangOpts .EnableRequirementMachineOpaqueArchetypes ) {
177+ if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
178+ llvm::dbgs () << " ^^ " << " Skipping abstract conformance of "
179+ << concreteType << " to " << proto->getName () << " \n " ;
180+ }
181+
182+ continue ;
183+ }
184+
184185 for (auto *assocType : proto->getAssociatedTypeMembers ()) {
185186 concretizeTypeWitnessInConformance (key, requirementKind,
186187 concreteConformanceSymbol,
187- concrete , assocType);
188+ conformance , assocType);
188189 }
189190
190191 // We only infer conditional requirements in top-level generic signatures,
191192 // not in protocol requirement signatures.
192- if (key.getRootProtocol () == nullptr )
193- inferConditionalRequirements (concrete, substitutions);
193+ if (conformance.isConcrete () &&
194+ key.getRootProtocol () == nullptr )
195+ inferConditionalRequirements (conformance.getConcrete (), substitutions);
194196 }
195197}
196198
197199void PropertyMap::concretizeTypeWitnessInConformance (
198200 Term key, RequirementKind requirementKind,
199201 Symbol concreteConformanceSymbol,
200- ProtocolConformance *concrete ,
202+ ProtocolConformanceRef conformance ,
201203 AssociatedTypeDecl *assocType) const {
202204 auto concreteType = concreteConformanceSymbol.getConcreteType ();
203205 auto substitutions = concreteConformanceSymbol.getSubstitutions ();
@@ -211,17 +213,35 @@ void PropertyMap::concretizeTypeWitnessInConformance(
211213 << " on " << concreteType << " \n " ;
212214 }
213215
214- auto t = concrete->getTypeWitness (assocType);
215- if (!t) {
216- if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
217- llvm::dbgs () << " ^^ " << " Type witness for " << assocType->getName ()
218- << " of " << concreteType << " could not be inferred\n " ;
216+ CanType typeWitness;
217+ if (conformance.isConcrete ()) {
218+ auto t = conformance.getConcrete ()->getTypeWitness (assocType);
219+
220+ if (!t) {
221+ if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
222+ llvm::dbgs () << " ^^ " << " Type witness for " << assocType->getName ()
223+ << " of " << concreteType << " could not be inferred\n " ;
224+ }
225+
226+ t = ErrorType::get (concreteType);
219227 }
220228
221- t = ErrorType::get (concreteType);
222- }
229+ typeWitness = t->getCanonicalType ();
230+ } else if (conformance.isAbstract ()) {
231+ auto archetype = concreteType->getAs <OpaqueTypeArchetypeType>();
232+ if (archetype == nullptr ) {
233+ llvm::errs () << " Should only have an abstract conformance with an "
234+ << " opaque archetype type\n " ;
235+ llvm::errs () << " Symbol: " << concreteConformanceSymbol << " \n " ;
236+ llvm::errs () << " Term: " << key << " \n " ;
237+ dump (llvm::errs ());
238+ abort ();
239+ }
223240
224- auto typeWitness = t->getCanonicalType ();
241+ typeWitness = archetype->getNestedType (assocType)->getCanonicalType ();
242+ } else if (conformance.isInvalid ()) {
243+ typeWitness = CanType (ErrorType::get (Context.getASTContext ()));
244+ }
225245
226246 if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
227247 llvm::dbgs () << " ^^ " << " Type witness for " << assocType->getName ()
0 commit comments