Auto merge of #128301 - matthiaskrgr:rollup-9fyf587, r=matthiaskrgr
Rollup of 3 pull requests Successful merges: - #125889 (Add migration lint for 2024 prelude additions) - #128215 (Update the reference) - #128263 (rustdoc: use strategic ThinVec/Box to shrink `clean::ItemKind`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
78c857394e
46 changed files with 774 additions and 184 deletions
|
|
@ -9,7 +9,7 @@ use rustc_hir as hir;
|
|||
use rustc_lint::{ARRAY_INTO_ITER, BOXED_SLICE_INTO_ITER};
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
|
||||
use rustc_session::lint::builtin::{RUST_2021_PRELUDE_COLLISIONS, RUST_2024_PRELUDE_COLLISIONS};
|
||||
use rustc_span::symbol::kw::{Empty, Underscore};
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::Span;
|
||||
|
|
@ -35,6 +35,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let (prelude_or_array_lint, edition) = match segment.ident.name {
|
||||
// `try_into` was added to the prelude in Rust 2021.
|
||||
sym::try_into if !span.at_least_rust_2021() => (RUST_2021_PRELUDE_COLLISIONS, "2021"),
|
||||
// `Future::poll` was added to the prelude in Rust 2024.
|
||||
sym::poll
|
||||
// We check that the self type is `Pin<&mut _>` to avoid false positives for this common name.
|
||||
if !span.at_least_rust_2024()
|
||||
&& let ty::Adt(adt_def, args) = self_ty.kind()
|
||||
&& self.tcx.is_lang_item(adt_def.did(), hir::LangItem::Pin)
|
||||
&& let ty::Ref(_, _, ty::Mutability::Mut) =
|
||||
args[0].as_type().unwrap().kind() =>
|
||||
{
|
||||
(RUST_2024_PRELUDE_COLLISIONS, "2024")
|
||||
}
|
||||
// `IntoFuture::into_future` was added to the prelude in Rust 2024.
|
||||
sym::into_future if !span.at_least_rust_2024() => {
|
||||
(RUST_2024_PRELUDE_COLLISIONS, "2024")
|
||||
}
|
||||
// `into_iter` wasn't added to the prelude,
|
||||
// but `[T; N].into_iter()` doesn't resolve to IntoIterator::into_iter
|
||||
// before Rust 2021, which results in the same problem.
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ declare_lint_pass! {
|
|||
RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX,
|
||||
RUST_2021_PRELUDE_COLLISIONS,
|
||||
RUST_2024_INCOMPATIBLE_PAT,
|
||||
RUST_2024_PRELUDE_COLLISIONS,
|
||||
SELF_CONSTRUCTOR_FROM_OUTER_ITEM,
|
||||
SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
|
||||
SINGLE_USE_LIFETIMES,
|
||||
|
|
@ -3754,6 +3755,46 @@ declare_lint! {
|
|||
};
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
/// The `rust_2024_prelude_collisions` lint detects the usage of trait methods which are ambiguous
|
||||
/// with traits added to the prelude in future editions.
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust,edition2021,compile_fail
|
||||
/// #![deny(rust_2024_prelude_collisions)]
|
||||
/// trait Meow {
|
||||
/// fn poll(&self) {}
|
||||
/// }
|
||||
/// impl<T> Meow for T {}
|
||||
///
|
||||
/// fn main() {
|
||||
/// core::pin::pin!(async {}).poll();
|
||||
/// // ^^^^^^
|
||||
/// // This call to try_into matches both Future::poll and Meow::poll as
|
||||
/// // `Future` has been added to the Rust prelude in 2024 edition.
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// {{produces}}
|
||||
///
|
||||
/// ### Explanation
|
||||
///
|
||||
/// Rust 2024, introduces two new additions to the standard library's prelude:
|
||||
/// `Future` and `IntoFuture`. This results in an ambiguity as to which method/function
|
||||
/// to call when an existing `poll`/`into_future` method is called via dot-call syntax or
|
||||
/// a `poll`/`into_future` associated function is called directly on a type.
|
||||
///
|
||||
pub RUST_2024_PRELUDE_COLLISIONS,
|
||||
Allow,
|
||||
"detects the usage of trait methods which are ambiguous with traits added to the \
|
||||
prelude in future editions",
|
||||
@future_incompatible = FutureIncompatibleInfo {
|
||||
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
|
||||
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>",
|
||||
};
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
/// The `rust_2021_prefixes_incompatible_syntax` lint detects identifiers that will be parsed as a
|
||||
/// prefix instead in Rust 2021.
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use crate::core::builder::{
|
|||
};
|
||||
use crate::core::config::TargetSelection;
|
||||
use crate::{Compiler, Mode, Subcommand};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn cargo_subcommand(kind: Kind) -> &'static str {
|
||||
match kind {
|
||||
|
|
@ -52,7 +52,7 @@ impl Step for Std {
|
|||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
builder.update_submodule(&Path::new("library").join("stdarch"));
|
||||
builder.require_submodule("library/stdarch", None);
|
||||
|
||||
let target = self.target;
|
||||
let compiler = builder.compiler(builder.top_stage, builder.config.build);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
//! Implementation of running clippy on the compiler, standard library and various tools.
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use crate::builder::Builder;
|
||||
use crate::builder::ShouldRun;
|
||||
use crate::core::builder;
|
||||
|
|
@ -127,7 +125,7 @@ impl Step for Std {
|
|||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
builder.update_submodule(&Path::new("library").join("stdarch"));
|
||||
builder.require_submodule("library/stdarch", None);
|
||||
|
||||
let target = self.target;
|
||||
let compiler = builder.compiler(builder.top_stage, builder.config.build);
|
||||
|
|
|
|||
|
|
@ -182,11 +182,16 @@ impl Step for Std {
|
|||
return;
|
||||
}
|
||||
|
||||
builder.update_submodule(&Path::new("library").join("stdarch"));
|
||||
builder.require_submodule("library/stdarch", None);
|
||||
|
||||
// Profiler information requires LLVM's compiler-rt
|
||||
if builder.config.profiler {
|
||||
builder.update_submodule(Path::new("src/llvm-project"));
|
||||
builder.require_submodule(
|
||||
"src/llvm-project",
|
||||
Some(
|
||||
"The `build.profiler` config option requires `compiler-rt` sources from LLVM.",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
let mut target_deps = builder.ensure(StartupObjects { compiler, target });
|
||||
|
|
@ -456,13 +461,15 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
|
|||
// That's probably ok? At least, the difference wasn't enforced before. There's a comment in
|
||||
// the compiler_builtins build script that makes me nervous, though:
|
||||
// https://github.com/rust-lang/compiler-builtins/blob/31ee4544dbe47903ce771270d6e3bea8654e9e50/build.rs#L575-L579
|
||||
builder.update_submodule(&Path::new("src").join("llvm-project"));
|
||||
builder.require_submodule(
|
||||
"src/llvm-project",
|
||||
Some(
|
||||
"The `build.optimized-compiler-builtins` config option \
|
||||
requires `compiler-rt` sources from LLVM.",
|
||||
),
|
||||
);
|
||||
let compiler_builtins_root = builder.src.join("src/llvm-project/compiler-rt");
|
||||
if !compiler_builtins_root.exists() {
|
||||
panic!(
|
||||
"need LLVM sources available to build `compiler-rt`, but they weren't present; consider enabling `build.submodules = true` or disabling `optimized-compiler-builtins`"
|
||||
);
|
||||
}
|
||||
assert!(compiler_builtins_root.exists());
|
||||
// Note that `libprofiler_builtins/build.rs` also computes this so if
|
||||
// you're changing something here please also change that.
|
||||
cargo.env("RUST_COMPILER_RT_ROOT", &compiler_builtins_root);
|
||||
|
|
|
|||
|
|
@ -907,7 +907,7 @@ impl Step for Src {
|
|||
/// Creates the `rust-src` installer component
|
||||
fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
|
||||
if !builder.config.dry_run() {
|
||||
builder.update_submodule(Path::new("src/llvm-project"));
|
||||
builder.require_submodule("src/llvm-project", None);
|
||||
}
|
||||
|
||||
let tarball = Tarball::new_targetless(builder, "rust-src");
|
||||
|
|
@ -1022,10 +1022,7 @@ impl Step for PlainSourceTarball {
|
|||
// FIXME: This code looks _very_ similar to what we have in `src/core/build_steps/vendor.rs`
|
||||
// perhaps it should be removed in favor of making `dist` perform the `vendor` step?
|
||||
|
||||
// Ensure we have all submodules from src and other directories checked out.
|
||||
for submodule in build_helper::util::parse_gitmodules(&builder.src) {
|
||||
builder.update_submodule(Path::new(submodule));
|
||||
}
|
||||
builder.require_and_update_all_submodules();
|
||||
|
||||
// Vendor all Cargo dependencies
|
||||
let mut cmd = command(&builder.initial_cargo);
|
||||
|
|
|
|||
|
|
@ -9,14 +9,14 @@
|
|||
|
||||
use std::io::{self, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{fs, mem};
|
||||
use std::{env, fs, mem};
|
||||
|
||||
use crate::core::build_steps::compile;
|
||||
use crate::core::build_steps::tool::{self, prepare_tool_cargo, SourceType, Tool};
|
||||
use crate::core::builder::{self, crate_description};
|
||||
use crate::core::builder::{Alias, Builder, Compiler, Kind, RunConfig, ShouldRun, Step};
|
||||
use crate::core::config::{Config, TargetSelection};
|
||||
use crate::utils::helpers::{dir_is_empty, symlink_dir, t, up_to_date};
|
||||
use crate::utils::helpers::{symlink_dir, t, up_to_date};
|
||||
use crate::Mode;
|
||||
|
||||
macro_rules! submodule_helper {
|
||||
|
|
@ -53,8 +53,8 @@ macro_rules! book {
|
|||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
$(
|
||||
let path = Path::new(submodule_helper!( $path, submodule $( = $submodule )? ));
|
||||
builder.update_submodule(&path);
|
||||
let path = submodule_helper!( $path, submodule $( = $submodule )? );
|
||||
builder.require_submodule(path, None);
|
||||
)?
|
||||
builder.ensure(RustbookSrc {
|
||||
target: self.target,
|
||||
|
|
@ -62,6 +62,7 @@ macro_rules! book {
|
|||
src: builder.src.join($path),
|
||||
parent: Some(self),
|
||||
languages: $lang.into(),
|
||||
rustdoc: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -80,7 +81,6 @@ book!(
|
|||
EditionGuide, "src/doc/edition-guide", "edition-guide", &[], submodule;
|
||||
EmbeddedBook, "src/doc/embedded-book", "embedded-book", &[], submodule;
|
||||
Nomicon, "src/doc/nomicon", "nomicon", &[], submodule;
|
||||
Reference, "src/doc/reference", "reference", &[], submodule;
|
||||
RustByExample, "src/doc/rust-by-example", "rust-by-example", &["ja"], submodule;
|
||||
RustdocBook, "src/doc/rustdoc", "rustdoc", &[];
|
||||
StyleGuide, "src/doc/style-guide", "style-guide", &[];
|
||||
|
|
@ -112,6 +112,7 @@ impl Step for UnstableBook {
|
|||
src: builder.md_doc_out(self.target).join("unstable-book"),
|
||||
parent: Some(self),
|
||||
languages: vec![],
|
||||
rustdoc: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -123,6 +124,7 @@ struct RustbookSrc<P: Step> {
|
|||
src: PathBuf,
|
||||
parent: Option<P>,
|
||||
languages: Vec<&'static str>,
|
||||
rustdoc: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl<P: Step> Step for RustbookSrc<P> {
|
||||
|
|
@ -153,13 +155,18 @@ impl<P: Step> Step for RustbookSrc<P> {
|
|||
builder.info(&format!("Rustbook ({target}) - {name}"));
|
||||
let _ = fs::remove_dir_all(&out);
|
||||
|
||||
builder
|
||||
.tool_cmd(Tool::Rustbook)
|
||||
.arg("build")
|
||||
.arg(&src)
|
||||
.arg("-d")
|
||||
.arg(&out)
|
||||
.run(builder);
|
||||
let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook);
|
||||
if let Some(mut rustdoc) = self.rustdoc {
|
||||
rustdoc.pop();
|
||||
let old_path = env::var_os("PATH").unwrap_or_default();
|
||||
let new_path =
|
||||
env::join_paths(std::iter::once(rustdoc).chain(env::split_paths(&old_path)))
|
||||
.expect("could not add rustdoc to PATH");
|
||||
|
||||
rustbook_cmd.env("PATH", new_path);
|
||||
}
|
||||
|
||||
rustbook_cmd.arg("build").arg(&src).arg("-d").arg(&out).run(builder);
|
||||
|
||||
for lang in &self.languages {
|
||||
let out = out.join(lang);
|
||||
|
|
@ -217,22 +224,14 @@ impl Step for TheBook {
|
|||
/// * Index page
|
||||
/// * Redirect pages
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
let relative_path = Path::new("src").join("doc").join("book");
|
||||
builder.update_submodule(&relative_path);
|
||||
builder.require_submodule("src/doc/book", None);
|
||||
|
||||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
|
||||
let absolute_path = builder.src.join(&relative_path);
|
||||
let absolute_path = builder.src.join("src/doc/book");
|
||||
let redirect_path = absolute_path.join("redirects");
|
||||
if !absolute_path.exists()
|
||||
|| !redirect_path.exists()
|
||||
|| dir_is_empty(&absolute_path)
|
||||
|| dir_is_empty(&redirect_path)
|
||||
{
|
||||
eprintln!("Please checkout submodule: {}", relative_path.display());
|
||||
crate::exit!(1);
|
||||
}
|
||||
|
||||
// build book
|
||||
builder.ensure(RustbookSrc {
|
||||
target,
|
||||
|
|
@ -240,6 +239,7 @@ impl Step for TheBook {
|
|||
src: absolute_path.clone(),
|
||||
parent: Some(self),
|
||||
languages: vec![],
|
||||
rustdoc: None,
|
||||
});
|
||||
|
||||
// building older edition redirects
|
||||
|
|
@ -252,6 +252,7 @@ impl Step for TheBook {
|
|||
// treat the other editions as not having a parent.
|
||||
parent: Option::<Self>::None,
|
||||
languages: vec![],
|
||||
rustdoc: None,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -932,8 +933,8 @@ macro_rules! tool_doc {
|
|||
let _ = source_type; // silence the "unused variable" warning
|
||||
let source_type = SourceType::Submodule;
|
||||
|
||||
let path = Path::new(submodule_helper!( $path, submodule $( = $submodule )? ));
|
||||
builder.update_submodule(&path);
|
||||
let path = submodule_helper!( $path, submodule $( = $submodule )? );
|
||||
builder.require_submodule(path, None);
|
||||
)?
|
||||
|
||||
let stage = builder.top_stage;
|
||||
|
|
@ -1172,12 +1173,6 @@ impl Step for RustcBook {
|
|||
/// in the "md-doc" directory in the build output directory. Then
|
||||
/// "rustbook" is used to convert it to HTML.
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
// These submodules are required to be checked out to build rustbook
|
||||
// because they have Cargo dependencies that are needed.
|
||||
#[allow(clippy::single_element_loop)] // This will change soon.
|
||||
for path in ["src/doc/book"] {
|
||||
builder.update_submodule(Path::new(path));
|
||||
}
|
||||
let out_base = builder.md_doc_out(self.target).join("rustc");
|
||||
t!(fs::create_dir_all(&out_base));
|
||||
let out_listing = out_base.join("src/lints");
|
||||
|
|
@ -1228,6 +1223,50 @@ impl Step for RustcBook {
|
|||
src: out_base,
|
||||
parent: Some(self),
|
||||
languages: vec![],
|
||||
rustdoc: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Ord, PartialOrd, Debug, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Reference {
|
||||
pub compiler: Compiler,
|
||||
pub target: TargetSelection,
|
||||
}
|
||||
|
||||
impl Step for Reference {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
let builder = run.builder;
|
||||
run.path("src/doc/reference").default_condition(builder.config.docs)
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
run.builder.ensure(Reference {
|
||||
compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
|
||||
target: run.target,
|
||||
});
|
||||
}
|
||||
|
||||
/// Builds the reference book.
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
builder.require_submodule("src/doc/reference", None);
|
||||
|
||||
// This is needed for generating links to the standard library using
|
||||
// the mdbook-spec plugin.
|
||||
builder.ensure(compile::Std::new(self.compiler, builder.config.build));
|
||||
let rustdoc = builder.rustdoc(self.compiler);
|
||||
|
||||
// Run rustbook/mdbook to generate the HTML pages.
|
||||
builder.ensure(RustbookSrc {
|
||||
target: self.target,
|
||||
name: "reference".to_owned(),
|
||||
src: builder.src.join("src/doc/reference"),
|
||||
parent: Some(self),
|
||||
languages: vec![],
|
||||
rustdoc: Some(rustdoc),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ impl LdFlags {
|
|||
/// if not).
|
||||
pub fn prebuilt_llvm_config(builder: &Builder<'_>, target: TargetSelection) -> LlvmBuildStatus {
|
||||
// If we have llvm submodule initialized already, sync it.
|
||||
builder.update_existing_submodule(&Path::new("src").join("llvm-project"));
|
||||
builder.update_existing_submodule("src/llvm-project");
|
||||
|
||||
builder.config.maybe_download_ci_llvm();
|
||||
|
||||
|
|
@ -110,7 +110,8 @@ pub fn prebuilt_llvm_config(builder: &Builder<'_>, target: TargetSelection) -> L
|
|||
}
|
||||
|
||||
// Initialize the llvm submodule if not initialized already.
|
||||
builder.update_submodule(&Path::new("src").join("llvm-project"));
|
||||
// If submodules are disabled, this does nothing.
|
||||
builder.update_submodule("src/llvm-project");
|
||||
|
||||
let root = "src/llvm-project/llvm";
|
||||
let out_dir = builder.llvm_out(target);
|
||||
|
|
@ -1197,7 +1198,10 @@ impl Step for CrtBeginEnd {
|
|||
|
||||
/// Build crtbegin.o/crtend.o for musl target.
|
||||
fn run(self, builder: &Builder<'_>) -> Self::Output {
|
||||
builder.update_submodule(Path::new("src/llvm-project"));
|
||||
builder.require_submodule(
|
||||
"src/llvm-project",
|
||||
Some("The LLVM sources are required for the CRT from `compiler-rt`."),
|
||||
);
|
||||
|
||||
let out_dir = builder.native_dir(self.target).join("crt");
|
||||
|
||||
|
|
@ -1270,7 +1274,10 @@ impl Step for Libunwind {
|
|||
|
||||
/// Build libunwind.a
|
||||
fn run(self, builder: &Builder<'_>) -> Self::Output {
|
||||
builder.update_submodule(Path::new("src/llvm-project"));
|
||||
builder.require_submodule(
|
||||
"src/llvm-project",
|
||||
Some("The LLVM sources are required for libunwind."),
|
||||
);
|
||||
|
||||
if builder.config.dry_run() {
|
||||
return PathBuf::new();
|
||||
|
|
|
|||
|
|
@ -2254,7 +2254,12 @@ impl BookTest {
|
|||
}
|
||||
|
||||
macro_rules! test_book {
|
||||
($($name:ident, $path:expr, $book_name:expr, default=$default:expr;)+) => {
|
||||
($(
|
||||
$name:ident, $path:expr, $book_name:expr,
|
||||
default=$default:expr
|
||||
$(,submodules = $submodules:expr)?
|
||||
;
|
||||
)+) => {
|
||||
$(
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct $name {
|
||||
|
|
@ -2277,6 +2282,11 @@ macro_rules! test_book {
|
|||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
$(
|
||||
for submodule in $submodules {
|
||||
builder.require_submodule(submodule, None);
|
||||
}
|
||||
)*
|
||||
builder.ensure(BookTest {
|
||||
compiler: self.compiler,
|
||||
path: PathBuf::from($path),
|
||||
|
|
@ -2290,15 +2300,15 @@ macro_rules! test_book {
|
|||
}
|
||||
|
||||
test_book!(
|
||||
Nomicon, "src/doc/nomicon", "nomicon", default=false;
|
||||
Reference, "src/doc/reference", "reference", default=false;
|
||||
Nomicon, "src/doc/nomicon", "nomicon", default=false, submodules=["src/doc/nomicon"];
|
||||
Reference, "src/doc/reference", "reference", default=false, submodules=["src/doc/reference"];
|
||||
RustdocBook, "src/doc/rustdoc", "rustdoc", default=true;
|
||||
RustcBook, "src/doc/rustc", "rustc", default=true;
|
||||
RustByExample, "src/doc/rust-by-example", "rust-by-example", default=false;
|
||||
EmbeddedBook, "src/doc/embedded-book", "embedded-book", default=false;
|
||||
TheBook, "src/doc/book", "book", default=false;
|
||||
RustByExample, "src/doc/rust-by-example", "rust-by-example", default=false, submodules=["src/doc/rust-by-example"];
|
||||
EmbeddedBook, "src/doc/embedded-book", "embedded-book", default=false, submodules=["src/doc/embedded-book"];
|
||||
TheBook, "src/doc/book", "book", default=false, submodules=["src/doc/book"];
|
||||
UnstableBook, "src/doc/unstable-book", "unstable-book", default=true;
|
||||
EditionGuide, "src/doc/edition-guide", "edition-guide", default=false;
|
||||
EditionGuide, "src/doc/edition-guide", "edition-guide", default=false, submodules=["src/doc/edition-guide"];
|
||||
);
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
|
|
@ -2396,8 +2406,8 @@ impl Step for RustcGuide {
|
|||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
let relative_path = Path::new("src").join("doc").join("rustc-dev-guide");
|
||||
builder.update_submodule(&relative_path);
|
||||
let relative_path = "src/doc/rustc-dev-guide";
|
||||
builder.require_submodule(relative_path, None);
|
||||
|
||||
let src = builder.src.join(relative_path);
|
||||
let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook).delay_failure();
|
||||
|
|
@ -3003,7 +3013,7 @@ impl Step for Bootstrap {
|
|||
let _guard = builder.msg(Kind::Test, 0, "bootstrap", host, host);
|
||||
|
||||
// Some tests require cargo submodule to be present.
|
||||
builder.build.update_submodule(Path::new("src/tools/cargo"));
|
||||
builder.build.require_submodule("src/tools/cargo", None);
|
||||
|
||||
let mut check_bootstrap = command(builder.python());
|
||||
check_bootstrap
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::core::build_steps::compile;
|
||||
use crate::core::build_steps::toolstate::ToolState;
|
||||
|
|
@ -241,6 +241,7 @@ macro_rules! bootstrap_tool {
|
|||
$(,is_external_tool = $external:expr)*
|
||||
$(,is_unstable_tool = $unstable:expr)*
|
||||
$(,allow_features = $allow_features:expr)?
|
||||
$(,submodules = $submodules:expr)?
|
||||
;
|
||||
)+) => {
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
|
|
@ -287,6 +288,11 @@ macro_rules! bootstrap_tool {
|
|||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
$(
|
||||
for submodule in $submodules {
|
||||
builder.require_submodule(submodule, None);
|
||||
}
|
||||
)*
|
||||
builder.ensure(ToolBuild {
|
||||
compiler: self.compiler,
|
||||
target: self.target,
|
||||
|
|
@ -314,7 +320,7 @@ macro_rules! bootstrap_tool {
|
|||
}
|
||||
|
||||
bootstrap_tool!(
|
||||
Rustbook, "src/tools/rustbook", "rustbook";
|
||||
Rustbook, "src/tools/rustbook", "rustbook", submodules = SUBMODULES_FOR_RUSTBOOK;
|
||||
UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen";
|
||||
Tidy, "src/tools/tidy", "tidy";
|
||||
Linkchecker, "src/tools/linkchecker", "linkchecker";
|
||||
|
|
@ -340,6 +346,10 @@ bootstrap_tool!(
|
|||
WasmComponentLd, "src/tools/wasm-component-ld", "wasm-component-ld", is_unstable_tool = true, allow_features = "min_specialization";
|
||||
);
|
||||
|
||||
/// These are the submodules that are required for rustbook to work due to
|
||||
/// depending on mdbook plugins.
|
||||
pub static SUBMODULES_FOR_RUSTBOOK: &[&str] = &["src/doc/book", "src/doc/reference"];
|
||||
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct OptimizedDist {
|
||||
pub compiler: Compiler,
|
||||
|
|
@ -363,7 +373,7 @@ impl Step for OptimizedDist {
|
|||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
// We need to ensure the rustc-perf submodule is initialized when building opt-dist since
|
||||
// the tool requires it to be in place to run.
|
||||
builder.update_submodule(Path::new("src/tools/rustc-perf"));
|
||||
builder.require_submodule("src/tools/rustc-perf", None);
|
||||
|
||||
builder.ensure(ToolBuild {
|
||||
compiler: self.compiler,
|
||||
|
|
@ -404,7 +414,7 @@ impl Step for RustcPerf {
|
|||
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
// We need to ensure the rustc-perf submodule is initialized.
|
||||
builder.update_submodule(Path::new("src/tools/rustc-perf"));
|
||||
builder.require_submodule("src/tools/rustc-perf", None);
|
||||
|
||||
let tool = ToolBuild {
|
||||
compiler: self.compiler,
|
||||
|
|
@ -704,7 +714,7 @@ impl Step for Cargo {
|
|||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
builder.build.update_submodule(Path::new("src/tools/cargo"));
|
||||
builder.build.require_submodule("src/tools/cargo", None);
|
||||
|
||||
builder.ensure(ToolBuild {
|
||||
compiler: self.compiler,
|
||||
|
|
@ -1086,8 +1096,6 @@ macro_rules! tool_extended {
|
|||
|
||||
// NOTE: tools need to be also added to `Builder::get_step_descriptions` in `builder.rs`
|
||||
// to make `./x.py build <tool>` work.
|
||||
// NOTE: Most submodule updates for tools are handled by bootstrap.py, since they're needed just to
|
||||
// invoke Cargo to build bootstrap. See the comment there for more details.
|
||||
tool_extended!((self, builder),
|
||||
Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true;
|
||||
CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use crate::core::build_steps::tool::SUBMODULES_FOR_RUSTBOOK;
|
||||
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
use crate::utils::exec::command;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||
pub(crate) struct Vendor {
|
||||
|
|
@ -35,8 +36,8 @@ impl Step for Vendor {
|
|||
}
|
||||
|
||||
// These submodules must be present for `x vendor` to work.
|
||||
for path in ["src/tools/cargo", "src/doc/book"] {
|
||||
builder.build.update_submodule(Path::new(path));
|
||||
for submodule in SUBMODULES_FOR_RUSTBOOK.iter().chain(["src/tools/cargo"].iter()) {
|
||||
builder.build.require_submodule(submodule, None);
|
||||
}
|
||||
|
||||
// Sync these paths by default.
|
||||
|
|
|
|||
|
|
@ -13,15 +13,18 @@ fn configure_with_args(cmd: &[String], host: &[&str], target: &[&str]) -> Config
|
|||
config.save_toolstates = None;
|
||||
config.dry_run = DryRun::SelfCheck;
|
||||
|
||||
// Ignore most submodules, since we don't need them for a dry run.
|
||||
// But make sure to check out the `doc` and `rust-analyzer` submodules, since some steps need them
|
||||
// just to know which commands to run.
|
||||
// Ignore most submodules, since we don't need them for a dry run, and the
|
||||
// tests run much faster without them.
|
||||
//
|
||||
// The src/doc/book submodule is needed because TheBook step tries to
|
||||
// access files even during a dry-run (may want to consider just skipping
|
||||
// that in a dry run).
|
||||
let submodule_build = Build::new(Config {
|
||||
// don't include LLVM, so CI doesn't require ninja/cmake to be installed
|
||||
rust_codegen_backends: vec![],
|
||||
..Config::parse(&["check".to_owned()])
|
||||
});
|
||||
submodule_build.update_submodule(Path::new("src/doc/book"));
|
||||
submodule_build.require_submodule("src/doc/book", None);
|
||||
config.submodules = Some(false);
|
||||
|
||||
config.ninja_in_file = false;
|
||||
|
|
|
|||
|
|
@ -2404,8 +2404,11 @@ impl Config {
|
|||
.unwrap_or_else(|| SplitDebuginfo::default_for_platform(target))
|
||||
}
|
||||
|
||||
pub fn submodules(&self, rust_info: &GitInfo) -> bool {
|
||||
self.submodules.unwrap_or(rust_info.is_managed_git_subrepository())
|
||||
/// Returns whether or not submodules should be managed by bootstrap.
|
||||
pub fn submodules(&self) -> bool {
|
||||
// If not specified in config, the default is to only manage
|
||||
// submodules if we're currently inside a git repository.
|
||||
self.submodules.unwrap_or(self.rust_info.is_managed_git_subrepository())
|
||||
}
|
||||
|
||||
pub fn codegen_backends(&self, target: TargetSelection) -> &[String] {
|
||||
|
|
|
|||
|
|
@ -441,7 +441,13 @@ impl Build {
|
|||
// Cargo.toml files.
|
||||
let rust_submodules = ["library/backtrace", "library/stdarch"];
|
||||
for s in rust_submodules {
|
||||
build.update_submodule(Path::new(s));
|
||||
build.require_submodule(
|
||||
s,
|
||||
Some(
|
||||
"The submodule is required for the standard library \
|
||||
and the main Cargo workspace.",
|
||||
),
|
||||
);
|
||||
}
|
||||
// Now, update all existing submodules.
|
||||
build.update_existing_submodules();
|
||||
|
|
@ -470,12 +476,17 @@ impl Build {
|
|||
build
|
||||
}
|
||||
|
||||
// modified from `check_submodule` and `update_submodule` in bootstrap.py
|
||||
/// Given a path to the directory of a submodule, update it.
|
||||
///
|
||||
/// `relative_path` should be relative to the root of the git repository, not an absolute path.
|
||||
pub(crate) fn update_submodule(&self, relative_path: &Path) {
|
||||
if !self.config.submodules(self.rust_info()) {
|
||||
///
|
||||
/// This *does not* update the submodule if `config.toml` explicitly says
|
||||
/// not to, or if we're not in a git repository (like a plain source
|
||||
/// tarball). Typically [`Build::require_submodule`] should be
|
||||
/// used instead to provide a nice error to the user if the submodule is
|
||||
/// missing.
|
||||
fn update_submodule(&self, relative_path: &str) {
|
||||
if !self.config.submodules() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -522,7 +533,7 @@ impl Build {
|
|||
return;
|
||||
}
|
||||
|
||||
println!("Updating submodule {}", relative_path.display());
|
||||
println!("Updating submodule {relative_path}");
|
||||
helpers::git(Some(&self.src))
|
||||
.run_always()
|
||||
.args(["submodule", "-q", "sync"])
|
||||
|
|
@ -576,11 +587,53 @@ impl Build {
|
|||
}
|
||||
}
|
||||
|
||||
/// Updates a submodule, and exits with a failure if submodule management
|
||||
/// is disabled and the submodule does not exist.
|
||||
///
|
||||
/// The given submodule name should be its path relative to the root of
|
||||
/// the main repository.
|
||||
///
|
||||
/// The given `err_hint` will be shown to the user if the submodule is not
|
||||
/// checked out and submodule management is disabled.
|
||||
pub fn require_submodule(&self, submodule: &str, err_hint: Option<&str>) {
|
||||
// When testing bootstrap itself, it is much faster to ignore
|
||||
// submodules. Almost all Steps work fine without their submodules.
|
||||
if cfg!(test) && !self.config.submodules() {
|
||||
return;
|
||||
}
|
||||
self.update_submodule(submodule);
|
||||
let absolute_path = self.config.src.join(submodule);
|
||||
if dir_is_empty(&absolute_path) {
|
||||
let maybe_enable = if !self.config.submodules()
|
||||
&& self.config.rust_info.is_managed_git_subrepository()
|
||||
{
|
||||
"\nConsider setting `build.submodules = true` or manually initializing the submodules."
|
||||
} else {
|
||||
""
|
||||
};
|
||||
let err_hint = err_hint.map_or_else(String::new, |e| format!("\n{e}"));
|
||||
eprintln!(
|
||||
"submodule {submodule} does not appear to be checked out, \
|
||||
but it is required for this step{maybe_enable}{err_hint}"
|
||||
);
|
||||
exit!(1);
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates all submodules, and exits with an error if submodule
|
||||
/// management is disabled and the submodule does not exist.
|
||||
pub fn require_and_update_all_submodules(&self) {
|
||||
for submodule in build_helper::util::parse_gitmodules(&self.src) {
|
||||
self.require_submodule(submodule, None);
|
||||
}
|
||||
}
|
||||
|
||||
/// If any submodule has been initialized already, sync it unconditionally.
|
||||
/// This avoids contributors checking in a submodule change by accident.
|
||||
pub fn update_existing_submodules(&self) {
|
||||
// Avoid running git when there isn't a git checkout.
|
||||
if !self.config.submodules(self.rust_info()) {
|
||||
fn update_existing_submodules(&self) {
|
||||
// Avoid running git when there isn't a git checkout, or the user has
|
||||
// explicitly disabled submodules in `config.toml`.
|
||||
if !self.config.submodules() {
|
||||
return;
|
||||
}
|
||||
let output = helpers::git(Some(&self.src))
|
||||
|
|
@ -592,22 +645,23 @@ impl Build {
|
|||
for line in output.lines() {
|
||||
// Look for `submodule.$name.path = $path`
|
||||
// Sample output: `submodule.src/rust-installer.path src/tools/rust-installer`
|
||||
let submodule = Path::new(line.split_once(' ').unwrap().1);
|
||||
let submodule = line.split_once(' ').unwrap().1;
|
||||
let path = Path::new(submodule);
|
||||
// Don't update the submodule unless it's already been cloned.
|
||||
if GitInfo::new(false, submodule).is_managed_git_subrepository() {
|
||||
if GitInfo::new(false, path).is_managed_git_subrepository() {
|
||||
self.update_submodule(submodule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates the given submodule only if it's initialized already; nothing happens otherwise.
|
||||
pub fn update_existing_submodule(&self, submodule: &Path) {
|
||||
pub fn update_existing_submodule(&self, submodule: &str) {
|
||||
// Avoid running git when there isn't a git checkout.
|
||||
if !self.config.submodules(self.rust_info()) {
|
||||
if !self.config.submodules() {
|
||||
return;
|
||||
}
|
||||
|
||||
if GitInfo::new(false, submodule).is_managed_git_subrepository() {
|
||||
if GitInfo::new(false, Path::new(submodule)).is_managed_git_subrepository() {
|
||||
self.update_submodule(submodule);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit e2f0bdc4031866734661dcdb548184bde1450baf
|
||||
Subproject commit 2e191814f163ee1e77e2d6094eee4dd78a289c5b
|
||||
|
|
@ -131,8 +131,8 @@ pub(crate) fn try_inline(
|
|||
Res::Def(DefKind::Const, did) => {
|
||||
record_extern_fqn(cx, did, ItemType::Constant);
|
||||
cx.with_param_env(did, |cx| {
|
||||
let (generics, ty, ct) = build_const_item(cx, did);
|
||||
clean::ConstantItem(generics, Box::new(ty), ct)
|
||||
let ct = build_const_item(cx, did);
|
||||
clean::ConstantItem(Box::new(ct))
|
||||
})
|
||||
}
|
||||
Res::Def(DefKind::Macro(kind), did) => {
|
||||
|
|
@ -720,10 +720,7 @@ pub(crate) fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
fn build_const_item(
|
||||
cx: &mut DocContext<'_>,
|
||||
def_id: DefId,
|
||||
) -> (clean::Generics, clean::Type, clean::Constant) {
|
||||
fn build_const_item(cx: &mut DocContext<'_>, def_id: DefId) -> clean::Constant {
|
||||
let mut generics =
|
||||
clean_ty_generics(cx, cx.tcx.generics_of(def_id), cx.tcx.explicit_predicates_of(def_id));
|
||||
clean::simplify::move_bounds_to_generic_parameters(&mut generics);
|
||||
|
|
@ -733,17 +730,17 @@ fn build_const_item(
|
|||
None,
|
||||
None,
|
||||
);
|
||||
(generics, ty, clean::Constant { kind: clean::ConstantKind::Extern { def_id } })
|
||||
clean::Constant { generics, type_: ty, kind: clean::ConstantKind::Extern { def_id } }
|
||||
}
|
||||
|
||||
fn build_static(cx: &mut DocContext<'_>, did: DefId, mutable: bool) -> clean::Static {
|
||||
clean::Static {
|
||||
type_: clean_middle_ty(
|
||||
type_: Box::new(clean_middle_ty(
|
||||
ty::Binder::dummy(cx.tcx.type_of(did).instantiate_identity()),
|
||||
cx,
|
||||
Some(did),
|
||||
None,
|
||||
),
|
||||
)),
|
||||
mutability: if mutable { Mutability::Mut } else { Mutability::Not },
|
||||
expr: None,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -287,23 +287,21 @@ fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) ->
|
|||
pub(crate) fn clean_const<'tcx>(
|
||||
constant: &hir::ConstArg<'tcx>,
|
||||
_cx: &mut DocContext<'tcx>,
|
||||
) -> Constant {
|
||||
) -> ConstantKind {
|
||||
match &constant.kind {
|
||||
hir::ConstArgKind::Path(qpath) => {
|
||||
Constant { kind: ConstantKind::Path { path: qpath_to_string(&qpath).into() } }
|
||||
}
|
||||
hir::ConstArgKind::Anon(anon) => {
|
||||
Constant { kind: ConstantKind::Anonymous { body: anon.body } }
|
||||
ConstantKind::Path { path: qpath_to_string(&qpath).into() }
|
||||
}
|
||||
hir::ConstArgKind::Anon(anon) => ConstantKind::Anonymous { body: anon.body },
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn clean_middle_const<'tcx>(
|
||||
constant: ty::Binder<'tcx, ty::Const<'tcx>>,
|
||||
_cx: &mut DocContext<'tcx>,
|
||||
) -> Constant {
|
||||
) -> ConstantKind {
|
||||
// FIXME: instead of storing the stringified expression, store `self` directly instead.
|
||||
Constant { kind: ConstantKind::TyConst { expr: constant.skip_binder().to_string().into() } }
|
||||
ConstantKind::TyConst { expr: constant.skip_binder().to_string().into() }
|
||||
}
|
||||
|
||||
pub(crate) fn clean_middle_region<'tcx>(region: ty::Region<'tcx>) -> Option<Lifetime> {
|
||||
|
|
@ -1230,14 +1228,11 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext
|
|||
let local_did = trait_item.owner_id.to_def_id();
|
||||
cx.with_param_env(local_did, |cx| {
|
||||
let inner = match trait_item.kind {
|
||||
hir::TraitItemKind::Const(ty, Some(default)) => {
|
||||
let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx));
|
||||
AssocConstItem(
|
||||
generics,
|
||||
Box::new(clean_ty(ty, cx)),
|
||||
ConstantKind::Local { def_id: local_did, body: default },
|
||||
)
|
||||
}
|
||||
hir::TraitItemKind::Const(ty, Some(default)) => AssocConstItem(Box::new(Constant {
|
||||
generics: enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)),
|
||||
kind: ConstantKind::Local { def_id: local_did, body: default },
|
||||
type_: clean_ty(ty, cx),
|
||||
})),
|
||||
hir::TraitItemKind::Const(ty, None) => {
|
||||
let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx));
|
||||
TyAssocConstItem(generics, Box::new(clean_ty(ty, cx)))
|
||||
|
|
@ -1282,11 +1277,11 @@ pub(crate) fn clean_impl_item<'tcx>(
|
|||
let local_did = impl_.owner_id.to_def_id();
|
||||
cx.with_param_env(local_did, |cx| {
|
||||
let inner = match impl_.kind {
|
||||
hir::ImplItemKind::Const(ty, expr) => {
|
||||
let generics = clean_generics(impl_.generics, cx);
|
||||
let default = ConstantKind::Local { def_id: local_did, body: expr };
|
||||
AssocConstItem(generics, Box::new(clean_ty(ty, cx)), default)
|
||||
}
|
||||
hir::ImplItemKind::Const(ty, expr) => AssocConstItem(Box::new(Constant {
|
||||
generics: clean_generics(impl_.generics, cx),
|
||||
kind: ConstantKind::Local { def_id: local_did, body: expr },
|
||||
type_: clean_ty(ty, cx),
|
||||
})),
|
||||
hir::ImplItemKind::Fn(ref sig, body) => {
|
||||
let m = clean_function(cx, sig, impl_.generics, FunctionArgs::Body(body));
|
||||
let defaultness = cx.tcx.defaultness(impl_.owner_id);
|
||||
|
|
@ -1320,12 +1315,12 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
|
|||
let tcx = cx.tcx;
|
||||
let kind = match assoc_item.kind {
|
||||
ty::AssocKind::Const => {
|
||||
let ty = Box::new(clean_middle_ty(
|
||||
let ty = clean_middle_ty(
|
||||
ty::Binder::dummy(tcx.type_of(assoc_item.def_id).instantiate_identity()),
|
||||
cx,
|
||||
Some(assoc_item.def_id),
|
||||
None,
|
||||
));
|
||||
);
|
||||
|
||||
let mut generics = clean_ty_generics(
|
||||
cx,
|
||||
|
|
@ -1339,9 +1334,13 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
|
|||
ty::TraitContainer => tcx.defaultness(assoc_item.def_id).has_value(),
|
||||
};
|
||||
if provided {
|
||||
AssocConstItem(generics, ty, ConstantKind::Extern { def_id: assoc_item.def_id })
|
||||
AssocConstItem(Box::new(Constant {
|
||||
generics,
|
||||
kind: ConstantKind::Extern { def_id: assoc_item.def_id },
|
||||
type_: ty,
|
||||
}))
|
||||
} else {
|
||||
TyAssocConstItem(generics, ty)
|
||||
TyAssocConstItem(generics, Box::new(ty))
|
||||
}
|
||||
}
|
||||
ty::AssocKind::Fn => {
|
||||
|
|
@ -1397,7 +1396,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
|
|||
{
|
||||
true
|
||||
}
|
||||
(GenericParamDefKind::Const { .. }, GenericArg::Const(c)) => match &c.kind {
|
||||
(GenericParamDefKind::Const { .. }, GenericArg::Const(c)) => match &**c {
|
||||
ConstantKind::TyConst { expr } => **expr == *param.name.as_str(),
|
||||
_ => false,
|
||||
},
|
||||
|
|
@ -2744,14 +2743,16 @@ fn clean_maybe_renamed_item<'tcx>(
|
|||
let mut name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id()));
|
||||
cx.with_param_env(def_id, |cx| {
|
||||
let kind = match item.kind {
|
||||
ItemKind::Static(ty, mutability, body_id) => {
|
||||
StaticItem(Static { type_: clean_ty(ty, cx), mutability, expr: Some(body_id) })
|
||||
}
|
||||
ItemKind::Const(ty, generics, body_id) => ConstantItem(
|
||||
clean_generics(generics, cx),
|
||||
Box::new(clean_ty(ty, cx)),
|
||||
Constant { kind: ConstantKind::Local { body: body_id, def_id } },
|
||||
),
|
||||
ItemKind::Static(ty, mutability, body_id) => StaticItem(Static {
|
||||
type_: Box::new(clean_ty(ty, cx)),
|
||||
mutability,
|
||||
expr: Some(body_id),
|
||||
}),
|
||||
ItemKind::Const(ty, generics, body_id) => ConstantItem(Box::new(Constant {
|
||||
generics: clean_generics(generics, cx),
|
||||
type_: clean_ty(ty, cx),
|
||||
kind: ConstantKind::Local { body: body_id, def_id },
|
||||
})),
|
||||
ItemKind::OpaqueTy(ref ty) => OpaqueTyItem(OpaqueTy {
|
||||
bounds: ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(),
|
||||
generics: clean_generics(ty.generics, cx),
|
||||
|
|
@ -3109,7 +3110,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
|
|||
ForeignFunctionItem(Box::new(Function { decl, generics }), safety)
|
||||
}
|
||||
hir::ForeignItemKind::Static(ty, mutability, safety) => ForeignStaticItem(
|
||||
Static { type_: clean_ty(ty, cx), mutability, expr: None },
|
||||
Static { type_: Box::new(clean_ty(ty, cx)), mutability, expr: None },
|
||||
safety,
|
||||
),
|
||||
hir::ForeignItemKind::Type => ForeignTypeItem,
|
||||
|
|
|
|||
|
|
@ -852,9 +852,9 @@ pub(crate) enum ItemKind {
|
|||
PrimitiveItem(PrimitiveType),
|
||||
/// A required associated constant in a trait declaration.
|
||||
TyAssocConstItem(Generics, Box<Type>),
|
||||
ConstantItem(Generics, Box<Type>, Constant),
|
||||
ConstantItem(Box<Constant>),
|
||||
/// An associated constant in a trait impl or a provided one in a trait declaration.
|
||||
AssocConstItem(Generics, Box<Type>, ConstantKind),
|
||||
AssocConstItem(Box<Constant>),
|
||||
/// A required associated type in a trait declaration.
|
||||
///
|
||||
/// The bounds may be non-empty if there is a `where` clause.
|
||||
|
|
@ -888,7 +888,7 @@ impl ItemKind {
|
|||
| TypeAliasItem(_)
|
||||
| OpaqueTyItem(_)
|
||||
| StaticItem(_)
|
||||
| ConstantItem(_, _, _)
|
||||
| ConstantItem(_)
|
||||
| TraitAliasItem(_)
|
||||
| TyMethodItem(_)
|
||||
| MethodItem(_, _)
|
||||
|
|
@ -922,7 +922,7 @@ impl ItemKind {
|
|||
| TypeAliasItem(_)
|
||||
| OpaqueTyItem(_)
|
||||
| StaticItem(_)
|
||||
| ConstantItem(_, _, _)
|
||||
| ConstantItem(_)
|
||||
| TraitAliasItem(_)
|
||||
| ForeignFunctionItem(_, _)
|
||||
| ForeignStaticItem(_, _)
|
||||
|
|
@ -2050,7 +2050,7 @@ impl From<hir::PrimTy> for PrimitiveType {
|
|||
pub(crate) struct Struct {
|
||||
pub(crate) ctor_kind: Option<CtorKind>,
|
||||
pub(crate) generics: Generics,
|
||||
pub(crate) fields: Vec<Item>,
|
||||
pub(crate) fields: ThinVec<Item>,
|
||||
}
|
||||
|
||||
impl Struct {
|
||||
|
|
@ -2076,7 +2076,7 @@ impl Union {
|
|||
/// only as a variant in an enum.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct VariantStruct {
|
||||
pub(crate) fields: Vec<Item>,
|
||||
pub(crate) fields: ThinVec<Item>,
|
||||
}
|
||||
|
||||
impl VariantStruct {
|
||||
|
|
@ -2110,7 +2110,7 @@ pub(crate) struct Variant {
|
|||
#[derive(Clone, Debug)]
|
||||
pub(crate) enum VariantKind {
|
||||
CLike,
|
||||
Tuple(Vec<Item>),
|
||||
Tuple(ThinVec<Item>),
|
||||
Struct(VariantStruct),
|
||||
}
|
||||
|
||||
|
|
@ -2246,7 +2246,7 @@ impl Path {
|
|||
pub(crate) enum GenericArg {
|
||||
Lifetime(Lifetime),
|
||||
Type(Type),
|
||||
Const(Box<Constant>),
|
||||
Const(Box<ConstantKind>),
|
||||
Infer,
|
||||
}
|
||||
|
||||
|
|
@ -2359,20 +2359,22 @@ pub(crate) struct BareFunctionDecl {
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct Static {
|
||||
pub(crate) type_: Type,
|
||||
pub(crate) type_: Box<Type>,
|
||||
pub(crate) mutability: Mutability,
|
||||
pub(crate) expr: Option<BodyId>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub(crate) struct Constant {
|
||||
pub(crate) generics: Generics,
|
||||
pub(crate) kind: ConstantKind,
|
||||
pub(crate) type_: Type,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub(crate) enum Term {
|
||||
Type(Type),
|
||||
Constant(Constant),
|
||||
Constant(ConstantKind),
|
||||
}
|
||||
|
||||
impl Term {
|
||||
|
|
@ -2594,7 +2596,7 @@ mod size_asserts {
|
|||
static_assert_size!(GenericParamDef, 40);
|
||||
static_assert_size!(Generics, 16);
|
||||
static_assert_size!(Item, 56);
|
||||
static_assert_size!(ItemKind, 56);
|
||||
static_assert_size!(ItemKind, 48);
|
||||
static_assert_size!(PathSegment, 40);
|
||||
static_assert_size!(Type, 32);
|
||||
// tidy-alphabetical-end
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ pub(crate) trait DocFolder: Sized {
|
|||
| FunctionItem(_)
|
||||
| OpaqueTyItem(_)
|
||||
| StaticItem(_)
|
||||
| ConstantItem(_, _, _)
|
||||
| ConstantItem(..)
|
||||
| TraitAliasItem(_)
|
||||
| TyMethodItem(_)
|
||||
| MethodItem(_, _)
|
||||
|
|
|
|||
|
|
@ -375,7 +375,7 @@ impl clean::Lifetime {
|
|||
}
|
||||
}
|
||||
|
||||
impl clean::Constant {
|
||||
impl clean::ConstantKind {
|
||||
pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl Display + '_ {
|
||||
let expr = self.expr(tcx);
|
||||
display_fn(
|
||||
|
|
|
|||
|
|
@ -1090,22 +1090,26 @@ fn render_assoc_item(
|
|||
clean::MethodItem(m, _) => {
|
||||
assoc_method(w, item, &m.generics, &m.decl, link, parent, cx, render_mode)
|
||||
}
|
||||
kind @ (clean::TyAssocConstItem(generics, ty) | clean::AssocConstItem(generics, ty, _)) => {
|
||||
assoc_const(
|
||||
w,
|
||||
item,
|
||||
generics,
|
||||
ty,
|
||||
match kind {
|
||||
clean::TyAssocConstItem(..) => None,
|
||||
clean::AssocConstItem(.., default) => Some(default),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
link,
|
||||
if parent == ItemType::Trait { 4 } else { 0 },
|
||||
cx,
|
||||
)
|
||||
}
|
||||
clean::TyAssocConstItem(generics, ty) => assoc_const(
|
||||
w,
|
||||
item,
|
||||
generics,
|
||||
ty,
|
||||
None,
|
||||
link,
|
||||
if parent == ItemType::Trait { 4 } else { 0 },
|
||||
cx,
|
||||
),
|
||||
clean::AssocConstItem(ci) => assoc_const(
|
||||
w,
|
||||
item,
|
||||
&ci.generics,
|
||||
&ci.type_,
|
||||
Some(&ci.kind),
|
||||
link,
|
||||
if parent == ItemType::Trait { 4 } else { 0 },
|
||||
cx,
|
||||
),
|
||||
clean::TyAssocTypeItem(ref generics, ref bounds) => assoc_type(
|
||||
w,
|
||||
item,
|
||||
|
|
@ -1690,8 +1694,7 @@ fn render_impl(
|
|||
w.write_str("</h4></section>");
|
||||
}
|
||||
}
|
||||
kind @ (clean::TyAssocConstItem(generics, ty)
|
||||
| clean::AssocConstItem(generics, ty, _)) => {
|
||||
clean::TyAssocConstItem(generics, ty) => {
|
||||
let source_id = format!("{item_type}.{name}");
|
||||
let id = cx.derive_id(&source_id);
|
||||
write!(w, "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">");
|
||||
|
|
@ -1706,11 +1709,29 @@ fn render_impl(
|
|||
item,
|
||||
generics,
|
||||
ty,
|
||||
match kind {
|
||||
clean::TyAssocConstItem(..) => None,
|
||||
clean::AssocConstItem(.., default) => Some(default),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None,
|
||||
link.anchor(if trait_.is_some() { &source_id } else { &id }),
|
||||
0,
|
||||
cx,
|
||||
);
|
||||
w.write_str("</h4></section>");
|
||||
}
|
||||
clean::AssocConstItem(ci) => {
|
||||
let source_id = format!("{item_type}.{name}");
|
||||
let id = cx.derive_id(&source_id);
|
||||
write!(w, "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">");
|
||||
render_rightside(w, cx, item, render_mode);
|
||||
if trait_.is_some() {
|
||||
// Anchors are only used on trait impls.
|
||||
write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>");
|
||||
}
|
||||
w.write_str("<h4 class=\"code-header\">");
|
||||
assoc_const(
|
||||
w,
|
||||
item,
|
||||
&ci.generics,
|
||||
&ci.type_,
|
||||
Some(&ci.kind),
|
||||
link.anchor(if trait_.is_some() { &source_id } else { &id }),
|
||||
0,
|
||||
cx,
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ pub(super) fn print_item(cx: &mut Context<'_>, item: &clean::Item, buf: &mut Buf
|
|||
clean::PrimitiveItem(_) => item_primitive(buf, cx, item),
|
||||
clean::StaticItem(ref i) => item_static(buf, cx, item, i, None),
|
||||
clean::ForeignStaticItem(ref i, safety) => item_static(buf, cx, item, i, Some(*safety)),
|
||||
clean::ConstantItem(generics, ty, c) => item_constant(buf, cx, item, generics, ty, c),
|
||||
clean::ConstantItem(ci) => item_constant(buf, cx, item, &ci.generics, &ci.type_, &ci.kind),
|
||||
clean::ForeignTypeItem => item_foreign_type(buf, cx, item),
|
||||
clean::KeywordItem => item_keyword(buf, cx, item),
|
||||
clean::OpaqueTyItem(ref e) => item_opaque_ty(buf, cx, item, e),
|
||||
|
|
@ -1841,7 +1841,7 @@ fn item_constant(
|
|||
it: &clean::Item,
|
||||
generics: &clean::Generics,
|
||||
ty: &clean::Type,
|
||||
c: &clean::Constant,
|
||||
c: &clean::ConstantKind,
|
||||
) {
|
||||
wrap_item(w, |w| {
|
||||
let tcx = cx.tcx();
|
||||
|
|
@ -1911,7 +1911,7 @@ fn item_fields(
|
|||
w: &mut Buffer,
|
||||
cx: &mut Context<'_>,
|
||||
it: &clean::Item,
|
||||
fields: &Vec<clean::Item>,
|
||||
fields: &[clean::Item],
|
||||
ctor_kind: Option<CtorKind>,
|
||||
) {
|
||||
let mut fields = fields
|
||||
|
|
|
|||
|
|
@ -188,6 +188,16 @@ impl FromWithTcx<clean::Constant> for Constant {
|
|||
}
|
||||
}
|
||||
|
||||
impl FromWithTcx<clean::ConstantKind> for Constant {
|
||||
// FIXME(generic_const_items): Add support for generic const items.
|
||||
fn from_tcx(constant: clean::ConstantKind, tcx: TyCtxt<'_>) -> Self {
|
||||
let expr = constant.expr(tcx);
|
||||
let value = constant.value(tcx);
|
||||
let is_literal = constant.is_literal(tcx);
|
||||
Constant { expr, value, is_literal }
|
||||
}
|
||||
}
|
||||
|
||||
impl FromWithTcx<clean::AssocItemConstraint> for TypeBinding {
|
||||
fn from_tcx(constraint: clean::AssocItemConstraint, tcx: TyCtxt<'_>) -> Self {
|
||||
TypeBinding {
|
||||
|
|
@ -325,8 +335,8 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
|
|||
TypeAliasItem(t) => ItemEnum::TypeAlias(t.into_tcx(tcx)),
|
||||
OpaqueTyItem(t) => ItemEnum::OpaqueTy(t.into_tcx(tcx)),
|
||||
// FIXME(generic_const_items): Add support for generic free consts
|
||||
ConstantItem(_generics, t, c) => {
|
||||
ItemEnum::Constant { type_: (*t).into_tcx(tcx), const_: c.into_tcx(tcx) }
|
||||
ConstantItem(ci) => {
|
||||
ItemEnum::Constant { type_: ci.type_.into_tcx(tcx), const_: ci.kind.into_tcx(tcx) }
|
||||
}
|
||||
MacroItem(m) => ItemEnum::Macro(m.source),
|
||||
ProcMacroItem(m) => ItemEnum::ProcMacro(m.into_tcx(tcx)),
|
||||
|
|
@ -341,8 +351,8 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
|
|||
ItemEnum::AssocConst { type_: (*ty).into_tcx(tcx), default: None }
|
||||
}
|
||||
// FIXME(generic_const_items): Add support for generic associated consts.
|
||||
AssocConstItem(_generics, ty, default) => {
|
||||
ItemEnum::AssocConst { type_: (*ty).into_tcx(tcx), default: Some(default.expr(tcx)) }
|
||||
AssocConstItem(ci) => {
|
||||
ItemEnum::AssocConst { type_: ci.type_.into_tcx(tcx), default: Some(ci.kind.expr(tcx)) }
|
||||
}
|
||||
TyAssocTypeItem(g, b) => ItemEnum::AssocType {
|
||||
generics: g.into_tcx(tcx),
|
||||
|
|
@ -829,7 +839,7 @@ impl FromWithTcx<clean::OpaqueTy> for OpaqueTy {
|
|||
impl FromWithTcx<clean::Static> for Static {
|
||||
fn from_tcx(stat: clean::Static, tcx: TyCtxt<'_>) -> Self {
|
||||
Static {
|
||||
type_: stat.type_.into_tcx(tcx),
|
||||
type_: (*stat.type_).into_tcx(tcx),
|
||||
mutable: stat.mutability == ast::Mutability::Mut,
|
||||
expr: stat
|
||||
.expr
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -
|
|||
| clean::AssocTypeItem(..)
|
||||
| clean::TypeAliasItem(_)
|
||||
| clean::StaticItem(_)
|
||||
| clean::ConstantItem(_, _, _)
|
||||
| clean::ConstantItem(..)
|
||||
| clean::ExternCrateItem { .. }
|
||||
| clean::ImportItem(_)
|
||||
| clean::PrimitiveItem(_)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ pub(crate) trait DocVisitor: Sized {
|
|||
| TypeAliasItem(_)
|
||||
| OpaqueTyItem(_)
|
||||
| StaticItem(_)
|
||||
| ConstantItem(_, _, _)
|
||||
| ConstantItem(..)
|
||||
| TraitAliasItem(_)
|
||||
| TyMethodItem(_)
|
||||
| MethodItem(_, _)
|
||||
|
|
|
|||
|
|
@ -661,6 +661,20 @@ dependencies = [
|
|||
"textwrap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mdbook-spec"
|
||||
version = "0.1.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"mdbook",
|
||||
"once_cell",
|
||||
"pathdiff",
|
||||
"regex",
|
||||
"semver",
|
||||
"serde_json",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mdbook-trpl-listing"
|
||||
version = "0.1.0"
|
||||
|
|
@ -794,6 +808,12 @@ dependencies = [
|
|||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathdiff"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
|
|
@ -1079,6 +1099,7 @@ dependencies = [
|
|||
"env_logger",
|
||||
"mdbook",
|
||||
"mdbook-i18n-helpers",
|
||||
"mdbook-spec",
|
||||
"mdbook-trpl-listing",
|
||||
"mdbook-trpl-note",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ env_logger = "0.11"
|
|||
mdbook-trpl-listing = { path = "../../doc/book/packages/mdbook-trpl-listing" }
|
||||
mdbook-trpl-note = { path = "../../doc/book/packages/mdbook-trpl-note" }
|
||||
mdbook-i18n-helpers = "0.3.3"
|
||||
mdbook-spec = { path = "../../doc/reference/mdbook-spec"}
|
||||
|
||||
[dependencies.mdbook]
|
||||
version = "0.4.37"
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use mdbook::errors::Result as Result3;
|
|||
use mdbook::MDBook;
|
||||
use mdbook_i18n_helpers::preprocessors::Gettext;
|
||||
|
||||
use mdbook_spec::Spec;
|
||||
use mdbook_trpl_listing::TrplListing;
|
||||
use mdbook_trpl_note::TrplNote;
|
||||
|
||||
|
|
@ -83,6 +84,13 @@ pub fn build(args: &ArgMatches) -> Result3<()> {
|
|||
book.config.build.build_dir = dest_dir.into();
|
||||
}
|
||||
|
||||
// NOTE: Replacing preprocessors using this technique causes error
|
||||
// messages to be displayed when the original preprocessor doesn't work
|
||||
// (but it otherwise succeeds).
|
||||
//
|
||||
// This should probably be fixed in mdbook to remove the existing
|
||||
// preprocessor, or this should modify the config and use
|
||||
// MDBook::load_with_config.
|
||||
if book.config.get_preprocessor("trpl-note").is_some() {
|
||||
book.with_preprocessor(TrplNote);
|
||||
}
|
||||
|
|
@ -91,6 +99,10 @@ pub fn build(args: &ArgMatches) -> Result3<()> {
|
|||
book.with_preprocessor(TrplListing);
|
||||
}
|
||||
|
||||
if book.config.get_preprocessor("spec").is_some() {
|
||||
book.with_preprocessor(Spec::new());
|
||||
}
|
||||
|
||||
book.build()?;
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ pub(crate) const WORKSPACES: &[(&str, ExceptionList, Option<(&[&str], &[&str])>,
|
|||
//("src/tools/miri/test-cargo-miri", &[], None), // FIXME uncomment once all deps are vendored
|
||||
//("src/tools/miri/test_dependencies", &[], None), // FIXME uncomment once all deps are vendored
|
||||
("src/tools/rust-analyzer", EXCEPTIONS_RUST_ANALYZER, None, &[]),
|
||||
("src/tools/rustbook", EXCEPTIONS_RUSTBOOK, None, &["src/doc/book"]),
|
||||
("src/tools/rustbook", EXCEPTIONS_RUSTBOOK, None, &["src/doc/book", "src/doc/reference"]),
|
||||
("src/tools/rustc-perf", EXCEPTIONS_RUSTC_PERF, None, &["src/tools/rustc-perf"]),
|
||||
("src/tools/x", &[], None, &[]),
|
||||
// tidy-alphabetical-end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
//@ revisions: e2021 e2024
|
||||
//@[e2021] edition: 2021
|
||||
//@[e2024] edition: 2024
|
||||
//@[e2024] compile-flags: -Zunstable-options
|
||||
//@ check-pass
|
||||
|
||||
#![deny(rust_2024_prelude_collisions)]
|
||||
|
||||
use std::future::Future;
|
||||
|
||||
fn main() {
|
||||
core::pin::pin!(async {}).poll(&mut context());
|
||||
}
|
||||
|
||||
fn context() -> core::task::Context<'static> {
|
||||
loop {}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
//@ revisions: e2021 e2024
|
||||
//@[e2021] edition: 2021
|
||||
//@[e2021] run-rustfix
|
||||
//@[e2024] edition: 2024
|
||||
//@[e2024] compile-flags: -Zunstable-options
|
||||
//@[e2024] check-pass
|
||||
|
||||
#![deny(rust_2024_prelude_collisions)]
|
||||
trait Meow {
|
||||
fn poll(&self, _ctx: &mut core::task::Context<'_>) {}
|
||||
}
|
||||
impl<T> Meow for T {}
|
||||
fn main() {
|
||||
Meow::poll(&core::pin::pin!(async {}), &mut context());
|
||||
//[e2021]~^ ERROR trait method `poll` will become ambiguous in Rust 2024
|
||||
//[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
|
||||
}
|
||||
|
||||
fn context() -> core::task::Context<'static> {
|
||||
loop {}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
error: trait method `poll` will become ambiguous in Rust 2024
|
||||
--> $DIR/future-poll-async-block.rs:14:5
|
||||
|
|
||||
LL | core::pin::pin!(async {}).poll(&mut context());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::poll(&core::pin::pin!(async {}), &mut context())`
|
||||
|
|
||||
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>
|
||||
note: the lint level is defined here
|
||||
--> $DIR/future-poll-async-block.rs:8:9
|
||||
|
|
||||
LL | #![deny(rust_2024_prelude_collisions)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
//@ revisions: e2021 e2024
|
||||
//@[e2021] edition: 2021
|
||||
//@[e2021] run-rustfix
|
||||
//@[e2024] edition: 2024
|
||||
//@[e2024] compile-flags: -Zunstable-options
|
||||
//@[e2024] check-pass
|
||||
|
||||
#![deny(rust_2024_prelude_collisions)]
|
||||
trait Meow {
|
||||
fn poll(&self, _ctx: &mut core::task::Context<'_>) {}
|
||||
}
|
||||
impl<T> Meow for T {}
|
||||
fn main() {
|
||||
core::pin::pin!(async {}).poll(&mut context());
|
||||
//[e2021]~^ ERROR trait method `poll` will become ambiguous in Rust 2024
|
||||
//[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
|
||||
}
|
||||
|
||||
fn context() -> core::task::Context<'static> {
|
||||
loop {}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
//@ revisions: e2021 e2024
|
||||
//@[e2021] edition: 2021
|
||||
//@[e2021] run-rustfix
|
||||
//@[e2024] edition: 2024
|
||||
//@[e2024] compile-flags: -Zunstable-options
|
||||
//@[e2024] check-pass
|
||||
|
||||
#![deny(rust_2024_prelude_collisions)]
|
||||
trait Meow {
|
||||
fn poll(&self) {}
|
||||
}
|
||||
impl<T> Meow for T {}
|
||||
fn main() {
|
||||
// This is a deliberate false positive.
|
||||
// While `()` does not implement `Future` and can therefore not be ambiguous, we
|
||||
// do not check that in the lint, as that introduces additional complexities.
|
||||
// Just checking whether the self type is `Pin<&mut _>` is enough.
|
||||
Meow::poll(&core::pin::pin!(()));
|
||||
//[e2021]~^ ERROR trait method `poll` will become ambiguous in Rust 2024
|
||||
//[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
error: trait method `poll` will become ambiguous in Rust 2024
|
||||
--> $DIR/future-poll-not-future-pinned.rs:18:5
|
||||
|
|
||||
LL | core::pin::pin!(()).poll();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::poll(&core::pin::pin!(()))`
|
||||
|
|
||||
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>
|
||||
note: the lint level is defined here
|
||||
--> $DIR/future-poll-not-future-pinned.rs:8:9
|
||||
|
|
||||
LL | #![deny(rust_2024_prelude_collisions)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
//@ revisions: e2021 e2024
|
||||
//@[e2021] edition: 2021
|
||||
//@[e2021] run-rustfix
|
||||
//@[e2024] edition: 2024
|
||||
//@[e2024] compile-flags: -Zunstable-options
|
||||
//@[e2024] check-pass
|
||||
|
||||
#![deny(rust_2024_prelude_collisions)]
|
||||
trait Meow {
|
||||
fn poll(&self) {}
|
||||
}
|
||||
impl<T> Meow for T {}
|
||||
fn main() {
|
||||
// This is a deliberate false positive.
|
||||
// While `()` does not implement `Future` and can therefore not be ambiguous, we
|
||||
// do not check that in the lint, as that introduces additional complexities.
|
||||
// Just checking whether the self type is `Pin<&mut _>` is enough.
|
||||
core::pin::pin!(()).poll();
|
||||
//[e2021]~^ ERROR trait method `poll` will become ambiguous in Rust 2024
|
||||
//[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
//@ revisions: e2021 e2024
|
||||
//@[e2021] edition: 2021
|
||||
//@[e2024] edition: 2024
|
||||
//@[e2024] compile-flags: -Zunstable-options
|
||||
//@ check-pass
|
||||
|
||||
#![deny(rust_2024_prelude_collisions)]
|
||||
trait Meow {
|
||||
fn poll(&self) {}
|
||||
}
|
||||
impl<T> Meow for T {}
|
||||
fn main() {
|
||||
// As the self type here is not `Pin<&mut _>`, the lint does not fire.
|
||||
().poll();
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
//@ edition: 2021
|
||||
|
||||
#![deny(rust_2024_compatibility)]
|
||||
|
||||
trait Meow {
|
||||
fn poll(&self, _ctx: &mut core::task::Context<'_>) {}
|
||||
}
|
||||
impl<T> Meow for T {}
|
||||
fn main() {
|
||||
core::pin::pin!(async {}).poll(&mut context());
|
||||
//~^ ERROR trait method `poll` will become ambiguous in Rust 2024
|
||||
//~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
|
||||
}
|
||||
|
||||
fn context() -> core::task::Context<'static> {
|
||||
loop {}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
error: trait method `poll` will become ambiguous in Rust 2024
|
||||
--> $DIR/in_2024_compatibility.rs:10:5
|
||||
|
|
||||
LL | core::pin::pin!(async {}).poll(&mut context());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::poll(&core::pin::pin!(async {}), &mut context())`
|
||||
|
|
||||
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>
|
||||
note: the lint level is defined here
|
||||
--> $DIR/in_2024_compatibility.rs:3:9
|
||||
|
|
||||
LL | #![deny(rust_2024_compatibility)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: `#[deny(rust_2024_prelude_collisions)]` implied by `#[deny(rust_2024_compatibility)]`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
//@ revisions: e2021 e2024
|
||||
//@[e2021] edition: 2021
|
||||
//@[e2021] run-rustfix
|
||||
//@[e2024] edition: 2024
|
||||
//@[e2024] compile-flags: -Zunstable-options
|
||||
//@[e2024] check-pass
|
||||
|
||||
#![deny(rust_2024_prelude_collisions)]
|
||||
trait Meow {
|
||||
fn into_future(&self) {}
|
||||
}
|
||||
impl Meow for Cat {}
|
||||
|
||||
struct Cat;
|
||||
|
||||
impl core::future::IntoFuture for Cat {
|
||||
type Output = ();
|
||||
type IntoFuture = core::future::Ready<()>;
|
||||
|
||||
fn into_future(self) -> Self::IntoFuture {
|
||||
core::future::ready(())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
Meow::into_future(&Cat);
|
||||
//[e2021]~^ ERROR trait method `into_future` will become ambiguous in Rust 2024
|
||||
//[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
error: trait method `into_future` will become ambiguous in Rust 2024
|
||||
--> $DIR/into-future-adt.rs:26:5
|
||||
|
|
||||
LL | Cat.into_future();
|
||||
| ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::into_future(&Cat)`
|
||||
|
|
||||
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>
|
||||
note: the lint level is defined here
|
||||
--> $DIR/into-future-adt.rs:8:9
|
||||
|
|
||||
LL | #![deny(rust_2024_prelude_collisions)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
29
tests/ui/rust-2024/prelude-migration/into-future-adt.rs
Normal file
29
tests/ui/rust-2024/prelude-migration/into-future-adt.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
//@ revisions: e2021 e2024
|
||||
//@[e2021] edition: 2021
|
||||
//@[e2021] run-rustfix
|
||||
//@[e2024] edition: 2024
|
||||
//@[e2024] compile-flags: -Zunstable-options
|
||||
//@[e2024] check-pass
|
||||
|
||||
#![deny(rust_2024_prelude_collisions)]
|
||||
trait Meow {
|
||||
fn into_future(&self) {}
|
||||
}
|
||||
impl Meow for Cat {}
|
||||
|
||||
struct Cat;
|
||||
|
||||
impl core::future::IntoFuture for Cat {
|
||||
type Output = ();
|
||||
type IntoFuture = core::future::Ready<()>;
|
||||
|
||||
fn into_future(self) -> Self::IntoFuture {
|
||||
core::future::ready(())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
Cat.into_future();
|
||||
//[e2021]~^ ERROR trait method `into_future` will become ambiguous in Rust 2024
|
||||
//[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
//@ revisions: e2021 e2024
|
||||
//@[e2021] edition: 2021
|
||||
//@[e2024] edition: 2024
|
||||
//@[e2024] compile-flags: -Zunstable-options
|
||||
//@ check-pass
|
||||
|
||||
#![deny(rust_2024_prelude_collisions)]
|
||||
|
||||
use core::future::IntoFuture;
|
||||
|
||||
struct Cat;
|
||||
|
||||
impl IntoFuture for Cat {
|
||||
type Output = ();
|
||||
type IntoFuture = core::future::Ready<()>;
|
||||
|
||||
fn into_future(self) -> Self::IntoFuture {
|
||||
core::future::ready(())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = Cat.into_future();
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
//@ revisions: e2021 e2024
|
||||
//@[e2021] edition: 2021
|
||||
//@[e2021] run-rustfix
|
||||
//@[e2024] edition: 2024
|
||||
//@[e2024] compile-flags: -Zunstable-options
|
||||
//@[e2024] check-pass
|
||||
|
||||
#![deny(rust_2024_prelude_collisions)]
|
||||
trait Meow {
|
||||
fn into_future(&self) {}
|
||||
}
|
||||
impl Meow for Cat {}
|
||||
|
||||
struct Cat;
|
||||
|
||||
fn main() {
|
||||
// This is a false positive, but it should be rare enough to not matter, and checking whether
|
||||
// it implements the trait can have other nontrivial consequences, so it was decided to accept
|
||||
// this.
|
||||
Meow::into_future(&Cat);
|
||||
//[e2021]~^ ERROR trait method `into_future` will become ambiguous in Rust 2024
|
||||
//[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
error: trait method `into_future` will become ambiguous in Rust 2024
|
||||
--> $DIR/into-future-not-into-future.rs:20:5
|
||||
|
|
||||
LL | Cat.into_future();
|
||||
| ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::into_future(&Cat)`
|
||||
|
|
||||
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>
|
||||
note: the lint level is defined here
|
||||
--> $DIR/into-future-not-into-future.rs:8:9
|
||||
|
|
||||
LL | #![deny(rust_2024_prelude_collisions)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
//@ revisions: e2021 e2024
|
||||
//@[e2021] edition: 2021
|
||||
//@[e2021] run-rustfix
|
||||
//@[e2024] edition: 2024
|
||||
//@[e2024] compile-flags: -Zunstable-options
|
||||
//@[e2024] check-pass
|
||||
|
||||
#![deny(rust_2024_prelude_collisions)]
|
||||
trait Meow {
|
||||
fn into_future(&self) {}
|
||||
}
|
||||
impl Meow for Cat {}
|
||||
|
||||
struct Cat;
|
||||
|
||||
fn main() {
|
||||
// This is a false positive, but it should be rare enough to not matter, and checking whether
|
||||
// it implements the trait can have other nontrivial consequences, so it was decided to accept
|
||||
// this.
|
||||
Cat.into_future();
|
||||
//[e2021]~^ ERROR trait method `into_future` will become ambiguous in Rust 2024
|
||||
//[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue