Skip to content

Commit

Permalink
Rollup merge of rust-lang#106557 - Ezrashaw:ui-test-fixups-1, r=Guill…
Browse files Browse the repository at this point in the history
…aumeGomez

Add some UI tests and reword error-code docs

Added UI tests for `E0013` and `E0015`. Error code docs for `E0015` were a bit unclear (they referred to all non-const errors in const context, when only non-const functions applied), so I touched them up a bit.

I also fixed up some issues in the new `error_codes.rs` tidy check (linked rust-lang#106341), that I overlooked previously.

r? ``@GuillaumeGomez``
  • Loading branch information
Yuki Okushi committed Jan 8, 2023
2 parents 7997ff6 + ae61c25 commit 3b5afa5
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 27 deletions.
23 changes: 8 additions & 15 deletions compiler/rustc_error_codes/src/error_codes/E0015.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
A constant item was initialized with something that is not a constant
expression.
A non-`const` function was called in a `const` context.

Erroneous code example:

Expand All @@ -8,26 +7,20 @@ fn create_some() -> Option<u8> {
Some(1)
}
const FOO: Option<u8> = create_some(); // error!
// error: cannot call non-const fn `create_some` in constants
const FOO: Option<u8> = create_some();
```

The only functions that can be called in static or constant expressions are
`const` functions, and struct/enum constructors.
All functions used in a `const` context (constant or static expression) must
be marked `const`.

To fix this error, you can declare `create_some` as a constant function:

```
const fn create_some() -> Option<u8> { // declared as a const function
// declared as a `const` function:
const fn create_some() -> Option<u8> {
Some(1)
}
const FOO: Option<u8> = create_some(); // ok!
// These are also working:
struct Bar {
x: u8,
}
const OTHER_FOO: Option<u8> = Some(1);
const BAR: Bar = Bar {x: 1};
const FOO: Option<u8> = create_some(); // no error!
```
4 changes: 4 additions & 0 deletions src/test/ui/error-codes/E0013.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
static X: i32 = 42;
const Y: i32 = X; //~ ERROR constants cannot refer to statics [E0013]

fn main() {}
11 changes: 11 additions & 0 deletions src/test/ui/error-codes/E0013.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0013]: constants cannot refer to statics
--> $DIR/E0013.rs:2:16
|
LL | const Y: i32 = X;
| ^
|
= help: consider extracting the value of the `static` to a `const`, and referring to that

error: aborting due to previous error

For more information about this error, try `rustc --explain E0013`.
8 changes: 8 additions & 0 deletions src/test/ui/error-codes/E0015.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fn create_some() -> Option<u8> {
Some(1)
}

const FOO: Option<u8> = create_some();
//~^ ERROR cannot call non-const fn `create_some` in constants [E0015]

fn main() {}
11 changes: 11 additions & 0 deletions src/test/ui/error-codes/E0015.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0015]: cannot call non-const fn `create_some` in constants
--> $DIR/E0015.rs:5:25
|
LL | const FOO: Option<u8> = create_some();
| ^^^^^^^^^^^^^
|
= note: calls in constants are limited to constant functions, tuple structs and tuple variants

error: aborting due to previous error

For more information about this error, try `rustc --explain E0015`.
27 changes: 15 additions & 12 deletions src/tools/tidy/src/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
//!
//! 4. We check that the error code is actually emitted by the compiler.
//! - This is done by searching `compiler/` with a regex.
//!
//! This tidy check was merged and refactored from two others. See #PR_NUM for information about linting changes that occurred during this refactor.

use std::{ffi::OsStr, fs, path::Path};

Expand Down Expand Up @@ -57,7 +55,7 @@ pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut
let no_longer_emitted = check_error_codes_docs(root_path, &error_codes, &mut errors, verbose);

// Stage 3: check list has UI tests
check_error_codes_tests(root_path, &error_codes, &mut errors, verbose);
check_error_codes_tests(root_path, &error_codes, &mut errors, verbose, &no_longer_emitted);

// Stage 4: check list is emitted by compiler
check_error_codes_used(search_paths, &error_codes, &mut errors, &no_longer_emitted, verbose);
Expand Down Expand Up @@ -174,22 +172,21 @@ fn check_error_codes_docs(
return;
}

let (found_code_example, found_proper_doctest, emit_ignore_warning, emit_no_longer_warning) =
let (found_code_example, found_proper_doctest, emit_ignore_warning, no_longer_emitted) =
check_explanation_has_doctest(&contents, &err_code);

if emit_ignore_warning {
verbose_print!(
verbose,
"warning: Error code `{err_code}` uses the ignore header. This should not be used, add the error code to the \
`IGNORE_DOCTEST_CHECK` constant instead."
);
}
if emit_no_longer_warning {

if no_longer_emitted {
no_longer_emitted_codes.push(err_code.to_owned());
verbose_print!(
verbose,
"warning: Error code `{err_code}` is no longer emitted and should be removed entirely."
);
}

if !found_code_example {
verbose_print!(
verbose,
Expand Down Expand Up @@ -226,7 +223,7 @@ fn check_explanation_has_doctest(explanation: &str, err_code: &str) -> (bool, bo
let mut found_proper_doctest = false;

let mut emit_ignore_warning = false;
let mut emit_no_longer_warning = false;
let mut no_longer_emitted = false;

for line in explanation.lines() {
let line = line.trim();
Expand All @@ -246,13 +243,13 @@ fn check_explanation_has_doctest(explanation: &str, err_code: &str) -> (bool, bo
} else if line
.starts_with("#### Note: this error code is no longer emitted by the compiler")
{
emit_no_longer_warning = true;
no_longer_emitted = true;
found_code_example = true;
found_proper_doctest = true;
}
}

(found_code_example, found_proper_doctest, emit_ignore_warning, emit_no_longer_warning)
(found_code_example, found_proper_doctest, emit_ignore_warning, no_longer_emitted)
}

// Stage 3: Checks that each error code has a UI test in the correct directory
Expand All @@ -261,6 +258,7 @@ fn check_error_codes_tests(
error_codes: &[String],
errors: &mut Vec<String>,
verbose: bool,
no_longer_emitted: &[String],
) {
let tests_path = root_path.join(Path::new(ERROR_TESTS_PATH));

Expand Down Expand Up @@ -295,6 +293,11 @@ fn check_error_codes_tests(
}
};

if no_longer_emitted.contains(code) {
// UI tests *can't* contain error codes that are no longer emitted.
continue;
}

let mut found_code = false;

for line in file.lines() {
Expand Down

0 comments on commit 3b5afa5

Please sign in to comment.