From 12dd4a190866a94b1802b3b5d9b60055308e15bb Mon Sep 17 00:00:00 2001 From: ltdk Date: Sat, 22 Feb 2025 14:59:07 -0500 Subject: [PATCH 01/14] Stabilise c_str_module --- library/alloc/src/ffi/mod.rs | 2 +- library/core/src/ffi/mod.rs | 2 +- library/std/src/ffi/mod.rs | 2 +- library/std/src/lib.rs | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/ffi/mod.rs b/library/alloc/src/ffi/mod.rs index 695d7ad07cf76..05a2763a22596 100644 --- a/library/alloc/src/ffi/mod.rs +++ b/library/alloc/src/ffi/mod.rs @@ -87,5 +87,5 @@ pub use self::c_str::CString; #[stable(feature = "alloc_c_string", since = "1.64.0")] pub use self::c_str::{FromVecWithNulError, IntoStringError, NulError}; -#[unstable(feature = "c_str_module", issue = "112134")] +#[stable(feature = "c_str_module", since = "CURRENT_RUSTC_VERSION")] pub mod c_str; diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index 9bae5fd466a18..c9c73a25d899e 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -20,7 +20,7 @@ pub use self::c_str::FromBytesUntilNulError; pub use self::c_str::FromBytesWithNulError; use crate::fmt; -#[unstable(feature = "c_str_module", issue = "112134")] +#[stable(feature = "c_str_module", since = "CURRENT_RUSTC_VERSION")] pub mod c_str; #[unstable( diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs index 860ec3a6be16e..6e1ec72dbdb3e 100644 --- a/library/std/src/ffi/mod.rs +++ b/library/std/src/ffi/mod.rs @@ -161,7 +161,7 @@ #![stable(feature = "rust1", since = "1.0.0")] -#[unstable(feature = "c_str_module", issue = "112134")] +#[stable(feature = "c_str_module", since = "CURRENT_RUSTC_VERSION")] pub mod c_str; #[stable(feature = "core_c_void", since = "1.30.0")] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 0661b3d770e48..998bf32a6cef7 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -327,7 +327,6 @@ #![feature(array_chunks)] #![feature(bstr)] #![feature(bstr_internals)] -#![feature(c_str_module)] #![feature(char_internals)] #![feature(clone_to_uninit)] #![feature(core_intrinsics)] From 6be84b1f3863c93f87946a1efd86120966d703dc Mon Sep 17 00:00:00 2001 From: ltdk Date: Sat, 22 Feb 2025 15:10:03 -0500 Subject: [PATCH 02/14] Somehow these stability attributes were able to be omitted before? --- library/alloc/src/ffi/c_str.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index fd93045a5ac4d..87625193b02aa 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -821,6 +821,7 @@ impl From>> for CString { } } +#[stable(feature = "c_string_from_str", since = "1.85.0")] impl FromStr for CString { type Err = NulError; @@ -833,6 +834,7 @@ impl FromStr for CString { } } +#[stable(feature = "c_string_from_str", since = "1.85.0")] impl TryFrom for String { type Error = IntoStringError; From 781949d68b7393d35e02e7acca6a7d523af1cef8 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 27 Mar 2025 21:27:15 +0100 Subject: [PATCH 03/14] Use char::is_whitespace directly in str::trim* --- library/core/src/str/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 5cc08f8a71afb..4de5ce89b1338 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2115,7 +2115,7 @@ impl str { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "str_trim"] pub fn trim(&self) -> &str { - self.trim_matches(|c: char| c.is_whitespace()) + self.trim_matches(char::is_whitespace) } /// Returns a string slice with leading whitespace removed. @@ -2154,7 +2154,7 @@ impl str { #[stable(feature = "trim_direction", since = "1.30.0")] #[rustc_diagnostic_item = "str_trim_start"] pub fn trim_start(&self) -> &str { - self.trim_start_matches(|c: char| c.is_whitespace()) + self.trim_start_matches(char::is_whitespace) } /// Returns a string slice with trailing whitespace removed. @@ -2193,7 +2193,7 @@ impl str { #[stable(feature = "trim_direction", since = "1.30.0")] #[rustc_diagnostic_item = "str_trim_end"] pub fn trim_end(&self) -> &str { - self.trim_end_matches(|c: char| c.is_whitespace()) + self.trim_end_matches(char::is_whitespace) } /// Returns a string slice with leading whitespace removed. From 676e29ba7fa756f21f6072f6ca58985dd998e377 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Fri, 28 Mar 2025 22:17:31 +0000 Subject: [PATCH 04/14] fix docs for `Peekable::next_if{_eq}` --- library/core/src/iter/adapters/peekable.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/iter/adapters/peekable.rs b/library/core/src/iter/adapters/peekable.rs index cc12cd9c35601..a6522659620a0 100644 --- a/library/core/src/iter/adapters/peekable.rs +++ b/library/core/src/iter/adapters/peekable.rs @@ -271,7 +271,7 @@ impl Peekable { /// assert_eq!(iter.next_if(|&x| x == 0), Some(0)); /// // The next item returned is now 1, so `next_if` will return `None`. /// assert_eq!(iter.next_if(|&x| x == 0), None); - /// // `next_if` saves the value of the next item if it was not equal to `expected`. + /// // `next_if` retains the next item if the predicate evaluates to `false` for it. /// assert_eq!(iter.next(), Some(1)); /// ``` /// @@ -304,9 +304,9 @@ impl Peekable { /// let mut iter = (0..5).peekable(); /// // The first item of the iterator is 0; consume it. /// assert_eq!(iter.next_if_eq(&0), Some(0)); - /// // The next item returned is now 1, so `next_if` will return `None`. + /// // The next item returned is now 1, so `next_if_eq` will return `None`. /// assert_eq!(iter.next_if_eq(&0), None); - /// // `next_if_eq` saves the value of the next item if it was not equal to `expected`. + /// // `next_if_eq` retains the next item if it was not equal to `expected`. /// assert_eq!(iter.next(), Some(1)); /// ``` #[stable(feature = "peekable_next_if", since = "1.51.0")] From 35363245657ee53a3735f1cef0df9a45e9ed44b9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 23 Apr 2025 22:09:11 +0200 Subject: [PATCH 05/14] Fix detection of `main` function if there are expressions around it --- src/librustdoc/doctest/make.rs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index d5c965f7053e0..94e227b70e00c 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -407,15 +407,19 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result { is_extern_crate = check_item(&item, &mut info, crate_name); } - StmtKind::Expr(ref expr) if matches!(expr.kind, ast::ExprKind::Err(_)) => { - reset_error_count(&psess); - return Err(()); + StmtKind::Expr(ref expr) => { + if matches!(expr.kind, ast::ExprKind::Err(_)) { + reset_error_count(&psess); + return Err(()); + } + has_non_module_items = true; } StmtKind::MacCall(ref mac_call) if !info.has_main_fn => { let mut iter = mac_call.mac.args.tokens.iter(); @@ -437,7 +441,11 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result {} + // We do nothing in this case. Not marking it as `non_module_items` either. + StmtKind::Empty => {} + _ => { + has_non_module_items = true; + } } // Weirdly enough, the `Stmt` span doesn't include its attributes, so we need to @@ -462,6 +470,11 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result { From 81438c0b05f177ae7bc0d6511d1cc507652eb241 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 23 Apr 2025 22:09:35 +0200 Subject: [PATCH 06/14] Add regression ui test for #140162 and for #139651 --- .../doctest/test-main-alongside-exprs.rs | 22 +++++++++++++++++++ .../doctest/test-main-alongside-exprs.stdout | 6 +++++ 2 files changed, 28 insertions(+) create mode 100644 tests/rustdoc-ui/doctest/test-main-alongside-exprs.rs create mode 100644 tests/rustdoc-ui/doctest/test-main-alongside-exprs.stdout diff --git a/tests/rustdoc-ui/doctest/test-main-alongside-exprs.rs b/tests/rustdoc-ui/doctest/test-main-alongside-exprs.rs new file mode 100644 index 0000000000000..ee2299c0fd87e --- /dev/null +++ b/tests/rustdoc-ui/doctest/test-main-alongside-exprs.rs @@ -0,0 +1,22 @@ +// This test ensures that if there is an expression alongside a `main` +// function, it will not consider the entire code to be part of the `main` +// function and will generate its own function to wrap everything. +// +// This is a regression test for: +// * +// * +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass + +#![crate_name = "foo"] + +//! ``` +//! # if cfg!(miri) { return; } +//! use std::ops::Deref; +//! +//! fn main() { +//! println!("Hi!"); +//! } +//! ``` diff --git a/tests/rustdoc-ui/doctest/test-main-alongside-exprs.stdout b/tests/rustdoc-ui/doctest/test-main-alongside-exprs.stdout new file mode 100644 index 0000000000000..90d7c3546bf10 --- /dev/null +++ b/tests/rustdoc-ui/doctest/test-main-alongside-exprs.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/test-main-alongside-exprs.rs - (line 15) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + From 3ededc1053f752d993a0b25286faebfe3616819d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 25 Apr 2025 22:01:00 +0200 Subject: [PATCH 07/14] Improve code --- src/librustdoc/doctest/make.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index 94e227b70e00c..c46c6d71491a3 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -407,7 +407,7 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result) -> Result { let mut iter = mac_call.mac.args.tokens.iter(); @@ -444,7 +447,7 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result {} _ => { - has_non_module_items = true; + has_non_items = true; } } @@ -470,7 +473,7 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result Date: Fri, 25 Apr 2025 22:04:50 +0200 Subject: [PATCH 08/14] If there is a `;` alone, we consider that the doctest needs to be put inside a function --- src/librustdoc/doctest/make.rs | 2 -- .../failed-doctest-extra-semicolon-on-item.rs | 4 +-- ...led-doctest-extra-semicolon-on-item.stdout | 27 ++----------------- 3 files changed, 4 insertions(+), 29 deletions(-) diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index c46c6d71491a3..e41a06aff3036 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -444,8 +444,6 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result {} _ => { has_non_items = true; } diff --git a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs index 508faadcf6729..ca5dd78746789 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs @@ -4,12 +4,12 @@ //@ compile-flags:--test //@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" -//@ failure-status: 101 +//@ check-pass /// /// /// ```rust -/// struct S {}; // unexpected semicolon after struct def +/// struct S {}; /// /// fn main() { /// assert_eq!(0, 1); diff --git a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stdout b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stdout index 9eb8b391e7809..1068b98cb0fbb 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stdout +++ b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stdout @@ -1,29 +1,6 @@ running 1 test -test $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) ... FAILED +test $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) ... ok -failures: - ----- $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) stdout ---- -error: expected item, found `;` - --> $DIR/failed-doctest-extra-semicolon-on-item.rs:12:12 - | -LL | struct S {}; // unexpected semicolon after struct def - | ^ - | - = help: braced struct declarations are not followed by a semicolon -help: remove this semicolon - | -LL - struct S {}; // unexpected semicolon after struct def -LL + struct S {} // unexpected semicolon after struct def - | - -error: aborting due to 1 previous error - -Couldn't compile the test. - -failures: - $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) - -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME From 43d8d89b9ef6ce10d3310fdb56fb850dc8b42c91 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Sat, 26 Apr 2025 13:48:22 +0500 Subject: [PATCH 09/14] clarified bootstrap optimization agrs --- bootstrap.example.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap.example.toml b/bootstrap.example.toml index 72c4492d465d8..72fd56fb5bd71 100644 --- a/bootstrap.example.toml +++ b/bootstrap.example.toml @@ -500,7 +500,7 @@ # building without optimizations takes much longer than optimizing. Further, some platforms # fail to build without this optimization (c.f. #65352). # The valid options are: -# true - Enable optimizations. +# true - Enable optimizations (same as 3). # false - Disable optimizations. # 0 - Disable optimizations. # 1 - Basic optimizations. From 86969dbe773b6e3f05ab34e9a2f8ba08441ebf88 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 26 Apr 2025 18:42:15 +0300 Subject: [PATCH 10/14] session: Cleanup `CanonicalizedPath::new` It wants an owned path, so pass an owned path --- compiler/rustc_interface/src/tests.rs | 8 ++++---- compiler/rustc_session/src/config.rs | 3 +-- compiler/rustc_session/src/utils.rs | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 5c8c51c8bbcc2..0ceda2201344e 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -1,7 +1,7 @@ #![allow(rustc::bad_opt_access)] -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeMap; use std::num::NonZero; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::sync::atomic::AtomicBool; use rustc_abi::Align; @@ -89,8 +89,8 @@ where S: Into, I: IntoIterator, { - let locations: BTreeSet = - locations.into_iter().map(|s| CanonicalizedPath::new(Path::new(&s.into()))).collect(); + let locations = + locations.into_iter().map(|s| CanonicalizedPath::new(PathBuf::from(s.into()))).collect(); ExternEntry { location: ExternLocation::ExactPaths(locations), diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 43955cc23a9e9..e2d36f6a4e2ff 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2323,14 +2323,13 @@ pub fn parse_externs( let ExternOpt { crate_name: name, path, options } = split_extern_opt(early_dcx, unstable_opts, &arg).unwrap_or_else(|e| e.emit()); - let path = path.map(|p| CanonicalizedPath::new(p.as_path())); - let entry = externs.entry(name.to_owned()); use std::collections::btree_map::Entry; let entry = if let Some(path) = path { // --extern prelude_name=some_file.rlib + let path = CanonicalizedPath::new(path); match entry { Entry::Vacant(vacant) => { let files = BTreeSet::from_iter(iter::once(path)); diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs index 2243e831b66ec..e9ddd66b5e8b3 100644 --- a/compiler/rustc_session/src/utils.rs +++ b/compiler/rustc_session/src/utils.rs @@ -1,4 +1,4 @@ -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::sync::OnceLock; use rustc_data_structures::profiling::VerboseTimingGuard; @@ -104,8 +104,8 @@ pub struct CanonicalizedPath { } impl CanonicalizedPath { - pub fn new(path: &Path) -> Self { - Self { original: path.to_owned(), canonicalized: try_canonicalize(path).ok() } + pub fn new(path: PathBuf) -> Self { + Self { canonicalized: try_canonicalize(&path).ok(), original: path } } pub fn canonicalized(&self) -> &PathBuf { From 9112c86f4226a6922f07bb44b49cedb75d1ee2f9 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Fri, 25 Apr 2025 11:27:01 -0400 Subject: [PATCH 11/14] Update example to use `CStr::to_string_lossy` --- library/core/src/ffi/c_str.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 85e87445a1b43..ac07c645c0195 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -79,8 +79,9 @@ use crate::{fmt, ops, slice, str}; /// /// fn my_string_safe() -> String { /// let cstr = unsafe { CStr::from_ptr(my_string()) }; -/// // Get copy-on-write Cow<'_, str>, then guarantee a freshly-owned String allocation -/// String::from_utf8_lossy(cstr.to_bytes()).to_string() +/// // Get a copy-on-write Cow<'_, str>, then extract the +/// // allocated String (or allocate a fresh one if needed). +/// cstr.to_string_lossy().into_owned() /// } /// /// println!("string: {}", my_string_safe()); From 8608a3f637871c157b030f5661231f8261ca9797 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 26 Apr 2025 14:08:36 -0700 Subject: [PATCH 12/14] lint-docs: Don't hard-code the valid editions This removes the hard-coded list of edition support in the lint-docs tool, and instead just assumes the edition attribute is something valid. There isn't a real reason to have this, as rustc will error if given a wrong number. This should be easier to maintain going forward. --- src/tools/lint-docs/src/lib.rs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs index 9fd33e23204e7..7e00697a0bdfb 100644 --- a/src/tools/lint-docs/src/lib.rs +++ b/src/tools/lint-docs/src/lib.rs @@ -444,21 +444,15 @@ impl<'a> LintExtractor<'a> { fs::write(&tempfile, source) .map_err(|e| format!("failed to write {}: {}", tempfile.display(), e))?; let mut cmd = Command::new(self.rustc_path); - if options.contains(&"edition2024") { - cmd.arg("--edition=2024"); - cmd.arg("-Zunstable-options"); - } else if options.contains(&"edition2021") { - cmd.arg("--edition=2021"); - } else if options.contains(&"edition2018") { - cmd.arg("--edition=2018"); - } else if options.contains(&"edition2015") { - cmd.arg("--edition=2015"); - } else if options.contains(&"edition") { - panic!("lint-docs: unknown edition"); - } else { + let edition = options + .iter() + .filter_map(|opt| opt.strip_prefix("edition")) + .next() // defaults to latest edition - cmd.arg("--edition=2021"); - } + .unwrap_or("2021"); + cmd.arg(format!("--edition={edition}")); + // Just in case this is an unstable edition. + cmd.arg("-Zunstable-options"); cmd.arg("--error-format=json"); cmd.arg("--target").arg(self.rustc_target); if let Some(target_linker) = self.rustc_linker { From 1f108fe08a906b49026cd0aa324b3f9381c052c1 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 26 Apr 2025 14:08:58 -0700 Subject: [PATCH 13/14] Update lint-docs to default to Rust 2024 This updates the lint-docs tool to default to the 2024 edition. The lint docs are supposed to illustrate the code with the latest edition, and I just forgot to update this in https://github.com/rust-lang/rust/pull/133349. Some docs needed to add the `edition` attribute since they were assuming a particular edition, but were missing the explicit annotation. --- compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_lint/src/impl_trait_overcaptures.rs | 2 +- compiler/rustc_lint_defs/src/builtin.rs | 4 ++-- src/tools/lint-docs/src/lib.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index e65f4beab2411..41b43f6479867 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -948,7 +948,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust,compile_fail + /// ```rust,compile_fail,edition2021 /// #[no_mangle] /// const FOO: i32 = 5; /// ``` diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index f1dc420aa3c92..7f4789ad0d9b8 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -41,7 +41,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust,compile_fail + /// ```rust,compile_fail,edition2021 /// # #![deny(impl_trait_overcaptures)] /// # use std::fmt::Display; /// let mut x = vec![]; diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 17d501c5730b8..03b8112938cff 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1424,7 +1424,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust,compile_fail + /// ```rust,compile_fail,edition2021 /// macro_rules! foo { /// () => {}; /// ($name) => { }; @@ -4128,7 +4128,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust,compile_fail + /// ```rust,compile_fail,edition2021 /// #![deny(dependency_on_unit_never_type_fallback)] /// fn main() { /// if true { diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs index 7e00697a0bdfb..d6c69d39e17ff 100644 --- a/src/tools/lint-docs/src/lib.rs +++ b/src/tools/lint-docs/src/lib.rs @@ -449,7 +449,7 @@ impl<'a> LintExtractor<'a> { .filter_map(|opt| opt.strip_prefix("edition")) .next() // defaults to latest edition - .unwrap_or("2021"); + .unwrap_or("2024"); cmd.arg(format!("--edition={edition}")); // Just in case this is an unstable edition. cmd.arg("-Zunstable-options"); From aa69e3a0cb8f1b2e086709a038baad6f39249150 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 27 Apr 2025 00:12:32 +0200 Subject: [PATCH 14/14] Fix bad handling of macros if there is already a `main` function --- src/librustdoc/doctest/make.rs | 5 ++++- .../doctest/auxiliary/macro-after-main.rs | 1 + tests/rustdoc-ui/doctest/macro-after-main.rs | 16 ++++++++++++++++ tests/rustdoc-ui/doctest/macro-after-main.stdout | 6 ++++++ 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 tests/rustdoc-ui/doctest/auxiliary/macro-after-main.rs create mode 100644 tests/rustdoc-ui/doctest/macro-after-main.rs create mode 100644 tests/rustdoc-ui/doctest/macro-after-main.stdout diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index e41a06aff3036..4194abc8d5742 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -424,7 +424,10 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result { + StmtKind::MacCall(ref mac_call) => { + if info.has_main_fn { + continue; + } let mut iter = mac_call.mac.args.tokens.iter(); while let Some(token) = iter.next() { diff --git a/tests/rustdoc-ui/doctest/auxiliary/macro-after-main.rs b/tests/rustdoc-ui/doctest/auxiliary/macro-after-main.rs new file mode 100644 index 0000000000000..ed7584b742533 --- /dev/null +++ b/tests/rustdoc-ui/doctest/auxiliary/macro-after-main.rs @@ -0,0 +1 @@ +use std::string::String; diff --git a/tests/rustdoc-ui/doctest/macro-after-main.rs b/tests/rustdoc-ui/doctest/macro-after-main.rs new file mode 100644 index 0000000000000..0a42343f1c272 --- /dev/null +++ b/tests/rustdoc-ui/doctest/macro-after-main.rs @@ -0,0 +1,16 @@ +// This test checks a corner case where the macro calls used to be skipped, +// making them considered as statement, and therefore some cases where +// `include!` macro was then put into a function body, making the doctest +// compilation fail. + +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass + +//! ``` +//! include!("./auxiliary/macro-after-main.rs"); +//! +//! fn main() {} +//! eprintln!(); +//! ``` diff --git a/tests/rustdoc-ui/doctest/macro-after-main.stdout b/tests/rustdoc-ui/doctest/macro-after-main.stdout new file mode 100644 index 0000000000000..72ffe2b5a27c5 --- /dev/null +++ b/tests/rustdoc-ui/doctest/macro-after-main.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/macro-after-main.rs - (line 11) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME +