Result-ify src/parser.rs (#608)

* Make ConvertToAst trait fallible

It's got some panics, and we'll be switching those to errors!

* First example of a diagnostic-driven error

Add a diagnostic-driven error `#[wasm_bindgen]` being attached to public
functions, and add some macros to boot to make it easier to generate errors!

* Result-ify `src/parser.rs`

This commit converts all of `src/parser.rs` away from panics to using
`Diagnostic` instead. Along the way this adds a test case per changed `panic!`,
ensuring that we don't regress in these areas!
This commit is contained in:
Alex Crichton
2018-08-01 18:59:59 -05:00
committed by GitHub
parent d90802a40c
commit bdec2582aa
14 changed files with 667 additions and 137 deletions

View File

@ -0,0 +1,23 @@
#![feature(use_extern_macros)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen(x)]
pub fn foo() {}
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(y)]
fn bar();
#[wasm_bindgen z]
fn bar();
#[wasm_bindgen(z2) x]
fn bar();
#[wasm_bindgen { }]
fn bar();
}

View File

@ -0,0 +1,32 @@
error: error parsing #[wasm_bindgen] attribute options: failed to parse anything
--> $DIR/invalid-attr.rs:7:16
|
7 | #[wasm_bindgen(x)]
| ^
error: error parsing #[wasm_bindgen] attribute options: failed to parse anything
--> $DIR/invalid-attr.rs:12:20
|
12 | #[wasm_bindgen(y)]
| ^
error: malformed #[wasm_bindgen] attribute
--> $DIR/invalid-attr.rs:15:5
|
15 | #[wasm_bindgen z]
| ^^^^^^^^^^^^^^^^^
error: malformed #[wasm_bindgen] attribute
--> $DIR/invalid-attr.rs:18:5
|
18 | #[wasm_bindgen(z2) x]
| ^^^^^^^^^^^^^^^^^^^^^
error: malformed #[wasm_bindgen] attribute
--> $DIR/invalid-attr.rs:21:5
|
21 | #[wasm_bindgen { }]
| ^^^^^^^^^^^^^^^^^^^^
error: aborting due to 5 previous errors

View File

@ -0,0 +1,23 @@
#![feature(use_extern_macros)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
enum A {}
#[wasm_bindgen]
pub enum B {
D(u32),
}
#[wasm_bindgen]
pub enum C {
X = 1 + 3,
}
#[wasm_bindgen]
pub enum D {
X = 4294967296,
}

View File

@ -0,0 +1,26 @@
error: only public enums are allowed with #[wasm_bindgen]
--> $DIR/invalid-enums.rs:8:1
|
8 | enum A {}
| ^^^^^^^^^
error: only C-Style enums allowed with #[wasm_bindgen]
--> $DIR/invalid-enums.rs:12:6
|
12 | D(u32),
| ^^^^^
error: enums with #[wasm_bidngen] may only have number literal values
--> $DIR/invalid-enums.rs:17:9
|
17 | X = 1 + 3,
| ^^^^^
error: enums with #[wasm_bindgen] can only support numbers that can be represented as u32
--> $DIR/invalid-enums.rs:22:9
|
22 | X = 4294967296,
| ^^^^^^^^^^
error: aborting due to 4 previous errors

View File

@ -0,0 +1,43 @@
#![feature(use_extern_macros)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
type A;
fn f() -> &'static u32;
#[wasm_bindgen(method)]
fn f1();
#[wasm_bindgen(method)]
fn f2(x: u32);
#[wasm_bindgen(method)]
fn f3(x: &&u32);
#[wasm_bindgen(method)]
fn f4(x: &foo::Bar);
#[wasm_bindgen(method)]
fn f4(x: &::Bar);
#[wasm_bindgen(method)]
fn f4(x: &Bar<T>);
#[wasm_bindgen(method)]
fn f4(x: &Fn(T));
#[wasm_bindgen(constructor)]
fn f();
#[wasm_bindgen(constructor)]
fn f() -> ::Bar;
#[wasm_bindgen(constructor)]
fn f() -> &Bar;
#[wasm_bindgen(catch)]
fn f() -> u32;
#[wasm_bindgen(catch)]
fn f() -> &u32;
#[wasm_bindgen(catch)]
fn f() -> Result<>;
#[wasm_bindgen(catch)]
fn f() -> Result<'a>;
}

