https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118698

--- Comment #17 from Patrick Palka <ppalka at gcc dot gnu.org> ---
(In reply to Jason Merrill from comment #15)
> (In reply to Patrick Palka from comment #12)
> > Substituting <T,foo> into <decltype([]{},T> seems like a partial
> > substitution to me.  If the lambda itself had any template parameters of its
> > own, or autos, we wouldn't want to reduce their level, so it seems
> > tf_partial should be set during normalization?
> 
> Hmm, perhaps, it certainly seems related to the use of tf_partial in
> instantiate_template.  But doing that brings back the tsubst_lambda_expr
> EXTRA_ARGS problems.
Yeah, passing tf_partial wouldn't be sufficient IIUC.
> 
> I think part of the problem is that tf_partial has gotten overloaded.  The
> original meaning was "we only have arguments for some of the parms at this
> level".  The use in instantiate_template has broadened the meaning to
> "substituting without changing the number of levels of parms".  Which would
> also apply in normalization.
> 
> But it's unclear to me why we would want EXTRA_ARGS in that broader sense;
> if we have all the args, we're just substituting them, I'd expect that to
> work fine with the "leave auto alone" meaning.
Even with level-less auto, what about a generic lambda's own template
parameters?  We still need to avoid lowering their levels prematurely during a
dependent/partial substitution.

template<class T>
struct A {
  template<class U>
  using type = decltype([]<class V>{});

  void f() { type<int> t; }
};

template void A<char>::f();

Here we eagerly substitute the alias template ahead of time with a full set of
generic arguments {{T},{int}}.  And then at instantiation time we substitute
again with a full set of concrete arguments {{char},{int}}.  If we don't pass
tf_partial the first time around, the level of V would be prematurely lowered
to 1 which causes the instantiation time substitution to misbehave.
> 
> And the assumption in add_extra_args seems wrong for the original sense; in
> general with tf_partial we would not have a full set of template arguments,
> though we might have enough of them to do the substitution.  And we should
> have the right number of levels, which is the point of that change.
At least for the fn_type_unification and coerce_template_parms call sites that
pass tf_partial under the old meaning, we should always have a full set of
template arguments (with some arguments missing in the innermost level).  Ditto
the instantiate_template call site under the broader meaning.

Reply via email to