On 05/26/2011 03:04 PM, Nathan Froyd wrote:
Thanks, this is looking pretty close. A few more issues, mostly to do
with wording of the diagnostics:
@@ -14084,7 +14350,7 @@ fn_type_unification (tree fn,
sarg = tree_cons (NULL_TREE, TREE_TYPE (substed), sarg);
for (i = 0; i < nargs && sarg; ++i, sarg = TREE_CHAIN (sarg))
if (!same_type_p (args[i], TREE_VALUE (sarg)))
- return 1;
+ return unify_unknown (explain_p);
Here the problem is that substituting in the deduced template arguments
didn't give us the result we were looking for; the diagnostic should
print the substitution result and the desired result.
if (resolve_overloaded_unification
- (tparms, targs, parm, arg, strict, sub_strict))
+ (tparms, targs, parm, arg, strict, sub_strict, explain_p))
continue;
- return 1;
+ return unify_unknown (explain_p);
Here the problem is that deduction is unable to resolve the address of
an overloaded function.
+ inform (input_location,
+ " template parameter %qD is not a parameter pack",
+ parm);
+ inform (input_location, " please report this as a bug");
Actually, I was wrong; this isn't a bug. 14.8.2.4/8 says, "If A was
transformed from a function parameter pack and P is not a parameter
pack, type deduction fails."
But let's print the argument as well in this case.
+unify_ptrmem_cst_mismatch (bool explain_p, tree parm, tree arg)
+{
+ if (explain_p)
+ inform (input_location,
+ " mismatched pointer-to-memory constants %qE and %qE",
+ parm, arg);
Here the problem is that arg is not a pointer-to-member constant at all
(note also "member", not "memory").
if (TREE_CODE (arg) != INTEGER_CST)
- return 1;
+ return unify_constant_mismatch (explain_p, parm, arg);
This could end up complaining that arg isn't constant when the problem
is that it's the wrong kind of constant.
You might combine unify_ptrmem_cst_mismatch, unify_constant_mismatch,
and unify_constant_unequal to just say that arg is not a constant equal
to parm. Or just use unify_template_argument_mismatch.
+unify_expression_unequal (bool explain_p, tree parm, tree arg)
+{
+ if (explain_p)
+ inform (input_location, " %qE is not equal to %qE", parm, arg);
This should say "equivalent" rather than "equal".
+ " portions of parameter pack %qT could not be deduced",
The problem here is that portions of the pack were deduced to different
values, like unify_inconsistency but with packs. Let's print out the
conflicting values.
+ " method type %qT is not a valid template argument", arg);
"member function type"
+unify_too_many_parameters (bool explain_p, int have, int wanted)
+unify_too_few_parameters (bool explain_p, int have, int wanted)
s/parameters/arguments/
if (strict != DEDUCE_EXACT
&& can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg,
flags))
continue;
return unify_arg_conversion (explain_p, parm, type, arg);
In the DEDUCE_EXACT case, let's use unify_type_mismatch.
&& !template_template_parm_bindings_ok_p
(DECL_INNERMOST_TEMPLATE_PARMS (fn), targs))
return unify_inconsistent_template_template_parameters (explain_p);
Here the problem is that the template parameters of a template template
argument are inconsistent with other deduced template arguments, as
illustrated in the example just above this snippet. Ideally here we'd
print the parameter types of the template template argument and the
parameter types of the template template parameter after substituting in
the other template arguments. I'm not going to insist on that now, but
let's be a bit more verbose than "inconsistent template template
parameters".
&& TREE_CODE (tparm) != TYPE_DECL)
|| (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM
&& TREE_CODE (tparm) != TEMPLATE_DECL))
- return 1;
+ return unify_template_parameter_mismatch (explain_p,
+ parm, tparm);
Looking more closely, I have no idea how this could happen. It seems to
hypothesize a template type parameter that isn't a type parameter, or a
template template parameter that isn't a template template parameter.
Let's try asserting that this can't happen.
converted_args
= (coerce_template_parms (tparms, explicit_targs, NULL_TREE, tf_none,
/*require_all_args=*/false,
/*use_default_args=*/false));
if (converted_args == error_mark_node)
- return 1;
+ {
+ /* Run it for diagnostics. */
+ if (explain_p)
+ coerce_template_parms (tparms, explicit_targs, NULL_TREE,
+ tf_warning_or_error,
+ /*require_all_args=*/false,
+ /*use_default_args=*/false);
+ return 1;
+ }
Instead of calling it twice, pass different tsubst_flags depending on
explain_p. And the same for all the other places where you call a
function again with tf_warning_or_error.
+ return unify_too_few_parameters (explain_p, TREE_VEC_LENGTH (argv
+ len);
Line too long.
+ /* FIXME: Should we pass in unification information and then use that
+ to elaborate on the error messages below? */
Just pass in explain_p = true, and then we shouldn't need the "unable to
deduce" message here.
Jason