View File

@ -0,0 +1,92 @@
error: it is currently not sound to use lifetimes in function signatures
--> $DIR/invalid-imports.rs:11:16
|
11 | fn f() -> &'static u32;
| ^^^^^^^
error: imported methods must have at least one argument
--> $DIR/invalid-imports.rs:14:5
|
14 | fn f1();
| ^^^^^^^^
error: first argument of method must be a shared reference
--> $DIR/invalid-imports.rs:16:14
|
16 | fn f2(x: u32);
| ^^^
error: first argument of method must be a path
--> $DIR/invalid-imports.rs:18:14
|
18 | fn f3(x: &&u32);
| ^^^^^
error: multi-segment paths are not supported yet
--> $DIR/invalid-imports.rs:20:15
|
20 | fn f4(x: &foo::Bar);
| ^^^^^^^^
error: global paths are not supported yet
--> $DIR/invalid-imports.rs:22:15
|
22 | fn f4(x: &::Bar);
| ^^^^^
error: paths with type parameters are not supported yet
--> $DIR/invalid-imports.rs:24:15
|
24 | fn f4(x: &Bar<T>);
| ^^^^^^
error: paths with type parameters are not supported yet
--> $DIR/invalid-imports.rs:26:15
|
26 | fn f4(x: &Fn(T));
| ^^^^^
error: constructor returns must be bare types
--> $DIR/invalid-imports.rs:29:5
|
29 | fn f();
| ^^^^^^^
error: global paths are not supported yet
--> $DIR/invalid-imports.rs:31:15
|
31 | fn f() -> ::Bar;
| ^^^^^
error: return value of constructor must be a bare path
--> $DIR/invalid-imports.rs:33:5
|
33 | fn f() -> &Bar;
| ^^^^^^^^^^^^^^^
error: must be Result<...>
--> $DIR/invalid-imports.rs:36:15
|
36 | fn f() -> u32;
| ^^^
error: must be Result<...>
--> $DIR/invalid-imports.rs:38:15
|
38 | fn f() -> &u32;
| ^^^^
error: must have at least one generic parameter
--> $DIR/invalid-imports.rs:40:15
|
40 | fn f() -> Result<>;
| ^^^^^^^^
error: it is currently not sound to use lifetimes in function signatures
--> $DIR/invalid-imports.rs:42:22
|
42 | fn f() -> Result<'a>;
| ^^
error: aborting due to 15 previous errors

View File

@ -0,0 +1,38 @@
#![feature(use_extern_macros)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
fn foo() {}
#[wasm_bindgen]
pub unsafe fn foo1() {}
#[wasm_bindgen]
pub const fn foo2() {}
#[wasm_bindgen]
struct Foo<T>(T);
#[wasm_bindgen]
extern "C" {
static mut FOO: u32;
pub fn foo3(x: i32, ...);
}
#[wasm_bindgen]
extern "system" {
}
#[wasm_bindgen]
pub fn foo4<T>() {}
#[wasm_bindgen]
pub fn foo5<'a>() {}
#[wasm_bindgen]
pub fn foo6<'a, T>() {}
#[wasm_bindgen]
trait X {}

View File

