Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Non-type template parameter used as _type-id_ is not diagnosed #575

Closed
JohelEGP opened this issue Aug 9, 2023 · 4 comments
Closed
Labels
bug Something isn't working

Comments

@JohelEGP
Copy link
Contributor

JohelEGP commented Aug 9, 2023

Title: Non-type template parameter used as type-id is not diagnosed.

Description:

I encountered this when poking Cppfront to get it to emit a type-constraint.
The issue is alleviated by resolving #425,
as it would only happen with an NTTP by copy.

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

t: @struct <T: std::regular> type = {
  v: T;
}
f: <T: std::regular> (v: T) = _ = v;
g: <T: std::regular> (forward v: T) = _ = v;
h: <T: std::regular> (move v: T) = _ = v;

main: () = {
  _ = :t = (0); // Not OK (works, should error)
  f(0); // error (by chance?)
  g(0); // error (by chance?)
  h(0); // Not OK (works, should error)
}
Commands:
cppfront main.cpp2
clang++17 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -fsanitize=undefined -Werror=unused-result -I . main.cpp

Expected result: A diagnostic when using an NTTP as a type.

Actual result and error:

Cpp2 lowered to Cpp1:
//=== Cpp2 type declarations ====================================================


#include "cpp2util.h"

template<std::regular T> class t;
  

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

template<std::regular T> class t {
  public: T v; 
};
template<std::regular T> auto f(cpp2::in<T> v) -> void;
template<std::regular T> auto g(auto&& v) -> void
CPP2_REQUIRES (std::is_same_v<CPP2_TYPEOF(v), T>)
;
template<std::regular T> auto h(T&& v) -> void;

auto main() -> int;
  

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


template<std::regular T> auto f(cpp2::in<T> v) -> void { (void) v;  }
template<std::regular T> auto g(auto&& v) -> void
requires (std::is_same_v<CPP2_TYPEOF(v), T>)
 { (void) CPP2_FORWARD(v);  }
template<std::regular T> auto h(T&& v) -> void { (void) std::move(v);  }

auto main() -> int{
  (void) t{0};  // Not OK (works, should error)
  f(0); // error (by chance?)
  g(0); // error (by chance?)
  h(0); // Not OK (works, should error)
}
Output:
main.cpp2:10:3: error: no matching function for call to 'f'
   10 |   f(0); // error (by chance?)
      |   ^
main.cpp2:4:31: note: candidate template ignored: couldn't infer template argument 'T'
    4 | template<std::regular T> auto f(cpp2::in<T> v) -> void { (void) v;  }
      |                               ^
main.cpp2:11:3: error: no matching function for call to 'g'
   11 |   g(0); // error (by chance?)
      |   ^
main.cpp2:5:31: note: candidate template ignored: couldn't infer template argument 'T'
    5 | template<std::regular T> auto g(auto&& v) -> void
      |                               ^
2 errors generated.
@JohelEGP JohelEGP added the bug Something isn't working label Aug 9, 2023
@JohelEGP

This comment was marked as resolved.

@hsutter
Copy link
Owner

hsutter commented Aug 13, 2023

When you wrote <T: std::regular>, I think you meant to apply a concept constraint.

That isn't yet supported, but my intent is to spell it as <T: type is std::regular>.

The syntax <T: sometypeid> is always a value parameter (NTTP).

Please reopen if I misunderstood! Thanks.

@hsutter hsutter closed this as completed Aug 13, 2023
@JohelEGP
Copy link
Contributor Author

Yes, I know it's not supported, and did it intentionally anyways.
What I'm wondering is whether Cppfront should diagnose
the function definitions of those calls in the reproducer that say // Not OK (works, should error).
Because it knows T is an NTTP, yet allows T to be used as a type-id.

@JohelEGP
Copy link
Contributor Author

That isn't yet supported, but my intent is to spell it as <T: type is std::regular>.

I'm supposing we will be able to omit type, and similarly declare NTTPs like <V: _ is std::regular>.
And similarly support this terse syntax on parameters, return types, and variable declarations (just like Cpp1), e.g.

f: <_: type is C, _: is C, _: _ is C> (_: _ is C, _: is C) -> _ is C { _: _ is C = …; }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants