10275: internal: parser cleanups r=Veykril a=matklad

bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2021-09-18 12:20:55 +00:00 committed by GitHub
commit dd12521ac9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 300 additions and 312 deletions

View File

@ -1,28 +1,39 @@
use super::*;
// test trait_item
// trait T<U>: Hash + Clone where U: Copy {}
// trait X<U: Debug + Display>: Hash + Clone where U: Copy {}
// trait T { fn new() -> Self; }
pub(super) fn trait_(p: &mut Parser, m: Marker) {
assert!(p.at(T![trait]));
p.bump(T![trait]);
name_r(p, ITEM_RECOVERY_SET);
// test trait_item_generic_params
// trait X<U: Debug + Display> {}
type_params::opt_generic_param_list(p);
// test trait_alias
// trait Z<U> = T<U>;
// trait Z<U> = T<U> where U: Copy;
// trait Z<U> = where Self: T<U>;
if p.eat(T![=]) {
// test trait_alias
// trait Z<U> = T<U>;
type_params::bounds_without_colon(p);
// test trait_alias_where_clause
// trait Z<U> = T<U> where U: Copy;
// trait Z<U> = where Self: T<U>;
type_params::opt_where_clause(p);
p.expect(T![;]);
m.complete(p, TRAIT);
return;
}
if p.at(T![:]) {
// test trait_item_bounds
// trait T: Hash + Clone {}
type_params::bounds(p);
}
// test trait_item_where_clause
// trait T where Self: Copy {}
type_params::opt_where_clause(p);
if p.at(T!['{']) {
assoc_item_list(p);
} else {
@ -31,24 +42,23 @@ pub(super) fn trait_(p: &mut Parser, m: Marker) {
m.complete(p, TRAIT);
}
// test impl_def
// impl Foo {}
// test impl_item
// impl S {}
pub(super) fn impl_(p: &mut Parser, m: Marker) {
assert!(p.at(T![impl]));
p.bump(T![impl]);
if choose_type_params_over_qpath(p) {
if p.at(T![<]) && not_a_qualified_path(p) {
type_params::opt_generic_param_list(p);
}
// test impl_def_const
// impl const Send for X {}
// test impl_item_const
// impl const Send for S {}
p.eat(T![const]);
// FIXME: never type
// impl ! {}
// test impl_def_neg
// impl !Send for X {}
// test impl_item_neg
// impl !Send for S {}
p.eat(T![!]);
impl_type(p);
if p.eat(T![for]) {
@ -63,7 +73,7 @@ pub(super) fn impl_(p: &mut Parser, m: Marker) {
m.complete(p, IMPL);
}
// test impl_item_list
// test assoc_item_list
// impl F {
// type A = i32;
// const B: i32 = 92;
@ -72,14 +82,11 @@ pub(super) fn impl_(p: &mut Parser, m: Marker) {
// }
pub(crate) fn assoc_item_list(p: &mut Parser) {
assert!(p.at(T!['{']));
let m = p.start();
p.bump(T!['{']);
// test impl_inner_attributes
// enum F{}
// impl F {
// //! This is a doc comment
// #![doc("This is also a doc comment")]
// }
// test assoc_item_list_inner_attrs
// impl S { #![attr] }
attributes::inner_attrs(p);
while !p.at(EOF) && !p.at(T!['}']) {
@ -95,7 +102,7 @@ pub(crate) fn assoc_item_list(p: &mut Parser) {
// test impl_type_params
// impl<const N: u32> Bar<N> {}
fn choose_type_params_over_qpath(p: &Parser) -> bool {
fn not_a_qualified_path(p: &Parser) -> bool {
// There's an ambiguity between generic parameters and qualified paths in impls.
// If we see `<` it may start both, so we have to inspect some following tokens.
// The following combinations can only start generics,
@ -112,9 +119,6 @@ fn choose_type_params_over_qpath(p: &Parser) -> bool {
// we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`)
// because this is what almost always expected in practice, qualified paths in impls
// (`impl <Type>::AssocTy { ... }`) aren't even allowed by type checker at the moment.
if !p.at(T![<]) {
return false;
}
if p.nth(1) == T![#] || p.nth(1) == T![>] || p.nth(1) == T![const] {
return true;
}

View File

@ -1,125 +1,31 @@
SOURCE_FILE@0..101
TRAIT@0..41
SOURCE_FILE@0..30
TRAIT@0..29
TRAIT_KW@0..5 "trait"
WHITESPACE@5..6 " "
NAME@6..7
IDENT@6..7 "T"
GENERIC_PARAM_LIST@7..10
L_ANGLE@7..8 "<"
TYPE_PARAM@8..9
NAME@8..9
IDENT@8..9 "U"
R_ANGLE@9..10 ">"
COLON@10..11 ":"
WHITESPACE@11..12 " "
TYPE_BOUND_LIST@12..24
TYPE_BOUND@12..16
PATH_TYPE@12..16
PATH@12..16
PATH_SEGMENT@12..16
NAME_REF@12..16
IDENT@12..16 "Hash"
WHITESPACE@16..17 " "
PLUS@17..18 "+"
WHITESPACE@18..19 " "
TYPE_BOUND@19..24
PATH_TYPE@19..24
PATH@19..24
PATH_SEGMENT@19..24
NAME_REF@19..24
IDENT@19..24 "Clone"
WHITESPACE@24..25 " "
WHERE_CLAUSE@25..38
WHERE_KW@25..30 "where"
WHITESPACE@30..31 " "
WHERE_PRED@31..38
PATH_TYPE@31..32
PATH@31..32
PATH_SEGMENT@31..32
NAME_REF@31..32
IDENT@31..32 "U"
COLON@32..33 ":"
WHITESPACE@33..34 " "
TYPE_BOUND_LIST@34..38
TYPE_BOUND@34..38
PATH_TYPE@34..38
PATH@34..38
PATH_SEGMENT@34..38
NAME_REF@34..38
IDENT@34..38 "Copy"
WHITESPACE@38..39 " "
ASSOC_ITEM_LIST@39..41
L_CURLY@39..40 "{"
R_CURLY@40..41 "}"
WHITESPACE@41..42 "\n"
TRAIT@42..100
TRAIT_KW@42..47 "trait"
WHITESPACE@47..48 " "
NAME@48..49
IDENT@48..49 "X"
GENERIC_PARAM_LIST@49..69
L_ANGLE@49..50 "<"
TYPE_PARAM@50..68
NAME@50..51
IDENT@50..51 "U"
COLON@51..52 ":"
WHITESPACE@52..53 " "
TYPE_BOUND_LIST@53..68
TYPE_BOUND@53..58
PATH_TYPE@53..58
PATH@53..58
PATH_SEGMENT@53..58
NAME_REF@53..58
IDENT@53..58 "Debug"
WHITESPACE@58..59 " "
PLUS@59..60 "+"
WHITESPACE@60..61 " "
TYPE_BOUND@61..68
PATH_TYPE@61..68
PATH@61..68
PATH_SEGMENT@61..68
NAME_REF@61..68
IDENT@61..68 "Display"
R_ANGLE@68..69 ">"
COLON@69..70 ":"
WHITESPACE@70..71 " "
TYPE_BOUND_LIST@71..83
TYPE_BOUND@71..75
PATH_TYPE@71..75
PATH@71..75
PATH_SEGMENT@71..75
NAME_REF@71..75
IDENT@71..75 "Hash"
WHITESPACE@75..76 " "
PLUS@76..77 "+"
WHITESPACE@77..78 " "
TYPE_BOUND@78..83
PATH_TYPE@78..83
PATH@78..83
PATH_SEGMENT@78..83
NAME_REF@78..83
IDENT@78..83 "Clone"
WHITESPACE@83..84 " "
WHERE_CLAUSE@84..97
WHERE_KW@84..89 "where"
WHITESPACE@89..90 " "
WHERE_PRED@90..97
PATH_TYPE@90..91
PATH@90..91
PATH_SEGMENT@90..91
NAME_REF@90..91
IDENT@90..91 "U"
COLON@91..92 ":"
WHITESPACE@92..93 " "
TYPE_BOUND_LIST@93..97
TYPE_BOUND@93..97
PATH_TYPE@93..97
PATH@93..97
PATH_SEGMENT@93..97
NAME_REF@93..97
IDENT@93..97 "Copy"
WHITESPACE@97..98 " "
ASSOC_ITEM_LIST@98..100
L_CURLY@98..99 "{"
R_CURLY@99..100 "}"
WHITESPACE@100..101 "\n"
WHITESPACE@7..8 " "
ASSOC_ITEM_LIST@8..29
L_CURLY@8..9 "{"
WHITESPACE@9..10 " "
FN@10..27
FN_KW@10..12 "fn"
WHITESPACE@12..13 " "
NAME@13..16
IDENT@13..16 "new"
PARAM_LIST@16..18
L_PAREN@16..17 "("
R_PAREN@17..18 ")"
WHITESPACE@18..19 " "
RET_TYPE@19..26
THIN_ARROW@19..21 "->"
WHITESPACE@21..22 " "
PATH_TYPE@22..26
PATH@22..26
PATH_SEGMENT@22..26
NAME_REF@22..26
IDENT@22..26 "Self"
SEMICOLON@26..27 ";"
WHITESPACE@27..28 " "
R_CURLY@28..29 "}"
WHITESPACE@29..30 "\n"

View File

@ -1,2 +1 @@
trait T<U>: Hash + Clone where U: Copy {}
trait X<U: Debug + Display>: Hash + Clone where U: Copy {}
trait T { fn new() -> Self; }

View File

@ -1 +0,0 @@
impl !Send for X {}

View File

@ -15,7 +15,7 @@ SOURCE_FILE@0..20
PATH@15..16
PATH_SEGMENT@15..16
NAME_REF@15..16
IDENT@15..16 "X"
IDENT@15..16 "S"
WHITESPACE@16..17 " "
ASSOC_ITEM_LIST@17..19
L_CURLY@17..18 "{"

View File

@ -0,0 +1 @@
impl !Send for S {}

View File

@ -1,14 +0,0 @@
SOURCE_FILE@0..12
IMPL@0..11
IMPL_KW@0..4 "impl"
WHITESPACE@4..5 " "
PATH_TYPE@5..8
PATH@5..8
PATH_SEGMENT@5..8
NAME_REF@5..8
IDENT@5..8 "Foo"
WHITESPACE@8..9 " "
ASSOC_ITEM_LIST@9..11
L_CURLY@9..10 "{"
R_CURLY@10..11 "}"
WHITESPACE@11..12 "\n"

View File

@ -1 +0,0 @@
impl Foo {}

View File

@ -0,0 +1,14 @@
SOURCE_FILE@0..10
IMPL@0..9
IMPL_KW@0..4 "impl"
WHITESPACE@4..5 " "
PATH_TYPE@5..6
PATH@5..6
PATH_SEGMENT@5..6
NAME_REF@5..6
IDENT@5..6 "S"
WHITESPACE@6..7 " "
ASSOC_ITEM_LIST@7..9
L_CURLY@7..8 "{"
R_CURLY@8..9 "}"
WHITESPACE@9..10 "\n"

View File

@ -0,0 +1 @@
impl S {}

View File

@ -1,41 +0,0 @@
SOURCE_FILE@0..94
ENUM@0..8
ENUM_KW@0..4 "enum"
WHITESPACE@4..5 " "
NAME@5..6
IDENT@5..6 "F"
VARIANT_LIST@6..8
L_CURLY@6..7 "{"
R_CURLY@7..8 "}"
WHITESPACE@8..9 "\n"
IMPL@9..93
IMPL_KW@9..13 "impl"
WHITESPACE@13..14 " "
PATH_TYPE@14..15
PATH@14..15
PATH_SEGMENT@14..15
NAME_REF@14..15
IDENT@14..15 "F"
WHITESPACE@15..16 " "
ASSOC_ITEM_LIST@16..93
L_CURLY@16..17 "{"
WHITESPACE@17..23 "\n "
COMMENT@23..48 "//! This is a doc com ..."
WHITESPACE@48..54 "\n "
ATTR@54..91
POUND@54..55 "#"
BANG@55..56 "!"
L_BRACK@56..57 "["
META@57..90
PATH@57..60
PATH_SEGMENT@57..60
NAME_REF@57..60
IDENT@57..60 "doc"
TOKEN_TREE@60..90
L_PAREN@60..61 "("
STRING@61..89 "\"This is also a doc c ..."
R_PAREN@89..90 ")"
R_BRACK@90..91 "]"
WHITESPACE@91..92 "\n"
R_CURLY@92..93 "}"
WHITESPACE@93..94 "\n"

View File

@ -1,5 +0,0 @@
enum F{}
impl F {
//! This is a doc comment
#![doc("This is also a doc comment")]
}

View File

@ -1,4 +1,4 @@
SOURCE_FILE@0..83
SOURCE_FILE@0..19
TRAIT@0..18
TRAIT_KW@0..5 "trait"
WHITESPACE@5..6 " "
@ -31,98 +31,3 @@ SOURCE_FILE@0..83
R_ANGLE@16..17 ">"
SEMICOLON@17..18 ";"
WHITESPACE@18..19 "\n"
TRAIT@19..51
TRAIT_KW@19..24 "trait"
WHITESPACE@24..25 " "
NAME@25..26
IDENT@25..26 "Z"
GENERIC_PARAM_LIST@26..29
L_ANGLE@26..27 "<"
TYPE_PARAM@27..28
NAME@27..28
IDENT@27..28 "U"
R_ANGLE@28..29 ">"
WHITESPACE@29..30 " "
EQ@30..31 "="
WHITESPACE@31..32 " "
TYPE_BOUND_LIST@32..36
TYPE_BOUND@32..36
PATH_TYPE@32..36
PATH@32..36
PATH_SEGMENT@32..36
NAME_REF@32..33
IDENT@32..33 "T"
GENERIC_ARG_LIST@33..36
L_ANGLE@33..34 "<"
TYPE_ARG@34..35
PATH_TYPE@34..35
PATH@34..35
PATH_SEGMENT@34..35
NAME_REF@34..35
IDENT@34..35 "U"
R_ANGLE@35..36 ">"
WHITESPACE@36..37 " "
WHERE_CLAUSE@37..50
WHERE_KW@37..42 "where"
WHITESPACE@42..43 " "
WHERE_PRED@43..50
PATH_TYPE@43..44
PATH@43..44
PATH_SEGMENT@43..44
NAME_REF@43..44
IDENT@43..44 "U"
COLON@44..45 ":"
WHITESPACE@45..46 " "
TYPE_BOUND_LIST@46..50
TYPE_BOUND@46..50
PATH_TYPE@46..50
PATH@46..50
PATH_SEGMENT@46..50
NAME_REF@46..50
IDENT@46..50 "Copy"
SEMICOLON@50..51 ";"
WHITESPACE@51..52 "\n"
TRAIT@52..82
TRAIT_KW@52..57 "trait"
WHITESPACE@57..58 " "
NAME@58..59
IDENT@58..59 "Z"
GENERIC_PARAM_LIST@59..62
L_ANGLE@59..60 "<"
TYPE_PARAM@60..61
NAME@60..61
IDENT@60..61 "U"
R_ANGLE@61..62 ">"
WHITESPACE@62..63 " "
EQ@63..64 "="
WHITESPACE@64..65 " "
TYPE_BOUND_LIST@65..65
WHERE_CLAUSE@65..81
WHERE_KW@65..70 "where"
WHITESPACE@70..71 " "
WHERE_PRED@71..81
PATH_TYPE@71..75
PATH@71..75
PATH_SEGMENT@71..75
NAME_REF@71..75
IDENT@71..75 "Self"
COLON@75..76 ":"
WHITESPACE@76..77 " "
TYPE_BOUND_LIST@77..81
TYPE_BOUND@77..81
PATH_TYPE@77..81
PATH@77..81
PATH_SEGMENT@77..81
NAME_REF@77..78
IDENT@77..78 "T"
GENERIC_ARG_LIST@78..81
L_ANGLE@78..79 "<"
TYPE_ARG@79..80
PATH_TYPE@79..80
PATH@79..80
PATH_SEGMENT@79..80
NAME_REF@79..80
IDENT@79..80 "U"
R_ANGLE@80..81 ">"
SEMICOLON@81..82 ";"
WHITESPACE@82..83 "\n"

View File

@ -1,3 +1 @@
trait Z<U> = T<U>;
trait Z<U> = T<U> where U: Copy;
trait Z<U> = where Self: T<U>;

View File

@ -1 +0,0 @@
impl const Send for X {}

View File

@ -16,7 +16,7 @@ SOURCE_FILE@0..25
PATH@20..21
PATH_SEGMENT@20..21
NAME_REF@20..21
IDENT@20..21 "X"
IDENT@20..21 "S"
WHITESPACE@21..22 " "
ASSOC_ITEM_LIST@22..24
L_CURLY@22..23 "{"

View File

@ -0,0 +1 @@
impl const Send for S {}

View File

@ -0,0 +1,35 @@
SOURCE_FILE@0..31
TRAIT@0..30
TRAIT_KW@0..5 "trait"
WHITESPACE@5..6 " "
NAME@6..7
IDENT@6..7 "X"
GENERIC_PARAM_LIST@7..27
L_ANGLE@7..8 "<"
TYPE_PARAM@8..26
NAME@8..9
IDENT@8..9 "U"
COLON@9..10 ":"
WHITESPACE@10..11 " "
TYPE_BOUND_LIST@11..26
TYPE_BOUND@11..16
PATH_TYPE@11..16
PATH@11..16
PATH_SEGMENT@11..16
NAME_REF@11..16
IDENT@11..16 "Debug"
WHITESPACE@16..17 " "
PLUS@17..18 "+"
WHITESPACE@18..19 " "
TYPE_BOUND@19..26
PATH_TYPE@19..26
PATH@19..26
PATH_SEGMENT@19..26
NAME_REF@19..26
IDENT@19..26 "Display"
R_ANGLE@26..27 ">"
WHITESPACE@27..28 " "
ASSOC_ITEM_LIST@28..30
L_CURLY@28..29 "{"
R_CURLY@29..30 "}"
WHITESPACE@30..31 "\n"

View File

@ -0,0 +1 @@
trait X<U: Debug + Display> {}

View File

@ -0,0 +1,29 @@
SOURCE_FILE@0..25
TRAIT@0..24
TRAIT_KW@0..5 "trait"
WHITESPACE@5..6 " "
NAME@6..7
IDENT@6..7 "T"
COLON@7..8 ":"
WHITESPACE@8..9 " "
TYPE_BOUND_LIST@9..21
TYPE_BOUND@9..13
PATH_TYPE@9..13
PATH@9..13
PATH_SEGMENT@9..13
NAME_REF@9..13
IDENT@9..13 "Hash"
WHITESPACE@13..14 " "
PLUS@14..15 "+"
WHITESPACE@15..16 " "
TYPE_BOUND@16..21
PATH_TYPE@16..21
PATH@16..21
PATH_SEGMENT@16..21
NAME_REF@16..21
IDENT@16..21 "Clone"
WHITESPACE@21..22 " "
ASSOC_ITEM_LIST@22..24
L_CURLY@22..23 "{"
R_CURLY@23..24 "}"
WHITESPACE@24..25 "\n"

View File

@ -0,0 +1 @@
trait T: Hash + Clone {}

View File

@ -0,0 +1,30 @@
SOURCE_FILE@0..28
TRAIT@0..27
TRAIT_KW@0..5 "trait"
WHITESPACE@5..6 " "
NAME@6..7
IDENT@6..7 "T"
WHITESPACE@7..8 " "
WHERE_CLAUSE@8..24
WHERE_KW@8..13 "where"
WHITESPACE@13..14 " "
WHERE_PRED@14..24
PATH_TYPE@14..18
PATH@14..18
PATH_SEGMENT@14..18
NAME_REF@14..18
IDENT@14..18 "Self"
COLON@18..19 ":"
WHITESPACE@19..20 " "
TYPE_BOUND_LIST@20..24
TYPE_BOUND@20..24
PATH_TYPE@20..24
PATH@20..24
PATH_SEGMENT@20..24
NAME_REF@20..24
IDENT@20..24 "Copy"
WHITESPACE@24..25 " "
ASSOC_ITEM_LIST@25..27
L_CURLY@25..26 "{"
R_CURLY@26..27 "}"
WHITESPACE@27..28 "\n"

View File

@ -0,0 +1 @@
trait T where Self: Copy {}

View File

@ -0,0 +1,26 @@
SOURCE_FILE@0..20
IMPL@0..19
IMPL_KW@0..4 "impl"
WHITESPACE@4..5 " "
PATH_TYPE@5..6
PATH@5..6
PATH_SEGMENT@5..6
NAME_REF@5..6
IDENT@5..6 "S"
WHITESPACE@6..7 " "
ASSOC_ITEM_LIST@7..19
L_CURLY@7..8 "{"
WHITESPACE@8..9 " "
ATTR@9..17
POUND@9..10 "#"
BANG@10..11 "!"
L_BRACK@11..12 "["
META@12..16
PATH@12..16
PATH_SEGMENT@12..16
NAME_REF@12..16
IDENT@12..16 "attr"
R_BRACK@16..17 "]"
WHITESPACE@17..18 " "
R_CURLY@18..19 "}"
WHITESPACE@19..20 "\n"

View File

@ -0,0 +1 @@
impl S { #![attr] }

View File

@ -0,0 +1,96 @@
SOURCE_FILE@0..64
TRAIT@0..32
TRAIT_KW@0..5 "trait"
WHITESPACE@5..6 " "
NAME@6..7
IDENT@6..7 "Z"
GENERIC_PARAM_LIST@7..10
L_ANGLE@7..8 "<"
TYPE_PARAM@8..9
NAME@8..9
IDENT@8..9 "U"
R_ANGLE@9..10 ">"
WHITESPACE@10..11 " "
EQ@11..12 "="
WHITESPACE@12..13 " "
TYPE_BOUND_LIST@13..17
TYPE_BOUND@13..17
PATH_TYPE@13..17
PATH@13..17
PATH_SEGMENT@13..17
NAME_REF@13..14
IDENT@13..14 "T"
GENERIC_ARG_LIST@14..17
L_ANGLE@14..15 "<"
TYPE_ARG@15..16
PATH_TYPE@15..16
PATH@15..16
PATH_SEGMENT@15..16
NAME_REF@15..16
IDENT@15..16 "U"
R_ANGLE@16..17 ">"
WHITESPACE@17..18 " "
WHERE_CLAUSE@18..31
WHERE_KW@18..23 "where"
WHITESPACE@23..24 " "
WHERE_PRED@24..31
PATH_TYPE@24..25
PATH@24..25
PATH_SEGMENT@24..25
NAME_REF@24..25
IDENT@24..25 "U"
COLON@25..26 ":"
WHITESPACE@26..27 " "
TYPE_BOUND_LIST@27..31
TYPE_BOUND@27..31
PATH_TYPE@27..31
PATH@27..31
PATH_SEGMENT@27..31
NAME_REF@27..31
IDENT@27..31 "Copy"
SEMICOLON@31..32 ";"
WHITESPACE@32..33 "\n"
TRAIT@33..63
TRAIT_KW@33..38 "trait"
WHITESPACE@38..39 " "
NAME@39..40
IDENT@39..40 "Z"
GENERIC_PARAM_LIST@40..43
L_ANGLE@40..41 "<"
TYPE_PARAM@41..42
NAME@41..42
IDENT@41..42 "U"
R_ANGLE@42..43 ">"
WHITESPACE@43..44 " "
EQ@44..45 "="
WHITESPACE@45..46 " "
TYPE_BOUND_LIST@46..46
WHERE_CLAUSE@46..62
WHERE_KW@46..51 "where"
WHITESPACE@51..52 " "
WHERE_PRED@52..62
PATH_TYPE@52..56
PATH@52..56
PATH_SEGMENT@52..56
NAME_REF@52..56
IDENT@52..56 "Self"
COLON@56..57 ":"
WHITESPACE@57..58 " "
TYPE_BOUND_LIST@58..62
TYPE_BOUND@58..62
PATH_TYPE@58..62
PATH@58..62
PATH_SEGMENT@58..62
NAME_REF@58..59
IDENT@58..59 "T"
GENERIC_ARG_LIST@59..62
L_ANGLE@59..60 "<"
TYPE_ARG@60..61
PATH_TYPE@60..61
PATH@60..61
PATH_SEGMENT@60..61
NAME_REF@60..61
IDENT@60..61 "U"
R_ANGLE@61..62 ">"
SEMICOLON@62..63 ";"
WHITESPACE@63..64 "\n"

View File

@ -0,0 +1,2 @@
trait Z<U> = T<U> where U: Copy;
trait Z<U> = where Self: T<U>;