@ -0,0 +1,68 @@
error: can only #[wasm_bindgen] public functions
--> $DIR/invalid-items.rs:8:1
|
8 | fn foo() {}
| ^^^^^^^^^^^
error: can only #[wasm_bindgen] safe functions
--> $DIR/invalid-items.rs:11:5
|
11 | pub unsafe fn foo1() {}
| ^^^^^^
error: can only #[wasm_bindgen] non-const functions
--> $DIR/invalid-items.rs:14:5
|
14 | pub const fn foo2() {}
| ^^^^^
error: structs with #[wasm_bindgen] cannot have lifetime or type parameters currently
--> $DIR/invalid-items.rs:17:11
|
17 | struct Foo<T>(T);
| ^^^
error: cannot import mutable globals yet
--> $DIR/invalid-items.rs:21:12
|
21 | static mut FOO: u32;
| ^^^
error: can't #[wasm_bindgen] variadic functions
--> $DIR/invalid-items.rs:23:25
|
23 | pub fn foo3(x: i32, ...);
| ^^^
error: only foreign mods with the `C` ABI are allowed
--> $DIR/invalid-items.rs:27:8
|
27 | extern "system" {
| ^^^^^^^^
error: can't #[wasm_bindgen] functions with lifetime or type parameters
--> $DIR/invalid-items.rs:31:12
|
31 | pub fn foo4<T>() {}
| ^^^
error: can't #[wasm_bindgen] functions with lifetime or type parameters
--> $DIR/invalid-items.rs:33:12
|
33 | pub fn foo5<'a>() {}
| ^^^^
error: can't #[wasm_bindgen] functions with lifetime or type parameters
--> $DIR/invalid-items.rs:35:12
|
35 | pub fn foo6<'a, T>() {}
| ^^^^^^^
error: #[wasm_bindgen] can only be applied to a function, struct, enum, impl, or extern block
--> $DIR/invalid-items.rs:38:1
|
38 | trait X {}
| ^^^^^^^^^^
error: aborting due to 11 previous errors

View File

@ -0,0 +1,43 @@
#![feature(use_extern_macros)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub struct A;
#[wasm_bindgen]
default impl A {
}
#[wasm_bindgen]
unsafe impl A {
}
#[wasm_bindgen]
impl Clone for A {
}
#[wasm_bindgen]
impl<T> A {
}
#[wasm_bindgen]
impl &'static A {
}
macro_rules! x { () => () }
#[wasm_bindgen]
impl A {
const X: u32 = 3;
type Y = u32;
x!();
// pub default fn foo() {} // TODO: compiler's pretty printer totally broken
pub const fn foo() {}
pub unsafe fn foo() {}
}

View File

@ -0,0 +1,62 @@
error: #[wasm_bindgen] default impls are not supported
--> $DIR/invalid-methods.rs:11:1
|
11 | default impl A {
| ^^^^^^^
error: #[wasm_bindgen] unsafe impls are not supported
--> $DIR/invalid-methods.rs:15:1
|
15 | unsafe impl A {
| ^^^^^^
error: #[wasm_bindgen] trait impls are not supported
--> $DIR/invalid-methods.rs:19:6
|
19 | impl Clone for A {
| ^^^^^
error: #[wasm_bindgen] generic impls aren't supported
--> $DIR/invalid-methods.rs:23:5
|
23 | impl<T> A {
| ^^^
error: unsupported self type in #[wasm_bindgen] impl
--> $DIR/invalid-methods.rs:27:6
|
27 | impl &'static A {
| ^^^^^^^^^^
error: const definitions aren't supported with #[wasm_bindgen]
--> $DIR/invalid-methods.rs:34:5
|
34 | const X: u32 = 3;
| ^^^^^^^^^^^^^^^^^
error: type definitions in impls aren't supported with #[wasm_bindgen]
--> $DIR/invalid-methods.rs:35:5
|
35 | type Y = u32;
| ^^^^^^^^^^^^^
error: macros in impls aren't supported
--> $DIR/invalid-methods.rs:36:5
|
36 | x!();
| ^^^^^
error: can only #[wasm_bindgen] non-const functions
--> $DIR/invalid-methods.rs:41:9
|
41 | pub const fn foo() {}
| ^^^^^
error: can only bindgen safe functions
--> $DIR/invalid-methods.rs:42:9
|
42 | pub unsafe fn foo() {}
| ^^^^^^
error: aborting due to 10 previous errors

View File

@ -1,10 +1,8 @@
error: custom attribute panicked
--> $DIR/non-public-function.rs:7:1
error: can only #[wasm_bindgen] public functions
--> $DIR/non-public-function.rs:8:1
|
7 | #[wasm_bindgen]
| ^^^^^^^^^^^^^^^
|
= help: message: can only bindgen public functions
8 | fn foo() {}
| ^^^^^^^^^^^
error: aborting due to previous error