-
Notifications
You must be signed in to change notification settings - Fork 251
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(to_cpp1): improve recognition of dependent types and deducible pa…
…rameters
- Loading branch information
Showing
11 changed files
with
855 additions
and
128 deletions.
There are no files selected for viewing
32 changes: 32 additions & 0 deletions
32
regression-tests/pure2-bugfix-for-deducible-parameters.cpp2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Dependent, non-deducible parameters are wrapped like non-dependent parameters. | ||
init: <T> (out x: std::integral_constant<i32, T::value>) = { x = (); } | ||
init: <T> (out x: std::integral_constant<i32, T::value>, _: T) = { x = (); } | ||
id: <T> (in_ref x: std::integral_constant<i32, T::value>) = x; | ||
id: <T> (x: std::integral_constant<i32, T::value>, y: T) = { assert(x& == y&); } | ||
|
||
main: () = { | ||
zero: type == std::integral_constant<i32, 0>; | ||
|
||
z: zero; | ||
init<zero>(out z); | ||
assert(id<zero>(z)& == z&); | ||
|
||
// Deducible parameters. | ||
_ = :v = 0; | ||
:<T> (_: std::vector<T>) = {}(:std::vector<i32> = ()); | ||
:<T> (_: std::vector<std::vector<T>>) = {}(:std::vector<std::vector<i32>> = ()); | ||
// _ = :<T, U> (x: std::pair<T, typename U::value_type>, y: U) = {}(:std::pair = (0, 0), z); // Blocked on #727. | ||
:<T, U> (_: std::array<T, U::value>, _: U) = {}(:std::array<i32, 0> = (), z); | ||
init(out z, z); | ||
id(z, z); | ||
|
||
// Test that these are emitted unwrapped in case they are deducible. | ||
(copy f := :<T> (_: std::vector<std::type_identity_t<T>>) = {}) | ||
static_assert(!std::is_invocable_v<decltype(f), std::vector<i32>>, "`T` is non-deducible."); | ||
(copy f := :<T> (_: std::vector<std::vector<T>>) = {}) | ||
static_assert(std::is_invocable_v<decltype(f), std::vector<std::vector<i32>>>, "`T` is deducible."); | ||
} | ||
|
||
v: <T> type = { | ||
operator=: (out this, _: T) = { } | ||
} |
6 changes: 6 additions & 0 deletions
6
regression-tests/pure2-bugfix-for-dependent-types-recursion.cpp2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
main: () = { | ||
a: type == b; | ||
b: type == a; | ||
_ = a::t; | ||
_ = b::t; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
identity: <T> type == T; | ||
|
||
f: <T> (inout _: T::value_type) = { } | ||
f: <T> (move _: T::value_type) = { } | ||
f: <T, V: T::value_type> (x: T::value_type) -> T::value_type = { | ||
assert(x is T::value_type); | ||
y: T::value_type; | ||
y = x; | ||
z: type == T::value_type; | ||
return (:T::value_type = x); | ||
|
||
// Dependent *template-id*s. | ||
_ = :identity<T>::value_type = (); // First identifier. | ||
_ = :std::optional<T>::value_type = (); // Non-first identifier. | ||
_ = :std::array<i32, T::value>::value_type = (); | ||
_ = :std::array<i32, T::value + T::value>::value_type = (); | ||
|
||
// Emitted `template`. | ||
ptr: type == * T; // Also test lookup through type aliases. | ||
nptr: type == * i32; | ||
_ = :std::pointer_traits<ptr>::rebind<ptr> = (); // Type-only context. | ||
_ = :std::pointer_traits<nptr>::rebind<nptr> = (); // Non-dependent. | ||
_ = :std::pointer_traits<nptr>::rebind<ptr> = (); // Dependent on the nested template. | ||
_ = :std::pointer_traits<ptr>::rebind<nptr> = (); // Dependent on the outer template. | ||
// _ = :identity<typename std::pointer_traits<ptr>::rebind<ptr>> = (); // Non type-only context. Blocked on #727. | ||
|
||
// Aliases. | ||
w: type == T; | ||
_ = :w::value_type = x; | ||
v: type == w; | ||
_ = :v::value_type = x; | ||
a: type == T::type; | ||
_ = :a::value_type = x; | ||
|
||
{ | ||
// Test that there's no prefixed `typename` to.... | ||
_ = std::integral_constant<i32, T::value>(); // `T::value`. | ||
_ = :std::type_identity_t<T> = (); // `std::type_identity_t<T>`. | ||
|
||
// Test that non-dependent names aren't emitted with `typename`. | ||
a: type == std::integral_constant<i32, 0>; | ||
b: type == a; | ||
c: type == b; | ||
_ = :b::value_type = x; | ||
_ = :c::value_type = x; | ||
} | ||
} | ||
|
||
t: @cpp1_rule_of_zero <T: type> type = { | ||
u: type = { | ||
x: T::value_type = (); | ||
this: T::type = (); | ||
// Test that there's no `typename` in the member initializer list. | ||
operator=: (out this, that) = { } | ||
} | ||
x: T::value_type = 0; | ||
} | ||
|
||
main: () = { | ||
zero: type == std::integral_constant<i32, 0>; | ||
_ = f<zero, 0>(0); | ||
|
||
_ = : ::t<zero> = (); | ||
|
||
// Emitted `template` (noop, taken care of by the UFCS macro). | ||
_ = :(move f) = _ = f.operator()<i32>();(:<T> () = {}); | ||
|
||
// Nesting is not relevant to lookup. | ||
_ = :<T> () = { _ = :T::value_type = (); }; | ||
_ = :() = { _ = :<T> () = { _ = :T::value_type = (); }; }; | ||
_ = :() = { _ = :() = { _ = :<T> () = { _ = :T::value_type = (); }; }; }; | ||
_ = :() = { _ = :() = { _ = :() = { _ = :<T> () = { _ = :T::value_type = (); }; }; }; }; | ||
_ = :() = { _ = :() = { _ = :<T> () = { _ = :() = { _ = :T::value_type = (); }; }; }; }; | ||
_ = :() = { _ = :<T> () = { _ = :() = { _ = :() = { _ = :T::value_type = (); }; }; }; }; | ||
_ = :<T> () = { _ = :() = { _ = :() = { _ = :() = { _ = :T::value_type = (); }; }; }; }; | ||
_ = :<T> () = { _ = :() = { _ = :() = { _ = :(_: T::value_type) = {}; }; }; }; | ||
_ = :<T> () = { _ = :() = { _ = :(_: T::value_type) = { _ = :() = {}; }; }; }; | ||
_ = :<T> () = { _ = :(_: T::value_type) = { _ = :() = { _ = :() = {}; }; }; }; | ||
_ = :<T> (_: T::value_type) = { _ = :() = { _ = :() = { _ = :() = {}; }; }; }; | ||
|
||
// Lookup. | ||
{ | ||
alias: type == std::integral_constant<i32, 0>; | ||
_ = :alias::value_type = 0; // Non-dependent. | ||
} | ||
_ = :<T> (_: T) = { | ||
alias: type == std::integral_constant<T, 0>; | ||
_ = :alias::value_type = 0; // Dependent. | ||
{ | ||
alias: type == std::integral_constant<i32, 0>; | ||
_ = :alias::value_type = 0; // Non-dependent. | ||
} | ||
}(0); | ||
|
||
_ = :(r) -> std::type_identity_t<decltype(begin(r)*)> = r[0];(std::vector<int>(1)); | ||
} |
90 changes: 90 additions & 0 deletions
90
regression-tests/test-results/pure2-bugfix-for-deducible-parameters.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
|
||
#define CPP2_IMPORT_STD Yes | ||
|
||
//=== Cpp2 type declarations ==================================================== | ||
|
||
|
||
#include "cpp2util.h" | ||
|
||
#line 1 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
|
||
#line 30 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
template<typename T> class v; | ||
|
||
|
||
//=== Cpp2 type definitions and function declarations =========================== | ||
|
||
#line 1 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
// Dependent, non-deducible parameters are wrapped like non-dependent parameters. | ||
#line 2 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
template<typename T> auto init(cpp2::impl::out<std::integral_constant<cpp2::i32,T::value>> x) -> void; | ||
template<typename T> auto init(cpp2::impl::out<std::integral_constant<cpp2::i32,T::value>> x, [[maybe_unused]] T const& unnamed_param_2) -> void; | ||
template<typename T> [[nodiscard]] auto id(std::integral_constant<cpp2::i32,T::value> const& x) -> decltype(auto); | ||
template<typename T> auto id(cpp2::impl::in<std::integral_constant<cpp2::i32,T::value>> x, T const& y) -> void; | ||
|
||
auto main() -> int; | ||
|
||
#line 30 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
template<typename T> class v { | ||
public: explicit v([[maybe_unused]] T const& unnamed_param_2); | ||
#line 31 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
public: auto operator=([[maybe_unused]] T const& unnamed_param_2) -> v& ; | ||
public: v(v const&) = delete; /* No 'that' constructor, suppress copy */ | ||
public: auto operator=(v const&) -> void = delete; | ||
|
||
#line 32 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
}; | ||
|
||
|
||
//=== Cpp2 function definitions ================================================= | ||
|
||
#line 1 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
|
||
#line 2 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
template<typename T> auto init(cpp2::impl::out<std::integral_constant<cpp2::i32,T::value>> x) -> void{x.construct(); } | ||
#line 3 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
template<typename T> auto init(cpp2::impl::out<std::integral_constant<cpp2::i32,T::value>> x, [[maybe_unused]] T const& unnamed_param_2) -> void{x.construct(); } | ||
#line 4 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
template<typename T> [[nodiscard]] auto id(std::integral_constant<cpp2::i32,T::value> const& x) -> decltype(auto) { return x; } | ||
#line 5 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
template<typename T> auto id(cpp2::impl::in<std::integral_constant<cpp2::i32,T::value>> x, T const& y) -> void{if (cpp2::cpp2_default.is_active() && !(&x == &y) ) { cpp2::cpp2_default.report_violation(""); }} | ||
|
||
#line 7 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
auto main() -> int{ | ||
using zero = std::integral_constant<cpp2::i32,0>; | ||
|
||
cpp2::impl::deferred_init<zero> z; | ||
init<zero>(cpp2::impl::out(&z)); | ||
if (cpp2::cpp2_default.is_active() && !(&id<zero>(z.value()) == &z.value()) ) { cpp2::cpp2_default.report_violation(""); } | ||
|
||
// Deducible parameters. | ||
static_cast<void>(v{ 0}); | ||
[]<typename T>([[maybe_unused]] std::vector<T> const& unnamed_param_1) -> void{}(std::vector<cpp2::i32>{}); | ||
[]<typename T>([[maybe_unused]] std::vector<std::vector<T>> const& unnamed_param_1) -> void{}(std::vector<std::vector<cpp2::i32>>{}); | ||
// _ = :<T, U> (x: std::pair<T, typename U::value_type>, y: U) = {}(:std::pair = (0, 0), z); // Blocked on #727. | ||
[]<typename T, typename U>([[maybe_unused]] std::array<T,U::value> const& unnamed_param_1, [[maybe_unused]] U const& unnamed_param_2) -> void{}(std::array<cpp2::i32,0>{}, z.value()); | ||
init(cpp2::impl::out(&z.value()), z.value()); | ||
id(z.value(), cpp2::move(z.value())); | ||
{ | ||
auto f{[]<typename T>([[maybe_unused]] std::vector<std::type_identity_t<T>> const& unnamed_param_1) -> void{}}; | ||
|
||
// Test that these are emitted unwrapped in case they are deducible. | ||
|
||
#line 25 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
static_assert(!(std::is_invocable_v<decltype(cpp2::move(f)),std::vector<cpp2::i32>>), "`T` is non-deducible."); | ||
} | ||
{ | ||
auto f{[]<typename T>([[maybe_unused]] std::vector<std::vector<T>> const& unnamed_param_1) -> void{}}; | ||
|
||
#line 27 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
static_assert(std::is_invocable_v<decltype(cpp2::move(f)),std::vector<std::vector<cpp2::i32>>>, "`T` is deducible."); | ||
} | ||
#line 28 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
} | ||
|
||
#line 31 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
template <typename T> v<T>::v([[maybe_unused]] T const& unnamed_param_2){} | ||
#line 31 "pure2-bugfix-for-deducible-parameters.cpp2" | ||
template <typename T> auto v<T>::operator=([[maybe_unused]] T const& unnamed_param_2) -> v& { | ||
return *this; } | ||
|
2 changes: 2 additions & 0 deletions
2
regression-tests/test-results/pure2-bugfix-for-deducible-parameters.cpp2.output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pure2-bugfix-for-deducible-parameters.cpp2... ok (all Cpp2, passes safety checks) | ||
|
27 changes: 27 additions & 0 deletions
27
regression-tests/test-results/pure2-bugfix-for-dependent-types-recursion.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
|
||
#define CPP2_IMPORT_STD Yes | ||
|
||
//=== Cpp2 type declarations ==================================================== | ||
|
||
|
||
#include "cpp2util.h" | ||
|
||
#line 1 "pure2-bugfix-for-dependent-types-recursion.cpp2" | ||
|
||
|
||
//=== Cpp2 type definitions and function declarations =========================== | ||
|
||
#line 1 "pure2-bugfix-for-dependent-types-recursion.cpp2" | ||
auto main() -> int; | ||
|
||
//=== Cpp2 function definitions ================================================= | ||
|
||
#line 1 "pure2-bugfix-for-dependent-types-recursion.cpp2" | ||
auto main() -> int{ | ||
#line 2 "pure2-bugfix-for-dependent-types-recursion.cpp2" | ||
using a = b; | ||
using b = a; | ||
static_cast<void>(a::t); | ||
static_cast<void>(b::t); | ||
} | ||
|
2 changes: 2 additions & 0 deletions
2
regression-tests/test-results/pure2-bugfix-for-dependent-types-recursion.cpp2.output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pure2-bugfix-for-dependent-types-recursion.cpp2... ok (all Cpp2, passes safety checks) | ||
|
Oops, something went wrong.