@@ -3156,55 +3156,91 @@ Type swift::checkMemberType(DeclContext &DC, Type BaseTy,
3156
3156
return Type ();
3157
3157
}
3158
3158
3159
- bool swift::isExtensionApplied (DeclContext &DC, Type BaseTy,
3160
- const ExtensionDecl *ED) {
3159
+ static ArrayRef<Identifier> getSubstitutableTypeNames (SubstitutableType *Ty,
3160
+ std::vector<Identifier> &Scratch,
3161
+ bool &IsSelfDependent) {
3162
+ IsSelfDependent = false ;
3163
+ for (auto Cur = Ty; Cur; Cur = Cur->getParent ()) {
3164
+ if (Cur->getName ().str () == " Self" ) {
3165
+ IsSelfDependent = true ;
3166
+ break ;
3167
+ }
3168
+ Scratch.insert (Scratch.begin (), Cur->getName ());
3169
+ }
3170
+ return llvm::makeArrayRef (Scratch);
3171
+ }
3161
3172
3162
- // We need to make sure the extension is about the give type decl.
3163
- bool FoundExtension = false ;
3164
- if (auto ND = BaseTy->getNominalOrBoundGenericNominal ()) {
3165
- for (auto ET : ND->getExtensions ()) {
3166
- if (ET == ED) {
3167
- FoundExtension = true ;
3168
- break ;
3169
- }
3173
+ static ArrayRef<Identifier> getDependentMemberNames (DependentMemberType *Dep,
3174
+ std::vector<Identifier> &Scratch,
3175
+ bool &IsSelfDependent) {
3176
+ DependentMemberType *Prev = nullptr ;
3177
+ IsSelfDependent = false ;
3178
+ for (DependentMemberType *Cur = Dep; Cur;
3179
+ Prev = Cur, Cur = Cur->getBase ()->getAs <DependentMemberType>()) {
3180
+ Scratch.insert (Scratch.begin (), Cur->getName ());
3181
+ Prev = Cur;
3182
+ }
3183
+ if (Type Base = Prev->getBase ()) {
3184
+ if (SubstitutableType *Sub = Base->getAs <SubstitutableType>()) {
3185
+ getSubstitutableTypeNames (Sub, Scratch, IsSelfDependent);
3170
3186
}
3171
3187
}
3172
- assert (FoundExtension && " Cannot find the extension. " );
3173
- ConstraintSystemOptions Options;
3188
+ return llvm::makeArrayRef (Scratch );
3189
+ }
3174
3190
3191
+ bool swift::isExtensionApplied (DeclContext &DC, Type BaseTy,
3192
+ const ExtensionDecl *ED) {
3193
+ ConstraintSystemOptions Options;
3194
+ NominalTypeDecl *Nominal = BaseTy->getNominalOrBoundGenericNominal ();
3195
+ if (!Nominal || !BaseTy->isSpecialized () ||
3196
+ ED->getGenericRequirements ().empty ())
3197
+ return true ;
3175
3198
std::unique_ptr<TypeChecker> CreatedTC;
3176
3199
// If the current ast context has no type checker, create one for it.
3177
3200
auto *TC = static_cast <TypeChecker*>(DC.getASTContext ().getLazyResolver ());
3178
3201
if (!TC) {
3179
3202
CreatedTC.reset (new TypeChecker (DC.getASTContext ()));
3180
3203
TC = CreatedTC.get ();
3181
3204
}
3182
-
3183
- // Build substitution map for the given type.
3184
- SmallVector<Type, 3 > Scratch;
3185
- auto genericArgs = BaseTy->getAllGenericArgs (Scratch);
3186
- TypeSubstitutionMap substitutions;
3187
- auto genericParams = BaseTy->getNominalOrBoundGenericNominal ()
3188
- ->getInnermostGenericParamTypes ();
3189
- assert (genericParams.size () == genericArgs.size ());
3190
- for (unsigned i = 0 , n = genericParams.size (); i != n; ++i) {
3191
- auto gp = genericParams[i]->getCanonicalType ()->castTo <GenericTypeParamType>();
3192
- substitutions[gp] = genericArgs[i];
3193
- }
3194
3205
ConstraintSystem CS (*TC, &DC, Options);
3195
3206
auto Loc = CS.getConstraintLocator (nullptr );
3196
- if (ED->getGenericRequirements ().empty ())
3197
- return true ;
3207
+ std::vector<Identifier> Scratch;
3208
+ bool Failed = false ;
3209
+ SmallVector<Type, 3 > TypeScratch;
3210
+
3211
+ // Prepare type substitution map.
3212
+ auto GenericArgs = BaseTy->getAllGenericArgs (TypeScratch);
3213
+ TypeSubstitutionMap Substitutions;
3214
+ auto GenericParams = Nominal->getInnermostGenericParamTypes ();
3215
+ assert (GenericParams.size () == GenericArgs.size ());
3216
+ for (unsigned I = 0 , N = GenericParams.size (); I != N; ++I) {
3217
+ auto GP = GenericParams[I]->getCanonicalType ()->castTo <GenericTypeParamType>();
3218
+ Substitutions[GP] = GenericArgs[I];
3219
+ }
3220
+ auto resolveType = [&](Type Ty) {
3221
+ ArrayRef<Identifier> Names;
3222
+ bool IsSelfDependent = false ;
3223
+ if (SubstitutableType *Sub = Ty->getAs <SubstitutableType>()) {
3224
+ Scratch.clear ();
3225
+ Names = getSubstitutableTypeNames (Sub, Scratch, IsSelfDependent);
3226
+ } else if (DependentMemberType *Dep = Ty->getAs <DependentMemberType>()) {
3227
+ Scratch.clear ();
3228
+ Names = getDependentMemberNames (Dep, Scratch, IsSelfDependent);
3229
+ } else
3230
+ return Ty;
3231
+ return IsSelfDependent ? checkMemberType (DC, BaseTy, Names)
3232
+ :Ty.subst (DC.getParentModule (), Substitutions,
3233
+ SubstFlags::IgnoreMissing);
3234
+ };
3198
3235
auto createMemberConstraint = [&](Requirement &Req, ConstraintKind Kind) {
3199
-
3200
- // Use the substitution map of the given type to substitute the parameter of
3201
- // the extension.
3202
- auto First = Req. getFirstType (). subst (ED-> getParentModule (), substitutions,
3203
- SubstFlags::IgnoreMissing) ;
3204
-
3236
+ auto First = resolveType (Req. getFirstType ());
3237
+ auto Second = resolveType (Req. getSecondType ());
3238
+ if (First. isNull () || Second. isNull ()) {
3239
+ Failed = true ;
3240
+ return ;
3241
+ }
3205
3242
// Add constraints accordingly.
3206
- CS.addConstraint (Constraint::create (CS, Kind, First, Req.getSecondType (),
3207
- DeclName (), Loc));
3243
+ CS.addConstraint (Constraint::create (CS, Kind, First, Second, DeclName (), Loc));
3208
3244
};
3209
3245
3210
3246
// For every requirement, add a constraint.
@@ -3223,6 +3259,8 @@ bool swift::isExtensionApplied(DeclContext &DC, Type BaseTy,
3223
3259
break ;
3224
3260
}
3225
3261
}
3262
+ if (Failed)
3263
+ return true ;
3226
3264
3227
3265
// Having a solution implies the extension's requirements have been fulfilled.
3228
3266
return CS.solveSingle ().hasValue ();
0 commit comments