@@ -61,10 +61,6 @@ void RequirementSource::dump(llvm::raw_ostream &out,
6161 out << " inferred" ;
6262 break ;
6363
64- case OuterScope:
65- out << " outer" ;
66- break ;
67-
6864 case Inherited:
6965 out << " inherited" ;
7066 break ;
@@ -685,7 +681,6 @@ ArchetypeBuilder::PotentialArchetype::getType(ArchetypeBuilder &builder) {
685681 switch (conforms.second .getKind ()) {
686682 case RequirementSource::Explicit:
687683 case RequirementSource::Inferred:
688- case RequirementSource::OuterScope:
689684 case RequirementSource::Protocol:
690685 case RequirementSource::Redundant:
691686 Protos.push_back (conforms.first );
@@ -993,6 +988,21 @@ bool ArchetypeBuilder::addSuperclassRequirement(PotentialArchetype *T,
993988 });
994989 }
995990
991+ // Make sure the concrete type fulfills the superclass requirement
992+ // of the archetype.
993+ if (T->isConcreteType ()) {
994+ Type concrete = T->getConcreteType ();
995+ if (!Superclass->isExactSuperclassOf (concrete, getLazyResolver ())) {
996+ Diags.diagnose (T->getSameTypeSource ().getLoc (),
997+ diag::type_does_not_inherit,
998+ T->getRootParam (), concrete, Superclass)
999+ .highlight (Source.getLoc ());
1000+ return true ;
1001+ }
1002+
1003+ return false ;
1004+ }
1005+
9961006 // Local function to handle the update of superclass conformances
9971007 // when the superclass constraint changes.
9981008 auto updateSuperclassConformances = [&] {
@@ -1257,7 +1267,7 @@ bool ArchetypeBuilder::addSameTypeRequirementToConcrete(
12571267 }
12581268
12591269 // Make sure the concrete type fulfills the requirements on the archetype.
1260- DenseMap<ProtocolDecl *, ProtocolConformance* > conformances;
1270+ DenseMap<ProtocolDecl *, ProtocolConformanceRef > conformances;
12611271 if (!Concrete->is <ArchetypeType>()) {
12621272 for (auto conforms : T->getConformsTo ()) {
12631273 auto protocol = conforms.first ;
@@ -1270,16 +1280,27 @@ bool ArchetypeBuilder::addSameTypeRequirementToConcrete(
12701280 return true ;
12711281 }
12721282
1273- assert (conformance->isConcrete () && " Abstract conformance?" );
1274- conformances[protocol] = conformance->getConcrete ();
1283+ conformances.insert ({protocol, *conformance});
12751284 }
12761285 }
12771286
12781287 // Record the requirement.
12791288 T->ArchetypeOrConcreteType = NestedType::forConcreteType (Concrete);
12801289 T->SameTypeSource = Source;
12811290
1291+ // Make sure the concrete type fulfills the superclass requirement
1292+ // of the archetype.
1293+ if (T->Superclass ) {
1294+ if (!T->Superclass ->isExactSuperclassOf (Concrete, getLazyResolver ())) {
1295+ Diags.diagnose (Source.getLoc (), diag::type_does_not_inherit,
1296+ T->getRootParam (), Concrete, T->Superclass )
1297+ .highlight (T->SuperclassSource ->getLoc ());
1298+ return true ;
1299+ }
1300+ }
1301+
12821302 // Recursively resolve the associated types to their concrete types.
1303+ RequirementSource nestedSource (RequirementSource::Redundant, Source.getLoc ());
12831304 for (auto nested : T->getNestedTypes ()) {
12841305 AssociatedTypeDecl *assocType
12851306 = nested.second .front ()->getResolvedAssociatedType ();
@@ -1288,21 +1309,28 @@ bool ArchetypeBuilder::addSameTypeRequirementToConcrete(
12881309 concreteArchetype->getNestedType (nested.first );
12891310 addSameTypeRequirementToConcrete (nested.second .front (),
12901311 witnessType.getValue (),
1291- Source );
1312+ nestedSource );
12921313 } else {
12931314 assert (conformances.count (assocType->getProtocol ()) > 0
12941315 && " missing conformance?" );
1295- auto witness = conformances[assocType->getProtocol ()]
1296- ->getTypeWitness (assocType, getLazyResolver ());
1297- auto witnessType = witness.getReplacement ();
1316+ auto conformance = conformances.find (assocType->getProtocol ())->second ;
1317+ Type witnessType;
1318+ if (conformance.isConcrete ()) {
1319+ witnessType = conformance.getConcrete ()
1320+ ->getTypeWitness (assocType, getLazyResolver ())
1321+ .getReplacement ();
1322+ } else {
1323+ witnessType = DependentMemberType::get (Concrete, assocType);
1324+ }
1325+
12981326 if (auto witnessPA = resolveArchetype (witnessType)) {
12991327 addSameTypeRequirementBetweenArchetypes (nested.second .front (),
13001328 witnessPA,
1301- Source );
1329+ nestedSource );
13021330 } else {
13031331 addSameTypeRequirementToConcrete (nested.second .front (),
13041332 witnessType,
1305- Source );
1333+ nestedSource );
13061334 }
13071335 }
13081336 }
@@ -2010,14 +2038,10 @@ ArchetypeBuilder::mapTypeOutOfContext(ModuleDecl *M,
20102038}
20112039
20122040void ArchetypeBuilder::addGenericSignature (GenericSignature *sig,
2013- GenericEnvironment *env,
2014- bool treatRequirementsAsExplicit) {
2041+ GenericEnvironment *env) {
20152042 if (!sig) return ;
20162043
2017- RequirementSource::Kind sourceKind = treatRequirementsAsExplicit
2018- ? RequirementSource::Explicit
2019- : RequirementSource::OuterScope;
2020-
2044+ RequirementSource::Kind sourceKind = RequirementSource::Explicit;
20212045 for (auto param : sig->getGenericParams ()) {
20222046 addGenericParameter (param);
20232047
@@ -2057,7 +2081,6 @@ static void collectRequirements(ArchetypeBuilder &builder,
20572081 switch (source.getKind ()) {
20582082 case RequirementSource::Explicit:
20592083 case RequirementSource::Inferred:
2060- case RequirementSource::OuterScope:
20612084 // The requirement was explicit and required, keep it.
20622085 break ;
20632086
0 commit comments