This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/48934] no rejection reason given for SFINAE


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48934

--- Comment #11 from froydnj at codesourcery dot com <froydnj at codesourcery dot com> 2011-05-09 18:59:55 UTC ---
On Mon, May 09, 2011 at 06:26:44PM +0000, jason at gcc dot gnu.org wrote:
> > The hackish way of doing this would be to notice during deduction that
> > substitution of a function type failed, then go back and substitute piece-wise
> > into return type and argument types until you find the failing type.  That
> > could be done without the changes above, but it'd be a bit gross.
> 
> It sounds to me like that would be both simpler and better than trying to pass
> back information about why the substitution failed.  If we get to the point
> where we're trying to explain substitution failure, we can just do the
> substitution again with tf_warning_or_error and we'll find out exactly what the
> problem is with the usual error messages.

I'm not sure what you suggest is a win.  The desired (or, at least,
consistent with what we do now) behavior is to say:

foo.C:blahblah: error: no matching function for call to foo
foo.C:blahblah: note: candidate is foo(blahblah)
foo.c:blahblah: note:   substitution failed for parameter `F'

At least, that's what I understood Jonathan asking for--perhaps he
wanted something more detailed about why substitution failed, which is a
debate for another time, I think.

If I understand your proposal correctly, we'd get something more like:

foo.C:blahblah: error: no matching function for call to foo
foo.C:blahblah: note: candidate is foo(blahblah)
foo.C:blahblah: error: [some explanation]

which doesn't seem quite right.

To make the hack suggestion more concrete, we currently have,
pt.c:fn_type_unification:

    /* All is well so far.  Now, check:

       [temp.deduct]

       When all template arguments have been deduced, all uses of
       template parameters in nondeduced contexts are replaced with
       the corresponding deduced argument values.  If the
       substitution results in an invalid type, as described above,
       type deduction fails.  */
    {
      tree substed = tsubst (TREE_TYPE (fn), targs, tf_none, NULL_TREE);
      if (substed == error_mark_node)
    return 1;

and I was proposing to replace the bare 'return 1' with something more
like:

       {
         /* Check to see if return types were the reason substitution
            failed.  */
         tree t = <tsubst on return types>
         if (t == error_mark_node)
           return unify_return_type_substitution_failure ...

         /* Loop over the arguments of TREE_TYPE (FN) and TARGS.  */
         foreach ...
           {
              tree t = <tsubst on argument type>
              if (t == error_mark_node)
                return unify_argument_substitution_failure ....
           }

and then we would handle return_type_substitution_failure or
argument_substitution_failure in call.c's error handling.

I'm sure that code doesn't work as-is, but hopefully you get the idea.

This is getting a bit convoluted.  I thought the original patch posted
back in February was pretty sane, but as I look into a little more, it's
starting to get hairy.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]