48: Types r=matklad a=matklad

bors r+
This commit is contained in:
bors[bot] 2018-02-11 09:58:32 +00:00
commit 7176029803
31 changed files with 488 additions and 34 deletions

View file

@ -105,6 +105,12 @@ Grammar(
"TUPLE_TYPE",
"NEVER_TYPE",
"PATH_TYPE",
"POINTER_TYPE",
"ARRAY_TYPE",
"SLICE_TYPE",
"REFERENCE_TYPE",
"PLACEHOLDER_TYPE",
"FN_POINTER_TYPE",
"EXTERN_BLOCK",
"ENUM_VARIANT",

View file

@ -14,7 +14,7 @@ fn const_or_static(p: &mut Parser, kw: SyntaxKind) {
p.eat(MUT_KW); // TODO: validator to forbid const mut
name(p);
p.expect(COLON);
types::ty(p);
types::type_(p);
p.expect(EQ);
expressions::expr(p);
p.expect(SEMI);

View file

@ -222,12 +222,6 @@ fn fn_item(p: &mut Parser) {
p.expect(L_CURLY);
p.expect(R_CURLY);
}
fn fn_value_parameters(p: &mut Parser) {
assert!(p.at(L_PAREN));
p.bump();
p.expect(R_PAREN);
}
}
// test type_item
@ -247,7 +241,7 @@ fn type_item(p: &mut Parser) {
type_params::where_clause(p);
p.expect(EQ);
types::ty(p);
types::type_(p);
p.expect(SEMI);
}
@ -263,14 +257,3 @@ fn mod_item(p: &mut Parser) {
}
}
}
fn abi(p: &mut Parser) {
assert!(p.at(EXTERN_KW));
let abi = p.start();
p.bump();
match p.current() {
STRING | RAW_STRING => p.bump(),
_ => (),
}
abi.complete(p, ABI);
}

View file

