@@ -7099,6 +7099,20 @@ static bool isTupleWithUnresolvedPackExpansion(Type type) {
70997099 return false;
71007100}
71017101
7102+ static bool isDependentMemberTypeWithBaseThatContainsUnresolvedPackExpansions(
7103+ ConstraintSystem &cs, Type type) {
7104+ if (!type->is<DependentMemberType>())
7105+ return false;
7106+
7107+ auto baseTy = cs.getFixedTypeRecursive(type->getDependentMemberRoot(),
7108+ /*wantRValue=*/true);
7109+ llvm::SmallPtrSet<TypeVariableType *, 2> typeVars;
7110+ baseTy->getTypeVariables(typeVars);
7111+ return llvm::any_of(typeVars, [](const TypeVariableType *typeVar) {
7112+ return typeVar->getImpl().isPackExpansion();
7113+ });
7114+ }
7115+
71027116ConstraintSystem::TypeMatchResult
71037117ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
71047118 TypeMatchOptions flags,
@@ -7135,7 +7149,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
71357149 //
71367150 // along any unsolved path. No other returns should produce
71377151 // SolutionKind::Unsolved or inspect TMF_GenerateConstraints.
7138- auto formUnsolvedResult = [&] {
7152+ auto formUnsolvedResult = [&](bool useOriginalTypes = false) {
71397153 // If we're supposed to generate constraints (i.e., this is a
71407154 // newly-generated constraint), do so now.
71417155 if (flags.contains(TMF_GenerateConstraints)) {
@@ -7144,8 +7158,13 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
71447158 // this new constraint will be solved at a later point.
71457159 // Obviously, this must not happen at the top level, or the
71467160 // algorithm would not terminate.
7147- addUnsolvedConstraint(Constraint::create(*this, kind, type1, type2,
7148- getConstraintLocator(locator)));
7161+ if (useOriginalTypes) {
7162+ addUnsolvedConstraint(Constraint::create(
7163+ *this, kind, origType1, origType2, getConstraintLocator(locator)));
7164+ } else {
7165+ addUnsolvedConstraint(Constraint::create(
7166+ *this, kind, type1, type2, getConstraintLocator(locator)));
7167+ }
71497168 return getTypeMatchSuccess();
71507169 }
71517170
@@ -7396,6 +7415,29 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
73967415 }
73977416 }
73987417
7418+ // Dependent members cannot be simplified if base type contains unresolved
7419+ // pack expansion type variables because they don't give enough information
7420+ // to substitution logic to form a correct type. For example:
7421+ //
7422+ // ```
7423+ // protocol P { associatedtype V }
7424+ // struct S<each T> : P { typealias V = (repeat (each T)?) }
7425+ // ```
7426+ //
7427+ // If pack expansion is represented as `$T1` and its pattern is `$T2`, a
7428+ // reference to `V` would get a type `S<Pack{$T}>.V` and simplified version
7429+ // would be `Optional<Pack{$T1}>` instead of `Pack{repeat Optional<$T2>}`
7430+ // because `$T1` is treated as a substitution for `each T` until bound.
7431+ if (isDependentMemberTypeWithBaseThatContainsUnresolvedPackExpansions(
7432+ *this, origType1) ||
7433+ isDependentMemberTypeWithBaseThatContainsUnresolvedPackExpansions(
7434+ *this, origType2)) {
7435+ // It's important to preserve the original types here because any attempt
7436+ // at simplification or canonicalization wouldn't produce a correct type
7437+ // util pack expansion type variables are bound.
7438+ return formUnsolvedResult(/*useOriginalTypes=*/true);
7439+ }
7440+
73997441 llvm::SmallVector<RestrictionOrFix, 4> conversionsOrFixes;
74007442
74017443 // Decompose parallel structure.
0 commit comments