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