@ -89,7 +89,7 @@ fn named_fields(p: &mut Parser) {
if p.at(IDENT) {
name(p);
p.expect(COLON);
types::ty(p);
types::type_(p);
field.complete(p, NAMED_FIELD);
} else {
field.abandon(p);
@ -105,7 +105,7 @@ fn pos_fields(p: &mut Parser) {
while !p.at(R_PAREN) && !p.at(EOF) {
let pos_field = p.start();
visibility(p);
types::ty(p);
types::type_(p);
pos_field.complete(p, POS_FIELD);
if !p.at(R_PAREN) {

View file

@ -50,6 +50,30 @@ fn alias(p: &mut Parser) -> bool {
true //FIXME: return false if three are errors
}
fn abi(p: &mut Parser) {
assert!(p.at(EXTERN_KW));
let abi = p.start();
p.bump();
match p.current() {
STRING | RAW_STRING => p.bump(),
_ => (),
}
abi.complete(p, ABI);
}
fn fn_value_parameters(p: &mut Parser) {
assert!(p.at(L_PAREN));
p.bump();
p.expect(R_PAREN);
}
fn fn_ret_type(p: &mut Parser) {
if p.at(THIN_ARROW) {
p.bump();
types::type_(p);
}
}
fn name(p: &mut Parser) {
if p.at(IDENT) {
let m = p.start();

View file

@ -62,7 +62,7 @@ pub(super) fn list(p: &mut Parser) {
}
}
if p.at(EQ) {
types::ty(p)
types::type_(p)
}
m.complete(p, TYPE_PARAM);
}

View file

@ -1,8 +1,14 @@
use super::*;
pub(super) fn ty(p: &mut Parser) {
pub(super) fn type_(p: &mut Parser) {
match p.current() {
L_PAREN => paren_or_tuple_ty(p),
L_PAREN => paren_or_tuple_type(p),
EXCL => never_type(p),
STAR => pointer_type(p),
L_BRACK => array_or_slice_type(p),
AMPERSAND => reference_type(p),
UNDERSCORE => placeholder_type(p),
FN_KW | UNSAFE_KW | EXTERN_KW => fn_pointer_type(p),
IDENT => path_type(p),
_ => {
p.error("expected type");
@ -10,7 +16,11 @@ pub(super) fn ty(p: &mut Parser) {
}
}
fn paren_or_tuple_ty(p: &mut Parser) {
fn type_no_plus(p: &mut Parser) {
type_(p);
}
fn paren_or_tuple_type(p: &mut Parser) {
assert!(p.at(L_PAREN));
let m = p.start();
p.bump();
@ -18,7 +28,7 @@ fn paren_or_tuple_ty(p: &mut Parser) {
let mut trailing_comma: bool = false;
while !p.at(EOF) && !p.at(R_PAREN) {
n_types += 1;
ty(p);
type_(p);
if p.eat(COMMA) {
trailing_comma = true;
} else {
@ -43,6 +53,119 @@ fn paren_or_tuple_ty(p: &mut Parser) {
m.complete(p, kind);
}
// test never_type
// type Never = !;
fn never_type(p: &mut Parser) {
assert!(p.at(EXCL));
let m = p.start();
p.bump();
m.complete(p, NEVER_TYPE);
}
fn pointer_type(p: &mut Parser) {
assert!(p.at(STAR));
let m = p.start();
p.bump();
match p.current() {
// test pointer_type_mut
// type M = *mut ();
// type C = *mut ();
MUT_KW | CONST_KW => p.bump(),
_ => {
// test pointer_type_no_mutability
// type T = *();
p.error(
"expected mut or const in raw pointer type \
(use `*mut T` or `*const T` as appropriate)",
);
}
};
type_no_plus(p);
m.complete(p, POINTER_TYPE);
}
fn array_or_slice_type(p: &mut Parser) {
assert!(p.at(L_BRACK));
let m = p.start();
p.bump();
type_(p);
let kind = match p.current() {
// test slice_type
// type T = [()];
R_BRACK => {
p.bump();
SLICE_TYPE
}
// test array_type
// type T = [(); 92];
SEMI => {
p.bump();
expressions::expr(p);
p.expect(R_BRACK);
ARRAY_TYPE
}
// test array_type_missing_semi
// type T = [() 92];
_ => {
p.error("expected `;` or `]`");
SLICE_TYPE
}
};
m.complete(p, kind);
}
// test reference_type;
// type A = &();
// type B = &'static ();
// type C = &mut ();
fn reference_type(p: &mut Parser) {
assert!(p.at(AMPERSAND));
let m = p.start();
p.bump();
p.eat(LIFETIME);
p.eat(MUT_KW);
type_no_plus(p);
m.complete(p, REFERENCE_TYPE);
}
// test placeholder_type
// type Placeholder = _;
fn placeholder_type(p: &mut Parser) {
assert!(p.at(UNDERSCORE));
let m = p.start();
p.bump();
m.complete(p, PLACEHOLDER_TYPE);
}
// test fn_pointer_type
// type A = fn();
// type B = unsafe fn();
// type C = unsafe extern "C" fn();
fn fn_pointer_type(p: &mut Parser) {
let m = p.start();
p.eat(UNSAFE_KW);
if p.at(EXTERN_KW) {
abi(p);
}
// test fn_pointer_type_missing_fn
// type F = unsafe ();
if !p.eat(FN_KW) {
m.abandon(p);
p.error("expected `fn`");
return;
}
fn_value_parameters(p);
// test fn_pointer_type_with_ret
// type F = fn() -> ();
fn_ret_type(p);
m.complete(p, FN_POINTER_TYPE);
}
fn path_type(p: &mut Parser) {
assert!(p.at(IDENT));
let m = p.start();

View file

@ -103,6 +103,12 @@ pub enum SyntaxKind {
TUPLE_TYPE,
NEVER_TYPE,
PATH_TYPE,
POINTER_TYPE,
ARRAY_TYPE,
SLICE_TYPE,
REFERENCE_TYPE,
PLACEHOLDER_TYPE,
FN_POINTER_TYPE,
EXTERN_BLOCK,
ENUM_VARIANT,
NAMED_FIELD,
@ -232,6 +238,12 @@ impl SyntaxKind {
TUPLE_TYPE => &SyntaxInfo { name: "TUPLE_TYPE" },
NEVER_TYPE => &SyntaxInfo { name: "NEVER_TYPE" },
PATH_TYPE => &SyntaxInfo { name: "PATH_TYPE" },
POINTER_TYPE => &SyntaxInfo { name: "POINTER_TYPE" },
ARRAY_TYPE => &SyntaxInfo { name: "ARRAY_TYPE" },
SLICE_TYPE => &SyntaxInfo { name: "SLICE_TYPE" },
REFERENCE_TYPE => &SyntaxInfo { name: "REFERENCE_TYPE" },
PLACEHOLDER_TYPE => &SyntaxInfo { name: "PLACEHOLDER_TYPE" },
FN_POINTER_TYPE => &SyntaxInfo { name: "FN_POINTER_TYPE" },
EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" },
ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" },
NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" },

View file

@ -0,0 +1 @@
type Never = !;

View file

@ -0,0 +1,13 @@
FILE@[0; 16)
TYPE_ITEM@[0; 16)
TYPE_KW@[0; 4)
NAME@[4; 11)
WHITESPACE@[4; 5)
IDENT@[5; 10) "Never"
WHITESPACE@[10; 11)
EQ@[11; 12)
NEVER_TYPE@[12; 14)
WHITESPACE@[12; 13)
EXCL@[13; 14)
SEMI@[14; 15)
WHITESPACE@[15; 16)

View file

@ -0,0 +1 @@
type T = *();

View file

@ -0,0 +1,17 @@
FILE@[0; 14)
TYPE_ITEM@[0; 14)
TYPE_KW@[0; 4)
NAME@[4; 7)
WHITESPACE@[4; 5)
IDENT@[5; 6) "T"
WHITESPACE@[6; 7)
EQ@[7; 8)
POINTER_TYPE@[8; 12)
WHITESPACE@[8; 9)
STAR@[9; 10)
err: `expected mut or const in raw pointer type (use `*mut T` or `*const T` as appropriate)`
TUPLE_TYPE@[10; 12)
L_PAREN@[10; 11)
R_PAREN@[11; 12)
SEMI@[12; 13)
WHITESPACE@[13; 14)

View file

@ -0,0 +1,2 @@
type M = *mut ();
type C = *mut ();

View file

@ -0,0 +1,35 @@
FILE@[0; 36)
TYPE_ITEM@[0; 18)
TYPE_KW@[0; 4)
NAME@[4; 7)
WHITESPACE@[4; 5)
IDENT@[5; 6) "M"
WHITESPACE@[6; 7)
EQ@[7; 8)
POINTER_TYPE@[8; 16)
WHITESPACE@[8; 9)
STAR@[9; 10)
MUT_KW@[10; 13)
TUPLE_TYPE@[13; 16)
WHITESPACE@[13; 14)
L_PAREN@[14; 15)
R_PAREN@[15; 16)
SEMI@[16; 17)
WHITESPACE@[17; 18)
TYPE_ITEM@[18; 36)
TYPE_KW@[18; 22)
NAME@[22; 25)
WHITESPACE@[22; 23)
IDENT@[23; 24) "C"
WHITESPACE@[24; 25)
EQ@[25; 26)
POINTER_TYPE@[26; 34)
WHITESPACE@[26; 27)
STAR@[27; 28)
MUT_KW@[28; 31)
TUPLE_TYPE@[31; 34)
WHITESPACE@[31; 32)
L_PAREN@[32; 33)
R_PAREN@[33; 34)
SEMI@[34; 35)
WHITESPACE@[35; 36)

View file

@ -0,0 +1 @@
type T = [() 92];

View file

@ -0,0 +1,28 @@
FILE@[0; 18)
TYPE_ITEM@[0; 13)
TYPE_KW@[0; 4)
NAME@[4; 7)
WHITESPACE@[4; 5)
IDENT@[5; 6) "T"
WHITESPACE@[6; 7)
EQ@[7; 8)
SLICE_TYPE@[8; 13)
WHITESPACE@[8; 9)
L_BRACK@[9; 10)
TUPLE_TYPE@[10; 13)
L_PAREN@[10; 11)
R_PAREN@[11; 12)
WHITESPACE@[12; 13)
err: `expected `;` or `]``
err: `expected SEMI`
ERROR@[13; 15)
err: `expected item`
INT_NUMBER@[13; 15)
ERROR@[15; 16)
err: `expected item`
R_BRACK@[15; 16)
ERROR@[16; 18)
err: `expected item, found `;`
consider removing this semicolon`
SEMI@[16; 17)
WHITESPACE@[17; 18)

View file

@ -0,0 +1 @@
type T = [(); 92];

View file

@ -0,0 +1,21 @@
FILE@[0; 19)
TYPE_ITEM@[0; 19)
TYPE_KW@[0; 4)
NAME@[4; 7)
WHITESPACE@[4; 5)
IDENT@[5; 6) "T"
WHITESPACE@[6; 7)
EQ@[7; 8)
ARRAY_TYPE@[8; 17)
WHITESPACE@[8; 9)
L_BRACK@[9; 10)
TUPLE_TYPE@[10; 12)
L_PAREN@[10; 11)
R_PAREN@[11; 12)
SEMI@[12; 13)
LITERAL@[13; 16)
WHITESPACE@[13; 14)
INT_NUMBER@[14; 16)
R_BRACK@[16; 17)
SEMI@[17; 18)
WHITESPACE@[18; 19)

View file

@ -0,0 +1 @@
type T = [()];

View file

@ -0,0 +1,17 @@
FILE@[0; 15)
TYPE_ITEM@[0; 15)
TYPE_KW@[0; 4)
NAME@[4; 7)
WHITESPACE@[4; 5)
IDENT@[5; 6) "T"
WHITESPACE@[6; 7)
EQ@[7; 8)
SLICE_TYPE@[8; 13)
WHITESPACE@[8; 9)
L_BRACK@[9; 10)
TUPLE_TYPE@[10; 12)
L_PAREN@[10; 11)
R_PAREN@[11; 12)
R_BRACK@[12; 13)
SEMI@[13; 14)
WHITESPACE@[14; 15)

View file

@ -0,0 +1,3 @@
type A = &();
type B = &'static ();
type C = &mut ();

View file

@ -0,0 +1,50 @@
FILE@[0; 54)
TYPE_ITEM@[0; 14)
TYPE_KW@[0; 4)
NAME@[4; 7)
WHITESPACE@[4; 5)
IDENT@[5; 6) "A"
WHITESPACE@[6; 7)
EQ@[7; 8)
REFERENCE_TYPE@[8; 12)
WHITESPACE@[8; 9)
AMPERSAND@[9; 10)
TUPLE_TYPE@[10; 12)
L_PAREN@[10; 11)
R_PAREN@[11; 12)
SEMI@[12; 13)
WHITESPACE@[13; 14)
TYPE_ITEM@[14; 36)
TYPE_KW@[14; 18)
NAME@[18; 21)
WHITESPACE@[18; 19)
IDENT@[19; 20) "B"
WHITESPACE@[20; 21)
EQ@[21; 22)
REFERENCE_TYPE@[22; 34)
WHITESPACE@[22; 23)
AMPERSAND@[23; 24)
LIFETIME@[24; 31) "'static"
TUPLE_TYPE@[31; 34)
WHITESPACE@[31; 32)
L_PAREN@[32; 33)
R_PAREN@[33; 34)
SEMI@[34; 35)
WHITESPACE@[35; 36)
TYPE_ITEM@[36; 54)
TYPE_KW@[36; 40)
NAME@[40; 43)
WHITESPACE@[40; 41)
IDENT@[41; 42) "C"
WHITESPACE@[42; 43)
EQ@[43; 44)
REFERENCE_TYPE@[44; 52)
WHITESPACE@[44; 45)
AMPERSAND@[45; 46)
MUT_KW@[46; 49)
TUPLE_TYPE@[49; 52)
WHITESPACE@[49; 50)
L_PAREN@[50; 51)
R_PAREN@[51; 52)
SEMI@[52; 53)
WHITESPACE@[53; 54)

View file

@ -0,0 +1 @@
type Placeholder = _;

View file

@ -0,0 +1,13 @@
FILE@[0; 22)
TYPE_ITEM@[0; 22)
TYPE_KW@[0; 4)
NAME@[4; 17)
WHITESPACE@[4; 5)
IDENT@[5; 16) "Placeholder"
WHITESPACE@[16; 17)
EQ@[17; 18)
PLACEHOLDER_TYPE@[18; 20)
WHITESPACE@[18; 19)
UNDERSCORE@[19; 20)
SEMI@[20; 21)
WHITESPACE@[21; 22)

View file

@ -0,0 +1,3 @@
type A = fn();
type B = unsafe fn();
type C = unsafe extern "C" fn();

View file

@ -0,0 +1,52 @@
FILE@[0; 70)
TYPE_ITEM@[0; 15)
TYPE_KW@[0; 4)
NAME@[4; 7)
WHITESPACE@[4; 5)
IDENT@[5; 6) "A"
WHITESPACE@[6; 7)
EQ@[7; 8)
FN_POINTER_TYPE@[8; 13)
WHITESPACE@[8; 9)
FN_KW@[9; 11)
L_PAREN@[11; 12)
R_PAREN@[12; 13)
SEMI@[13; 14)
WHITESPACE@[14; 15)
TYPE_ITEM@[15; 37)
TYPE_KW@[15; 19)
NAME@[19; 22)
WHITESPACE@[19; 20)
IDENT@[20; 21) "B"
WHITESPACE@[21; 22)
EQ@[22; 23)
FN_POINTER_TYPE@[23; 35)
WHITESPACE@[23; 24)
UNSAFE_KW@[24; 30)
WHITESPACE@[30; 31)
FN_KW@[31; 33)
L_PAREN@[33; 34)
R_PAREN@[34; 35)
SEMI@[35; 36)
WHITESPACE@[36; 37)
TYPE_ITEM@[37; 70)
TYPE_KW@[37; 41)
NAME@[41; 44)
WHITESPACE@[41; 42)
IDENT@[42; 43) "C"
WHITESPACE@[43; 44)
EQ@[44; 45)
FN_POINTER_TYPE@[45; 68)
WHITESPACE@[45; 46)
UNSAFE_KW@[46; 52)
ABI@[52; 64)
WHITESPACE@[52; 53)
EXTERN_KW@[53; 59)
WHITESPACE@[59; 60)
STRING@[60; 63)
WHITESPACE@[63; 64)
FN_KW@[64; 66)
L_PAREN@[66; 67)
R_PAREN@[67; 68)
SEMI@[68; 69)
WHITESPACE@[69; 70)

View file

@ -0,0 +1 @@
type F = unsafe ();

View file

@ -0,0 +1,24 @@
FILE@[0; 20)
TYPE_ITEM@[0; 16)
TYPE_KW@[0; 4)
NAME@[4; 7)
WHITESPACE@[4; 5)
IDENT@[5; 6) "F"
WHITESPACE@[6; 7)
EQ@[7; 8)
WHITESPACE@[8; 9)
UNSAFE_KW@[9; 15)
err: `expected `fn``
err: `expected SEMI`
WHITESPACE@[15; 16)
ERROR@[16; 17)
err: `expected item`
L_PAREN@[16; 17)
ERROR@[17; 18)
err: `expected item`
R_PAREN@[17; 18)
ERROR@[18; 20)
err: `expected item, found `;`
consider removing this semicolon`
SEMI@[18; 19)
WHITESPACE@[19; 20)

View file

@ -0,0 +1 @@
type F = fn() -> ();

View file

@ -0,0 +1,21 @@
FILE@[0; 21)
TYPE_ITEM@[0; 21)
TYPE_KW@[0; 4)
NAME@[4; 7)
WHITESPACE@[4; 5)
IDENT@[5; 6) "F"
WHITESPACE@[6; 7)
EQ@[7; 8)
FN_POINTER_TYPE@[8; 19)
WHITESPACE@[8; 9)
FN_KW@[9; 11)
L_PAREN@[11; 12)
R_PAREN@[12; 13)
WHITESPACE@[13; 14)
THIN_ARROW@[14; 16)
TUPLE_TYPE@[16; 19)
WHITESPACE@[16; 17)
L_PAREN@[17; 18)
R_PAREN@[18; 19)
SEMI@[19; 20)
WHITESPACE@[20; 21)

View file

@ -26,21 +26,20 @@ where
F: Fn(&str) -> String,
{
for path in collect_tests(paths) {
let actual = {
let text = read_text(&path);
f(&text)
};
let input_code = read_text(&path);
let parse_tree = f(&input_code);
let path = path.with_extension("txt");
if !path.exists() {
println!("\nfile: {}", path.display());
println!("No .txt file with expected result, creating...");
file::put_text(&path, actual).unwrap();
println!("No .txt file with expected result, creating...\n");
println!("{}\n{}", input_code, parse_tree);
file::put_text(&path, parse_tree).unwrap();
panic!("No expected result")
}
let expected = read_text(&path);
let expected = expected.as_str();
let actual = actual.as_str();
assert_equal_text(expected, actual, &path);
let parse_tree = parse_tree.as_str();
assert_equal_text(expected, parse_tree, &path);
}
}