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

Reply via email to