@@ -3970,7 +3970,21 @@ namespace Slang
3970
3970
{
3971
3971
// For now the "solver" is going to be ridiculously simplistic.
3972
3972
3973
- // The generic itself will have some constraints, so we need to try and solve those too
3973
+ // The generic itself will have some constraints, and for now we add these
3974
+ // to the system of constrains we will use for solving for the type variables.
3975
+ //
3976
+ // TODO: we need to decide whether constraints are used like this to influence
3977
+ // how we solve for type/value variables, or whether constraints in the parameter
3978
+ // list just work as a validation step *after* we've solved for the types.
3979
+ //
3980
+ // That is, should we allow `<T : Int>` to be written, and cause us to "infer"
3981
+ // that `T` should be the type `Int`? That seems a little silly.
3982
+ //
3983
+ // Eventually, though, we may want to support type identity constraints, especially
3984
+ // on associated types, like `<C where C : IContainer && C.IndexType == Int>`
3985
+ // These seem more reasonable to have influence constraint solving, since it could
3986
+ // conceivably let us specialize a `X<T> : IContainer` to `X<Int>` if we find
3987
+ // that `X<T>.IndexType == T`.
3974
3988
for ( auto constraintDeclRef : getMembersOfType<GenericTypeConstraintDecl>(genericDeclRef) )
3975
3989
{
3976
3990
if (!TryUnifyTypes (*system , GetSub (constraintDeclRef), GetSup (constraintDeclRef)))
@@ -4062,6 +4076,57 @@ namespace Slang
4062
4076
}
4063
4077
}
4064
4078
4079
+ // After we've solved for the explicit arguments, we need to
4080
+ // make a second pass and consider the implicit arguments,
4081
+ // based on what we've already determined to be the values
4082
+ // for the explicit arguments.
4083
+
4084
+ // Before we begin, we are going to go ahead and create the
4085
+ // "solved" substitution that we will return if everything works.
4086
+ // This is because we are going to use this substitution,
4087
+ // partially filled in with the results we know so far,
4088
+ // in order to specialize any constraints on the generic.
4089
+ //
4090
+ // E.g., if the generic parameters were `<T : ISidekick>`, and
4091
+ // we've already decided that `T` is `Robin`, then we want to
4092
+ // search for a conformance `Robin : ISidekick`, which involved
4093
+ // apply the substitutions we already know...
4094
+
4095
+ RefPtr<GenericSubstitution> solvedSubst = new GenericSubstitution ();
4096
+ solvedSubst->genericDecl = genericDeclRef.getDecl ();
4097
+ solvedSubst->outer = genericDeclRef.substitutions ;
4098
+ solvedSubst->args = args;
4099
+
4100
+ for ( auto constraintDecl : genericDeclRef.getDecl ()->getMembersOfType <GenericTypeConstraintDecl>() )
4101
+ {
4102
+ DeclRef<GenericTypeConstraintDecl> constraintDeclRef (
4103
+ constraintDecl,
4104
+ solvedSubst);
4105
+
4106
+ // Extract the (substituted) sub- and super-type from the constraint.
4107
+ auto sub = GetSub (constraintDeclRef);
4108
+ auto sup = GetSup (constraintDeclRef);
4109
+
4110
+ // Search for a witness that shows the constraint is satisfied.
4111
+ auto subTypeWitness = tryGetSubtypeWitness (sub, sup);
4112
+ if (subTypeWitness)
4113
+ {
4114
+ // We found a witness, so it will become an (implicit) argument.
4115
+ solvedSubst->args .Add (subTypeWitness);
4116
+ }
4117
+ else
4118
+ {
4119
+ // No witness was found, so the inference will now fail.
4120
+ //
4121
+ // TODO: Ideally we should print an error message in
4122
+ // this case, to let the user know why things failed.
4123
+ return nullptr ;
4124
+ }
4125
+
4126
+ // TODO: We may need to mark some constrains in our constraint
4127
+ // system as being solved now, as a result of the witness we found.
4128
+ }
4129
+
4065
4130
// Make sure we haven't constructed any spurious constraints
4066
4131
// that we aren't able to satisfy:
4067
4132
for (auto c : system ->constraints )
@@ -4072,13 +4137,6 @@ namespace Slang
4072
4137
}
4073
4138
}
4074
4139
4075
- // Consruct a reference to the extension with our constraint variables
4076
- // as the
4077
- RefPtr<GenericSubstitution> solvedSubst = new GenericSubstitution ();
4078
- solvedSubst->genericDecl = genericDeclRef.getDecl ();
4079
- solvedSubst->outer = genericDeclRef.substitutions ;
4080
- solvedSubst->args = args;
4081
-
4082
4140
return solvedSubst;
4083
4141
}
4084
4142
0 commit comments