1 // edition:2018
2 #![crate_type = "lib"]
3 #![feature(type_ascription)]
4 use std::future::Future;
5 use std::pin::Pin;
6 
7 // This tests the parser for "x as Y[z]". It errors, but we want to give useful
8 // errors and parse such that further code gives useful errors.
index_after_as_cast()9 pub fn index_after_as_cast() {
10     vec![1, 2, 3] as Vec<i32>[0];
11     //~^ ERROR: casts cannot be followed by indexing
12     vec![1, 2, 3]: Vec<i32>[0];
13     //~^ ERROR: casts cannot be followed by indexing
14 }
15 
index_after_cast_to_index()16 pub fn index_after_cast_to_index() {
17     (&[0]) as &[i32][0];
18     //~^ ERROR: casts cannot be followed by indexing
19     (&[0i32]): &[i32; 1][0];
20     //~^ ERROR: casts cannot be followed by indexing
21 }
22 
cast_after_cast()23 pub fn cast_after_cast() {
24     if 5u64 as i32 as u16 == 0u16 {
25 
26     }
27     if 5u64: u64: u64 == 0u64 {
28 
29     }
30     let _ = 5u64: u64: u64 as u8 as i8 == 9i8;
31     let _ = 0i32: i32: i32;
32     let _ = 0 as i32: i32;
33     let _ = 0i32: i32 as i32;
34     let _ = 0 as i32 as i32;
35     let _ = 0i32: i32: i32 as u32 as i32;
36 }
37 
cast_cast_method_call()38 pub fn cast_cast_method_call() {
39     let _ = 0i32: i32: i32.count_ones();
40     //~^ ERROR: casts cannot be followed by a method call
41     let _ = 0 as i32: i32.count_ones();
42     //~^ ERROR: casts cannot be followed by a method call
43     let _ = 0i32: i32 as i32.count_ones();
44     //~^ ERROR: casts cannot be followed by a method call
45     let _ = 0 as i32 as i32.count_ones();
46     //~^ ERROR: casts cannot be followed by a method call
47     let _ = 0i32: i32: i32 as u32 as i32.count_ones();
48     //~^ ERROR: casts cannot be followed by a method call
49     let _ = 0i32: i32.count_ones(): u32;
50     //~^ ERROR: casts cannot be followed by a method call
51     let _ = 0 as i32.count_ones(): u32;
52     //~^ ERROR: casts cannot be followed by a method call
53     let _ = 0i32: i32.count_ones() as u32;
54     //~^ ERROR: casts cannot be followed by a method call
55     let _ = 0 as i32.count_ones() as u32;
56     //~^ ERROR: casts cannot be followed by a method call
57     let _ = 0i32: i32: i32.count_ones() as u32 as i32;
58     //~^ ERROR: casts cannot be followed by a method call
59 }
60 
multiline_error()61 pub fn multiline_error() {
62     let _ = 0
63         as i32
64         .count_ones();
65     //~^^^ ERROR: casts cannot be followed by a method call
66 }
67 
68 // this tests that the precedence for `!x as Y.Z` is still what we expect
precedence()69 pub fn precedence() {
70     let x: i32 = &vec![1, 2, 3] as &Vec<i32>[0];
71     //~^ ERROR: casts cannot be followed by indexing
72 }
73 
method_calls()74 pub fn method_calls() {
75     0 as i32.max(0);
76     //~^ ERROR: casts cannot be followed by a method call
77     0: i32.max(0);
78     //~^ ERROR: casts cannot be followed by a method call
79 }
80 
complex()81 pub fn complex() {
82     let _ = format!(
83         "{} and {}",
84         if true { 33 } else { 44 } as i32.max(0),
85         //~^ ERROR: casts cannot be followed by a method call
86         if true { 33 } else { 44 }: i32.max(0)
87         //~^ ERROR: casts cannot be followed by a method call
88     );
89 }
90 
in_condition()91 pub fn in_condition() {
92     if 5u64 as i32.max(0) == 0 {
93         //~^ ERROR: casts cannot be followed by a method call
94     }
95     if 5u64: u64.max(0) == 0 {
96         //~^ ERROR: casts cannot be followed by a method call
97     }
98 }
99 
inside_block()100 pub fn inside_block() {
101     let _ = if true {
102         5u64 as u32.max(0) == 0
103         //~^ ERROR: casts cannot be followed by a method call
104     } else { false };
105     let _ = if true {
106         5u64: u64.max(0) == 0
107         //~^ ERROR: casts cannot be followed by a method call
108     } else { false };
109 }
110 
111 static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]);
112 //~^ ERROR: casts cannot be followed by indexing
113 
114 static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]);
115 //~^ ERROR: casts cannot be followed by indexing
116 
117 
cast_then_try() -> Result<u64,u64>118 pub fn cast_then_try() -> Result<u64,u64> {
119     Err(0u64) as Result<u64,u64>?;
120     //~^ ERROR: casts cannot be followed by ?
121     Err(0u64): Result<u64,u64>?;
122     //~^ ERROR: casts cannot be followed by ?
123     Ok(1)
124 }
125 
126 
cast_then_call()127 pub fn cast_then_call() {
128     type F = fn(u8);
129     // type ascription won't actually do [unique drop fn type] -> fn(u8) casts.
130     let drop_ptr = drop as fn(u8);
131     drop as F();
132     //~^ ERROR: parenthesized type parameters may only be used with a `Fn` trait [E0214]
133     drop_ptr: F();
134     //~^ ERROR: parenthesized type parameters may only be used with a `Fn` trait [E0214]
135 }
136 
cast_to_fn_should_work()137 pub fn cast_to_fn_should_work() {
138     let drop_ptr = drop as fn(u8);
139     drop as fn(u8);
140     drop_ptr: fn(u8);
141 }
142 
parens_after_cast_error()143 pub fn parens_after_cast_error() {
144     let drop_ptr = drop as fn(u8);
145     drop as fn(u8)(0);
146     //~^ ERROR: casts cannot be followed by a function call
147     drop_ptr: fn(u8)(0);
148     //~^ ERROR: casts cannot be followed by a function call
149 }
150 
cast_then_await()151 pub async fn cast_then_await() {
152     Box::pin(noop()) as Pin<Box<dyn Future<Output = ()>>>.await;
153     //~^ ERROR: casts cannot be followed by `.await`
154 
155     Box::pin(noop()): Pin<Box<_>>.await;
156     //~^ ERROR: casts cannot be followed by `.await`
157 }
158 
noop()159 pub async fn noop() {}
160 
161 #[derive(Default)]
162 pub struct Foo {
163     pub bar: u32,
164 }
165 
struct_field()166 pub fn struct_field() {
167     Foo::default() as Foo.bar;
168     //~^ ERROR: cannot be followed by a field access
169     Foo::default(): Foo.bar;
170     //~^ ERROR: cannot be followed by a field access
171 }
172