@@ -162,33 +162,44 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
162162 continue ;
163163 }
164164
165- // FIXME: Maybe this can happen if the concrete type is an
166- // opaque result type?
167- assert (!conformance.isAbstract ());
168-
169165 auto concreteConformanceSymbol = Symbol::forConcreteConformance (
170166 concreteType, substitutions, proto, Context);
171167
172168 recordConcreteConformanceRule (concreteRuleID, conformanceRuleID,
173169 requirementKind, concreteConformanceSymbol);
174170
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+
175185 for (auto *assocType : proto->getAssociatedTypeMembers ()) {
176186 concretizeTypeWitnessInConformance (key, requirementKind,
177187 concreteConformanceSymbol,
178- concrete , assocType);
188+ conformance , assocType);
179189 }
180190
181191 // We only infer conditional requirements in top-level generic signatures,
182192 // not in protocol requirement signatures.
183- if (key.getRootProtocol () == nullptr )
184- inferConditionalRequirements (concrete, substitutions);
193+ if (conformance.isConcrete () &&
194+ key.getRootProtocol () == nullptr )
195+ inferConditionalRequirements (conformance.getConcrete (), substitutions);
185196 }
186197}
187198
188199void PropertyMap::concretizeTypeWitnessInConformance (
189200 Term key, RequirementKind requirementKind,
190201 Symbol concreteConformanceSymbol,
191- ProtocolConformance *concrete ,
202+ ProtocolConformanceRef conformance ,
192203 AssociatedTypeDecl *assocType) const {
193204 auto concreteType = concreteConformanceSymbol.getConcreteType ();
194205 auto substitutions = concreteConformanceSymbol.getSubstitutions ();
@@ -202,17 +213,35 @@ void PropertyMap::concretizeTypeWitnessInConformance(
202213 << " on " << concreteType << " \n " ;
203214 }
204215
205- auto t = concrete->getTypeWitness (assocType);
206- if (!t) {
207- if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
208- llvm::dbgs () << " ^^ " << " Type witness for " << assocType->getName ()
209- << " 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);
210227 }
211228
212- t = ErrorType::get (concreteType);
213- }
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+ }
214240
215- auto typeWitness = t->getCanonicalType ();
241+ typeWitness = archetype->getNestedType (assocType)->getCanonicalType ();
242+ } else if (conformance.isInvalid ()) {
243+ typeWitness = CanType (ErrorType::get (Context.getASTContext ()));
244+ }
216245
217246 if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
218247 llvm::dbgs () << " ^^ " << " Type witness for " << assocType->getName ()
0 commit comments