diff options
| author | Kivooeo <Kivooeo123@gmail.com> | 2025-05-06 15:06:45 +0500 |
|---|---|---|
| committer | Kivooeo <Kivooeo123@gmail.com> | 2025-05-06 23:02:47 +0500 |
| commit | 3c1c0726ad18dc07f3ef9b9465d5997ca13e332c (patch) | |
| tree | 26a7975d1de350e6328ad3e05f73c2fbd1d250a0 /tests/ui/explain | |
| parent | 651e9cf327358b28db7e37a2ae61727f4a2ef232 (diff) | |
| download | rust-3c1c0726ad18dc07f3ef9b9465d5997ca13e332c.tar.gz rust-3c1c0726ad18dc07f3ef9b9465d5997ca13e332c.zip | |
added error handle for error code > 9999
Diffstat (limited to 'tests/ui/explain')
| -rw-r--r-- | tests/ui/explain/basic.rs | 2 | ||||
| -rw-r--r-- | tests/ui/explain/basic.stdout | 71 | ||||
| -rw-r--r-- | tests/ui/explain/error-with-no-explanation.rs | 3 | ||||
| -rw-r--r-- | tests/ui/explain/error-with-no-explanation.stderr | 2 | ||||
| -rw-r--r-- | tests/ui/explain/invalid-error-code.rs | 2 | ||||
| -rw-r--r-- | tests/ui/explain/invalid-error-code.stderr | 2 | ||||
| -rw-r--r-- | tests/ui/explain/no-E-prefix.rs | 2 | ||||
| -rw-r--r-- | tests/ui/explain/no-E-prefix.stdout | 57 | ||||
| -rw-r--r-- | tests/ui/explain/overflow-error-code.rs | 4 | ||||
| -rw-r--r-- | tests/ui/explain/overflow-error-code.stderr | 2 |
10 files changed, 147 insertions, 0 deletions
diff --git a/tests/ui/explain/basic.rs b/tests/ui/explain/basic.rs new file mode 100644 index 00000000000..1206c4f95eb --- /dev/null +++ b/tests/ui/explain/basic.rs @@ -0,0 +1,2 @@ +//@ compile-flags: --explain E0591 +//@ check-pass diff --git a/tests/ui/explain/basic.stdout b/tests/ui/explain/basic.stdout new file mode 100644 index 00000000000..ef1d866c3ff --- /dev/null +++ b/tests/ui/explain/basic.stdout @@ -0,0 +1,71 @@ +Per [RFC 401][rfc401], if you have a function declaration `foo`: + +``` +struct S; + +// For the purposes of this explanation, all of these +// different kinds of `fn` declarations are equivalent: + +fn foo(x: S) { /* ... */ } +extern "C" { + fn foo(x: S); +} +impl S { + fn foo(self) { /* ... */ } +} +``` + +the type of `foo` is **not** `fn(S)`, as one might expect. +Rather, it is a unique, zero-sized marker type written here as `typeof(foo)`. +However, `typeof(foo)` can be _coerced_ to a function pointer `fn(S)`, +so you rarely notice this: + +``` +let x: fn(S) = foo; // OK, coerces +``` + +The reason that this matter is that the type `fn(S)` is not specific to +any particular function: it's a function _pointer_. So calling `x()` results +in a virtual call, whereas `foo()` is statically dispatched, because the type +of `foo` tells us precisely what function is being called. + +As noted above, coercions mean that most code doesn't have to be +concerned with this distinction. However, you can tell the difference +when using **transmute** to convert a fn item into a fn pointer. + +This is sometimes done as part of an FFI: + +``` +extern "C" fn foo(userdata: Box<i32>) { + /* ... */ +} + +unsafe { + let f: extern "C" fn(*mut i32) = transmute(foo); + callback(f); +} +``` + +Here, transmute is being used to convert the types of the fn arguments. +This pattern is incorrect because the type of `foo` is a function **item** +(`typeof(foo)`), which is zero-sized, and the target type (`fn()`) +is a function pointer, which is not zero-sized. +This pattern should be rewritten. There are a few possible ways to do this: + +- change the original fn declaration to match the expected signature, + and do the cast in the fn body (the preferred option) +- cast the fn item of a fn pointer before calling transmute, as shown here: + + ``` + let f: extern "C" fn(*mut i32) = transmute(foo as extern "C" fn(_)); + let f: extern "C" fn(*mut i32) = transmute(foo as usize); // works too + ``` + +The same applies to transmutes to `*mut fn()`, which were observed in practice. +Note though that use of this type is generally incorrect. +The intention is typically to describe a function pointer, but just `fn()` +alone suffices for that. `*mut fn()` is a pointer to a fn pointer. +(Since these values are typically just passed to C code, however, this rarely +makes a difference in practice.) + +[rfc401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md diff --git a/tests/ui/explain/error-with-no-explanation.rs b/tests/ui/explain/error-with-no-explanation.rs new file mode 100644 index 00000000000..383820eb458 --- /dev/null +++ b/tests/ui/explain/error-with-no-explanation.rs @@ -0,0 +1,3 @@ +// It's a valid error with no added explanation +//@ compile-flags: --explain E9999 +//~? ERROR: E9999 is not a valid error code diff --git a/tests/ui/explain/error-with-no-explanation.stderr b/tests/ui/explain/error-with-no-explanation.stderr new file mode 100644 index 00000000000..afb738cfecb --- /dev/null +++ b/tests/ui/explain/error-with-no-explanation.stderr @@ -0,0 +1,2 @@ +error: E9999 is not a valid error code + diff --git a/tests/ui/explain/invalid-error-code.rs b/tests/ui/explain/invalid-error-code.rs new file mode 100644 index 00000000000..114118d5196 --- /dev/null +++ b/tests/ui/explain/invalid-error-code.rs @@ -0,0 +1,2 @@ +//@ compile-flags: --explain error_code +//~? ERROR: error_code is not a valid error code diff --git a/tests/ui/explain/invalid-error-code.stderr b/tests/ui/explain/invalid-error-code.stderr new file mode 100644 index 00000000000..c33122ea88c --- /dev/null +++ b/tests/ui/explain/invalid-error-code.stderr @@ -0,0 +1,2 @@ +error: error_code is not a valid error code + diff --git a/tests/ui/explain/no-E-prefix.rs b/tests/ui/explain/no-E-prefix.rs new file mode 100644 index 00000000000..39c9122bfe1 --- /dev/null +++ b/tests/ui/explain/no-E-prefix.rs @@ -0,0 +1,2 @@ +//@ compile-flags: --explain 425 +//@ check-pass diff --git a/tests/ui/explain/no-E-prefix.stdout b/tests/ui/explain/no-E-prefix.stdout new file mode 100644 index 00000000000..756b970aa7e --- /dev/null +++ b/tests/ui/explain/no-E-prefix.stdout @@ -0,0 +1,57 @@ +An unresolved name was used. + +Erroneous code examples: + +``` +something_that_doesnt_exist::foo; +// error: unresolved name `something_that_doesnt_exist::foo` + +// or: + +trait Foo { + fn bar() { + Self; // error: unresolved name `Self` + } +} + +// or: + +let x = unknown_variable; // error: unresolved name `unknown_variable` +``` + +Please verify that the name wasn't misspelled and ensure that the +identifier being referred to is valid for the given situation. Example: + +``` +enum something_that_does_exist { + Foo, +} +``` + +Or: + +``` +mod something_that_does_exist { + pub static foo : i32 = 0i32; +} + +something_that_does_exist::foo; // ok! +``` + +Or: + +``` +let unknown_variable = 12u32; +let x = unknown_variable; // ok! +``` + +If the item is not defined in the current module, it must be imported using a +`use` statement, like so: + +``` +use foo::bar; +bar(); +``` + +If the item you are importing is not defined in some super-module of the +current module, then it must also be declared as public (e.g., `pub fn`). diff --git a/tests/ui/explain/overflow-error-code.rs b/tests/ui/explain/overflow-error-code.rs new file mode 100644 index 00000000000..284d5cddb35 --- /dev/null +++ b/tests/ui/explain/overflow-error-code.rs @@ -0,0 +1,4 @@ +// Check that we don't crash on error codes exceeding our internal limit. +// issue: <https://github.com/rust-lang/rust/issues/140647> +//@ compile-flags: --explain E10000 +//~? ERROR: E10000 is not a valid error code diff --git a/tests/ui/explain/overflow-error-code.stderr b/tests/ui/explain/overflow-error-code.stderr new file mode 100644 index 00000000000..67e584ea32e --- /dev/null +++ b/tests/ui/explain/overflow-error-code.stderr @@ -0,0 +1,2 @@ +error: E10000 is not a valid error code + |
