|
|
@@ -516,6 +516,7 @@ auto TypeChecker::ImplicitlyConvert(const std::string& context,
|
|
|
Nonnull<const Value*> destination)
|
|
|
-> ErrorOr<Nonnull<Expression*>> {
|
|
|
Nonnull<const Value*> source_type = &source->static_type();
|
|
|
+
|
|
|
// TODO: If a builtin conversion works, for now we don't create any
|
|
|
// expression to do the conversion and rely on the interpreter to know how to
|
|
|
// do it.
|
|
|
@@ -659,6 +660,18 @@ auto TypeChecker::ArgumentDeduction(
|
|
|
switch (param->kind()) {
|
|
|
case Value::Kind::VariableType: {
|
|
|
const auto& var_type = cast<VariableType>(*param);
|
|
|
+ const auto& binding = cast<VariableType>(*param).binding();
|
|
|
+ if (binding.has_static_type()) {
|
|
|
+ const Value* binding_type = Substitute(deduced, &binding.static_type());
|
|
|
+ if (!IsTypeOfType(binding_type)) {
|
|
|
+ if (!IsImplicitlyConvertible(arg, binding_type, impl_scope, false)) {
|
|
|
+ return CompilationError(source_loc)
|
|
|
+ << "cannot convert deduced value " << *arg << " for "
|
|
|
+ << binding.name() << " to parameter type " << *binding_type;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (std::find(bindings_to_deduce.begin(), bindings_to_deduce.end(),
|
|
|
&var_type.binding()) != bindings_to_deduce.end()) {
|
|
|
auto [it, success] = deduced.insert({&var_type.binding(), arg});
|
|
|
@@ -840,8 +853,9 @@ auto TypeChecker::ArgumentDeduction(
|
|
|
case Value::Kind::TypeOfConstraintType:
|
|
|
case Value::Kind::TypeOfChoiceType:
|
|
|
case Value::Kind::TypeOfParameterizedEntityName:
|
|
|
- case Value::Kind::TypeOfMemberName:
|
|
|
+ case Value::Kind::TypeOfMemberName: {
|
|
|
return handle_non_deduced_type();
|
|
|
+ }
|
|
|
case Value::Kind::ImplWitness:
|
|
|
case Value::Kind::SymbolicWitness:
|
|
|
case Value::Kind::ParameterizedEntityName:
|
|
|
@@ -1314,7 +1328,6 @@ auto TypeChecker::DeduceCallBindings(
|
|
|
<< "wrong number of arguments in function call, expected "
|
|
|
<< params.size() << " but got " << args.size();
|
|
|
}
|
|
|
-
|
|
|
// Bindings for deduced parameters and generic parameters.
|
|
|
BindingMap generic_bindings;
|
|
|
|
|
|
@@ -1370,9 +1383,12 @@ auto TypeChecker::DeduceCallBindings(
|
|
|
|
|
|
// Convert the arguments to the parameter type.
|
|
|
Nonnull<const Value*> param_type = Substitute(generic_bindings, params_type);
|
|
|
+
|
|
|
+ // Convert the arguments to the deduced and substituted parameter type.
|
|
|
CARBON_ASSIGN_OR_RETURN(
|
|
|
Nonnull<Expression*> converted_argument,
|
|
|
ImplicitlyConvert("call", impl_scope, &call.argument(), param_type));
|
|
|
+
|
|
|
call.set_argument(converted_argument);
|
|
|
|
|
|
return Success();
|