Skip to content

[BUG] Recognize non-deducible parameter #534

Open

Description

@JohelEGP

Title: Use cpp2::in for non-deducible parameters.

Description:

Currently, Cppfront doesn't wrap in cpp2::in
a template function $F$'s function parameter
that has the type of one of $F$'s template parameter
to avoid making it non-deducible.

However, it also does the same
when a similar use of $F$'s template parameter
makes the function parameter non-deducible.

If a function parameter is already non-deducible,
its type should be wrapped in cpp2::in.

Minimal reproducer (https://cpp2.godbolt.org/z/jjxTWfcfq):

f: <T> (x: std::integral_constant<i32, T::value>) = { }
main: () = { }
Commands:
cppfront main.cpp2
clang++17 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -I . main.cpp

Expected result:

template<typename T> auto f(cpp2::in<std::integral_constant<cpp2::i32,T::value>> x) -> void{}

Actual result and error:

template<typename T> auto f(std::integral_constant<cpp2::i32,T::value> const& x) -> void{}
Cpp2 lowered to Cpp1:
//=== Cpp2 type declarations ====================================================


#include "cpp2util.h"



//=== Cpp2 type definitions and function declarations ===========================

template<typename T> auto f(std::integral_constant<cpp2::i32,T::value> const& x) -> void;
auto main() -> int;


//=== Cpp2 function definitions =================================================

template<typename T> auto f(std::integral_constant<cpp2::i32,T::value> const& x) -> void{}
auto main() -> int{}
Output:
Program returned: 0

Activity

  1. changed the title [-][BUG] Use `cpp2::in` for non-deducible parameters[/-] [+][BUG] Recognize non-deducible parameter[/+] on Jul 3, 2023
  2. JohelEGP commented on Jul 3, 2023

    @JohelEGP
    ContributorAuthor

    Title: Recognize non-deducible parameter.

    Description:

    The report generalizes.
    The same applies to out parameters.

    Minimal reproducer (https://cpp2.godbolt.org/z/Tnvczs8qa):

    f: <T> (out x: std::integral_constant<i32, T::value>) = { x = (); }
    main: () = {
      t: type == std::integral_constant<i32, 0>;
      i: t;
      f<t>(out i);
    }
    
    Commands:
    cppfront main.cpp2
    clang++17 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -I . main.cpp

    Expected result:

    template<typename T> auto f(cpp2::out<std::integral_constant<cpp2::i32, T::value>> x) -> void;

    Actual result and error:

    template<typename T> auto f(std::integral_constant<cpp2::i32,T::value> x_) -> void;
    Cpp2 lowered to Cpp1:
    //=== Cpp2 type declarations ====================================================
    
    
    #include "cpp2util.h"
    
    
    
    //=== Cpp2 type definitions and function declarations ===========================
    
    template<typename T> auto f(std::integral_constant<cpp2::i32,T::value> x_) -> void;
    auto main() -> int;
      
    
    //=== Cpp2 function definitions =================================================
    
    template<typename T> auto f(std::integral_constant<cpp2::i32,T::value> x_) -> void{
                                                              auto x = cpp2::out(x_); 
    x.construct(); }
    auto main() -> int{
      using t = std::integral_constant<cpp2::i32,0>;
      cpp2::deferred_init<t> i; 
      f<t>(cpp2::out(&i));
    }
    Output:
    main.cpp2:5:3: error: no matching function for call to 'f'
        5 |   f<t>(cpp2::out(&i));
          |   ^~~~
    main.cpp2:1:27: note: candidate function template not viable: no known conversion from 'cpp2::out<integral_constant<int, 0>>' (aka 'cpp2::out<std::integral_constant<int, 0>>') to 'std::integral_constant<cpp2::i32, t::value>' (aka 'integral_constant<int, t::value>') for 1st argument
        5 | template<typename T> auto f(std::integral_constant<cpp2::i32,T::value> x_) -> void{
          |                           ^
        6 |                                                           auto x = cpp2::out(x_); 
        7 | #line 1 "/app/main.cpp2"
        8 | x.construct(); }
        9 | auto main() -> int{
       10 |   using t = std::integral_constant<cpp2::i32,0>;
       11 |   cpp2::deferred_init<t> i; 
       12 |   f<t>(cpp2::out(&i));
          |        ~~~~~~~~~~~~~
    1 error generated.
    
  3. JohelEGP commented on Jul 6, 2023

    @JohelEGP
    ContributorAuthor

    See #533 (comment) for the source of the bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions