@@ -4009,7 +4009,21 @@ namespace Slang
4009
4009
{
4010
4010
// For now the "solver" is going to be ridiculously simplistic.
4011
4011
4012
- // The generic itself will have some constraints, so we need to try and solve those too
4012
+ // The generic itself will have some constraints, and for now we add these
4013
+ // to the system of constrains we will use for solving for the type variables.
4014
+ //
4015
+ // TODO: we need to decide whether constraints are used like this to influence
4016
+ // how we solve for type/value variables, or whether constraints in the parameter
4017
+ // list just work as a validation step *after* we've solved for the types.
4018
+ //
4019
+ // That is, should we allow `<T : Int>` to be written, and cause us to "infer"
4020
+ // that `T` should be the type `Int`? That seems a little silly.
4021
+ //
4022
+ // Eventually, though, we may want to support type identity constraints, especially
4023
+ // on associated types, like `<C where C : IContainer && C.IndexType == Int>`
4024
+ // These seem more reasonable to have influence constraint solving, since it could
4025
+ // conceivably let us specialize a `X<T> : IContainer` to `X<Int>` if we find
4026
+ // that `X<T>.IndexType == T`.
4013
4027
for ( auto constraintDeclRef : getMembersOfType<GenericTypeConstraintDecl>(genericDeclRef) )
4014
4028
{
4015
4029
if (!TryUnifyTypes (*system , GetSub (constraintDeclRef), GetSup (constraintDeclRef)))
@@ -4101,6 +4115,57 @@ namespace Slang
4101
4115
}
4102
4116
}
4103
4117
4118
+ // After we've solved for the explicit arguments, we need to
4119
+ // make a second pass and consider the implicit arguments,
4120
+ // based on what we've already determined to be the values
4121
+ // for the explicit arguments.
4122
+
4123
+ // Before we begin, we are going to go ahead and create the
4124
+ // "solved" substitution that we will return if everything works.
4125
+ // This is because we are going to use this substitution,
4126
+ // partially filled in with the results we know so far,
4127
+ // in order to specialize any constraints on the generic.
4128
+ //
4129
+ // E.g., if the generic parameters were `<T : ISidekick>`, and
4130
+ // we've already decided that `T` is `Robin`, then we want to
4131
+ // search for a conformance `Robin : ISidekick`, which involved
4132
+ // apply the substitutions we already know...
4133
+
4134
+ RefPtr<GenericSubstitution> solvedSubst = new GenericSubstitution ();
4135
+ solvedSubst->genericDecl = genericDeclRef.getDecl ();
4136
+ solvedSubst->outer = genericDeclRef.substitutions ;
4137
+ solvedSubst->args = args;
4138
+
4139
+ for ( auto constraintDecl : genericDeclRef.getDecl ()->getMembersOfType <GenericTypeConstraintDecl>() )
4140
+ {
4141
+ DeclRef<GenericTypeConstraintDecl> constraintDeclRef (
4142
+ constraintDecl,
4143
+ solvedSubst);
4144
+
4145
+ // Extract the (substituted) sub- and super-type from the constraint.
4146
+ auto sub = GetSub (constraintDeclRef);
4147
+ auto sup = GetSup (constraintDeclRef);
4148
+
4149
+ // Search for a witness that shows the constraint is satisfied.
4150
+ auto subTypeWitness = tryGetSubtypeWitness (sub, sup);
4151
+ if (subTypeWitness)
4152
+ {
4153
+ // We found a witness, so it will become an (implicit) argument.
4154
+ solvedSubst->args .Add (subTypeWitness);
4155
+ }
4156
+ else
4157
+ {
4158
+ // No witness was found, so the inference will now fail.
4159
+ //
4160
+ // TODO: Ideally we should print an error message in
4161
+ // this case, to let the user know why things failed.
4162
+ return nullptr ;
4163
+ }
4164
+
4165
+ // TODO: We may need to mark some constrains in our constraint
4166
+ // system as being solved now, as a result of the witness we found.
4167
+ }
4168
+
4104
4169
// Make sure we haven't constructed any spurious constraints
4105
4170
// that we aren't able to satisfy:
4106
4171
for (auto c : system ->constraints )
@@ -4111,13 +4176,6 @@ namespace Slang
4111
4176
}
4112
4177
}
4113
4178
4114
- // Consruct a reference to the extension with our constraint variables
4115
- // as the
4116
- RefPtr<GenericSubstitution> solvedSubst = new GenericSubstitution ();
4117
- solvedSubst->genericDecl = genericDeclRef.getDecl ();
4118
- solvedSubst->outer = genericDeclRef.substitutions ;
4119
- solvedSubst->args = args;
4120
-
4121
4179
return solvedSubst;
4122
4180
}
4123
4181
0 commit comments