diff --git a/compiler/rustc_error_codes/src/error_codes/E0015.md b/compiler/rustc_error_codes/src/error_codes/E0015.md index 021a0219d13e2..ac78f66adada0 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0015.md +++ b/compiler/rustc_error_codes/src/error_codes/E0015.md @@ -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: @@ -8,26 +7,20 @@ fn create_some() -> Option { Some(1) } -const FOO: Option = create_some(); // error! +// error: cannot call non-const fn `create_some` in constants +const FOO: Option = 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 { // declared as a const function +// declared as a `const` function: +const fn create_some() -> Option { Some(1) } -const FOO: Option = create_some(); // ok! - -// These are also working: -struct Bar { - x: u8, -} - -const OTHER_FOO: Option = Some(1); -const BAR: Bar = Bar {x: 1}; +const FOO: Option = create_some(); // no error! ``` diff --git a/src/test/ui/error-codes/E0013.rs b/src/test/ui/error-codes/E0013.rs new file mode 100644 index 0000000000000..9b3982a785b7f --- /dev/null +++ b/src/test/ui/error-codes/E0013.rs @@ -0,0 +1,4 @@ +static X: i32 = 42; +const Y: i32 = X; //~ ERROR constants cannot refer to statics [E0013] + +fn main() {} diff --git a/src/test/ui/error-codes/E0013.stderr b/src/test/ui/error-codes/E0013.stderr new file mode 100644 index 0000000000000..dc22053a63895 --- /dev/null +++ b/src/test/ui/error-codes/E0013.stderr @@ -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`. diff --git a/src/test/ui/error-codes/E0015.rs b/src/test/ui/error-codes/E0015.rs new file mode 100644 index 0000000000000..b0211358d8166 --- /dev/null +++ b/src/test/ui/error-codes/E0015.rs @@ -0,0 +1,8 @@ +fn create_some() -> Option { + Some(1) +} + +const FOO: Option = create_some(); +//~^ ERROR cannot call non-const fn `create_some` in constants [E0015] + +fn main() {} diff --git a/src/test/ui/error-codes/E0015.stderr b/src/test/ui/error-codes/E0015.stderr new file mode 100644 index 0000000000000..ec1ce47b2ce78 --- /dev/null +++ b/src/test/ui/error-codes/E0015.stderr @@ -0,0 +1,11 @@ +error[E0015]: cannot call non-const fn `create_some` in constants + --> $DIR/E0015.rs:5:25 + | +LL | const FOO: Option = 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`. diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index fdc9d78990590..4b0a62fac839e 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -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}; @@ -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); @@ -174,8 +172,9 @@ 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, @@ -183,13 +182,11 @@ fn check_error_codes_docs( `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, @@ -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(); @@ -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 @@ -261,6 +258,7 @@ fn check_error_codes_tests( error_codes: &[String], errors: &mut Vec, verbose: bool, + no_longer_emitted: &[String], ) { let tests_path = root_path.join(Path::new(ERROR_TESTS_PATH)); @@ -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() {