@@ -746,9 +746,30 @@ namespace {
746
746
// / to see if it's a valid parameter for integer arguments or other value
747
747
// / generic parameters.
748
748
class ValueMatchVisitor : public TypeMatcher <ValueMatchVisitor> {
749
- public:
750
749
ValueMatchVisitor () {}
751
750
751
+ public:
752
+ static bool check (ASTContext &ctx, Type paramTy, Type argTy,
753
+ SourceLoc loc) {
754
+ auto matcher = ValueMatchVisitor ();
755
+ if (argTy->hasError () || matcher.match (paramTy, argTy))
756
+ return false ;
757
+
758
+ // If the parameter is a value, then we're trying to substitute a
759
+ // non-value type like 'Int' or 'T' to our value.
760
+ if (paramTy->isValueParameter ()) {
761
+ ctx.Diags .diagnose (loc, diag::cannot_pass_type_for_value_generic,
762
+ argTy, paramTy);
763
+ } else {
764
+ // Otherwise, we're trying to use a value type (either an integer
765
+ // directly or another generic value parameter) for a non-value
766
+ // parameter.
767
+ ctx.Diags .diagnose (loc, diag::value_type_used_in_type_parameter,
768
+ argTy, paramTy);
769
+ }
770
+ return true ;
771
+ }
772
+
752
773
bool mismatch (TypeBase *firstType, TypeBase *secondType,
753
774
Type sugaredFirstType) {
754
775
return true ;
@@ -763,6 +784,12 @@ namespace {
763
784
if (secondType->is <PlaceholderType>())
764
785
return true ;
765
786
787
+ // For type variable substitutions, the constraint system should
788
+ // handle any mismatches (currently this only happens for unbound
789
+ // opening though).
790
+ if (secondType->isTypeVariableOrMember ())
791
+ return true ;
792
+
766
793
return false ;
767
794
}
768
795
@@ -1019,11 +1046,6 @@ static Type applyGenericArguments(Type type,
1019
1046
return ErrorType::get (ctx);
1020
1047
1021
1048
args.push_back (substTy);
1022
-
1023
- // The type we're binding to may not have value parameters, but one of the
1024
- // arguments may be a value parameter so diagnose this situation as well.
1025
- if (substTy->isValueParameter ())
1026
- hasValueParam = true ;
1027
1049
}
1028
1050
1029
1051
// Make sure we have the right number of generic arguments.
@@ -1093,31 +1115,6 @@ static Type applyGenericArguments(Type type,
1093
1115
}
1094
1116
}
1095
1117
1096
- if (hasValueParam) {
1097
- ValueMatchVisitor matcher;
1098
-
1099
- for (auto i : indices (genericParams->getParams ())) {
1100
- auto param = genericParams->getParams ()[i]->getDeclaredInterfaceType ();
1101
- auto arg = args[i];
1102
-
1103
- if (!matcher.match (param, arg)) {
1104
- // If the parameter is a value, then we're trying to substitute a
1105
- // non-value type like 'Int' or 'T' to our value.
1106
- if (param->isValueParameter ()) {
1107
- diags.diagnose (loc, diag::cannot_pass_type_for_value_generic, arg, param);
1108
- return ErrorType::get (ctx);
1109
-
1110
- // Otherwise, we're trying to use a value type (either an integer
1111
- // directly or another generic value parameter) for a non-value
1112
- // parameter.
1113
- } else {
1114
- diags.diagnose (loc, diag::value_type_used_in_type_parameter, arg, param);
1115
- return ErrorType::get (ctx);
1116
- }
1117
- }
1118
- }
1119
- }
1120
-
1121
1118
// Construct the substituted type.
1122
1119
const auto result = resolution.applyUnboundGenericArguments (
1123
1120
decl, unboundType->getParent (), loc, args);
@@ -1183,6 +1180,7 @@ Type TypeResolution::applyUnboundGenericArguments(
1183
1180
" invalid arguments, use applyGenericArguments to emit diagnostics "
1184
1181
" and collect arguments to pack generic parameters" );
1185
1182
1183
+ auto &ctx = getASTContext ();
1186
1184
TypeSubstitutionMap subs;
1187
1185
1188
1186
// Get the interface type for the declaration. We will be substituting
@@ -1241,12 +1239,16 @@ Type TypeResolution::applyUnboundGenericArguments(
1241
1239
auto innerParams = decl->getGenericParams ()->getParams ();
1242
1240
for (unsigned i : indices (innerParams)) {
1243
1241
auto origTy = innerParams[i]->getDeclaredInterfaceType ();
1244
- auto origGP = origTy->getCanonicalType ()->castTo <GenericTypeParamType>();
1242
+ auto paramTy = origTy->getCanonicalType ()->castTo <GenericTypeParamType>();
1245
1243
1246
1244
auto substTy = genericArgs[i];
1247
1245
1248
- // Enter a substitution.
1249
- subs[origGP] = substTy;
1246
+ // Ensure the value-ness of the argument matches the parameter.
1247
+ if (ValueMatchVisitor::check (ctx, origTy, substTy, loc))
1248
+ substTy = ErrorType::get (ctx);
1249
+
1250
+ // Enter the substitution.
1251
+ subs[paramTy] = substTy;
1250
1252
1251
1253
skipRequirementsCheck |=
1252
1254
substTy->hasTypeVariable () || substTy->hasUnboundGenericType ();
@@ -1289,13 +1291,13 @@ Type TypeResolution::applyUnboundGenericArguments(
1289
1291
if (loc.isValid ()) {
1290
1292
TypeChecker::diagnoseRequirementFailure (
1291
1293
result.getRequirementFailureInfo (), loc, noteLoc,
1292
- UnboundGenericType::get (decl, parentTy, getASTContext () ),
1294
+ UnboundGenericType::get (decl, parentTy, ctx ),
1293
1295
genericSig.getGenericParams (), substitutions);
1294
1296
}
1295
1297
1296
1298
LLVM_FALLTHROUGH;
1297
1299
case CheckRequirementsResult::SubstitutionFailure:
1298
- return ErrorType::get (getASTContext () );
1300
+ return ErrorType::get (ctx );
1299
1301
case CheckRequirementsResult::Success:
1300
1302
break ;
1301
1303
}
0 commit comments