From b2a7713ae384789733f0919886cd5ea890b0cf20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 21 Aug 2024 03:17:47 +0000 Subject: [PATCH 1/6] Emit specific message for `time<0.3.35` inference failure ``` error[E0282]: type annotations needed for `Box<_>` --> ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/time-0.3.34/src/format_description/parse/mod.rs:83:9 | 83 | let items = format_items | ^^^^^ ... 86 | Ok(items.into()) | ---- type must be known at this point | = note: this is an inference error on crate `time` caused by a change in Rust 1.80.0; update `time` to version `>=0.3.35` ``` Partially address #127343. (cherry picked from commit b013a3ddf0060b62ee8050e241f80d024c48cc59) --- compiler/rustc_infer/messages.ftl | 2 + compiler/rustc_infer/src/errors/mod.rs | 2 + .../rustc_infer/src/infer/need_type_info.rs | 46 ++++++++++++++++++- compiler/rustc_infer/src/lib.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + ...d-time-version-format_description-parse.rs | 8 ++++ ...me-version-format_description-parse.stderr | 11 +++++ 7 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 tests/ui/inference/detect-old-time-version-format_description-parse.rs create mode 100644 tests/ui/inference/detect-old-time-version-format_description-parse.stderr diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl index c279195a7e99c..b40c353f0775b 100644 --- a/compiler/rustc_infer/messages.ftl +++ b/compiler/rustc_infer/messages.ftl @@ -388,6 +388,8 @@ infer_type_annotations_needed = {$source_kind -> } .label = type must be known at this point +infer_type_annotations_needed_error_time = this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35` by calling `cargo update` + infer_types_declared_different = these two types are declared with different lifetimes... infer_warn_removing_apit_params = you could use a `use<...>` bound to explicitly capture `{$new_lifetime}`, but argument-position `impl Trait`s are not nameable diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 2ce712e0bff58..10b6ddeb1779f 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -54,6 +54,8 @@ pub struct AnnotationRequired<'a> { #[note(infer_full_type_written)] pub was_written: Option<()>, pub path: PathBuf, + #[note(infer_type_annotations_needed_error_time)] + pub time_version: bool, } // Copy of `AnnotationRequired` for E0283 diff --git a/compiler/rustc_infer/src/infer/need_type_info.rs b/compiler/rustc_infer/src/infer/need_type_info.rs index 4f3dcd9043fd0..4ac5b521926d3 100644 --- a/compiler/rustc_infer/src/infer/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/need_type_info.rs @@ -8,7 +8,7 @@ use rustc_errors::{codes::*, Diag, IntoDiagArg}; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def::{CtorOf, DefKind, Namespace}; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, LetStmt, LocalSource}; use rustc_middle::bug; @@ -21,7 +21,7 @@ use rustc_middle::ty::{ TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults, }; use rustc_span::symbol::{sym, Ident}; -use rustc_span::{BytePos, Span, DUMMY_SP}; +use rustc_span::{BytePos, FileName, Span, DUMMY_SP}; use std::borrow::Cow; use std::iter; use std::path::PathBuf; @@ -409,6 +409,7 @@ impl<'tcx> InferCtxt<'tcx> { bad_label, was_written: None, path: Default::default(), + time_version: false, }), TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl { span, @@ -604,6 +605,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } } + + let time_version = + self.detect_old_time_crate_version(failure_span, &kind, &mut infer_subdiags); + match error_code { TypeAnnotationNeeded::E0282 => self.dcx().create_err(AnnotationRequired { span, @@ -615,6 +620,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { bad_label: None, was_written: path.as_ref().map(|_| ()), path: path.unwrap_or_default(), + time_version, }), TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl { span, @@ -640,6 +646,42 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }), } } + + /// Detect the inference regression on crate `time` <= 0.3.35 and emit a more targeted error. + /// + // FIXME: we should figure out a more generic version of doing this, ideally in cargo itself. + fn detect_old_time_crate_version( + &self, + span: Option, + kind: &InferSourceKind<'_>, + // We will clear the non-actionable suggestion from the error to reduce noise. + infer_subdiags: &mut Vec>, + ) -> bool { + // FIXME(#129461): We are time-boxing this code in the compiler. It'll start failing + // compilation once we promote 1.89 to beta, which will happen in 9 months from now. + #[cfg(not(version("1.89")))] + const fn version_check() {} + #[cfg(version("1.89"))] + const fn version_check() { + panic!("remove this check as presumably the ecosystem has moved from needing it"); + } + const { version_check() }; + // Only relevant when building the `time` crate. + if self.infcx.tcx.crate_name(LOCAL_CRATE) == sym::time + && let Some(span) = span + && let InferSourceKind::LetBinding { pattern_name, .. } = kind + && let Some(name) = pattern_name + && name.as_str() == "items" + && let FileName::Real(file) = self.infcx.tcx.sess.source_map().span_to_filename(span) + { + let path = file.local_path_if_available().to_string_lossy(); + if path.contains("format_description") && path.contains("parse") { + infer_subdiags.clear(); + return true; + } + } + false + } } #[derive(Debug)] diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 02ebf933f5329..fc47f5c11b7a9 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -19,6 +19,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(box_patterns)] +#![feature(cfg_version)] #![feature(control_flow_enum)] #![feature(extend_one)] #![feature(if_let_guard)] diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index b64efadb2619e..99d80eda37473 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1883,6 +1883,7 @@ symbols! { three_way_compare, thumb2, thumb_mode: "thumb-mode", + time, tmm_reg, to_owned_method, to_string, diff --git a/tests/ui/inference/detect-old-time-version-format_description-parse.rs b/tests/ui/inference/detect-old-time-version-format_description-parse.rs new file mode 100644 index 0000000000000..453a795e7686b --- /dev/null +++ b/tests/ui/inference/detect-old-time-version-format_description-parse.rs @@ -0,0 +1,8 @@ +#![crate_name = "time"] + +fn main() { + let items = Box::new(vec![]); //~ ERROR E0282 + //~^ NOTE type must be known at this point + //~| NOTE this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35` + items.into(); +} diff --git a/tests/ui/inference/detect-old-time-version-format_description-parse.stderr b/tests/ui/inference/detect-old-time-version-format_description-parse.stderr new file mode 100644 index 0000000000000..2949a5dcfec9c --- /dev/null +++ b/tests/ui/inference/detect-old-time-version-format_description-parse.stderr @@ -0,0 +1,11 @@ +error[E0282]: type annotations needed for `Box>` + --> $DIR/detect-old-time-version-format_description-parse.rs:4:9 + | +LL | let items = Box::new(vec![]); + | ^^^^^ ---------------- type must be known at this point + | + = note: this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35` by calling `cargo update` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. From 1953a13a9e81e34eb0335d8d2ae8a53a7b7d0b11 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Wed, 28 Aug 2024 19:36:46 -0400 Subject: [PATCH 2/6] Use a reduced recursion limit in the MIR inliner's cycle breaker (cherry picked from commit 950437a035aa81cf2af3d8aebdf8d9b294c54395) --- compiler/rustc_mir_transform/src/inline/cycle.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index d4477563e3adb..9ef6b20e77a69 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -137,6 +137,14 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( } false } + // FIXME(-Znext-solver): Remove this hack when trait solver overflow can return an error. + // In code like that pointed out in #128887, the type complexity we ask the solver to deal with + // grows as we recurse into the call graph. If we use the same recursion limit here and in the + // solver, the solver hits the limit first and emits a fatal error. But if we use a reduced + // limit, we will hit the limit first and give up on looking for inlining. And in any case, + // the default recursion limits are quite generous for us. If we need to recurse 64 times + // into the call graph, we're probably not going to find any useful MIR inlining. + let recursion_limit = tcx.recursion_limit() / 2; process( tcx, param_env, @@ -145,7 +153,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( &mut Vec::new(), &mut FxHashSet::default(), &mut FxHashMap::default(), - tcx.recursion_limit(), + recursion_limit, ) } From cfb20bc74ebc828e7dd22bf6cf83aa654daa2732 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 8 Aug 2024 11:36:48 -0700 Subject: [PATCH 3/6] rustdoc: do not run doctests with invalid langstrings (cherry picked from commit 7c4150fce0510218304b726174029fbb2c33ee03) --- src/librustdoc/html/markdown.rs | 20 +++++++++++++++---- src/librustdoc/html/markdown/tests.rs | 6 +++--- ...octest-no-run-invalid-langstring-124577.rs | 11 ++++++++++ 3 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 tests/rustdoc/doctest/doctest-no-run-invalid-langstring-124577.rs diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index a7f0df5afa98f..e9fc3a3ffcee8 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -925,6 +925,7 @@ pub(crate) struct TagIterator<'a, 'tcx> { data: &'a str, is_in_attribute_block: bool, extra: Option<&'a ExtraInfo<'tcx>>, + is_error: bool, } #[derive(Clone, Debug, Eq, PartialEq)] @@ -951,13 +952,20 @@ struct Indices { impl<'a, 'tcx> TagIterator<'a, 'tcx> { pub(crate) fn new(data: &'a str, extra: Option<&'a ExtraInfo<'tcx>>) -> Self { - Self { inner: data.char_indices().peekable(), data, is_in_attribute_block: false, extra } + Self { + inner: data.char_indices().peekable(), + data, + is_in_attribute_block: false, + extra, + is_error: false, + } } - fn emit_error(&self, err: impl Into) { + fn emit_error(&mut self, err: impl Into) { if let Some(extra) = self.extra { extra.error_invalid_codeblock_attr(err); } + self.is_error = true; } fn skip_separators(&mut self) -> Option { @@ -1155,6 +1163,9 @@ impl<'a, 'tcx> Iterator for TagIterator<'a, 'tcx> { type Item = LangStringToken<'a>; fn next(&mut self) -> Option { + if self.is_error { + return None; + } let Some(start) = self.skip_separators() else { if self.is_in_attribute_block { self.emit_error("unclosed attribute block (`{}`): missing `}` at the end"); @@ -1343,14 +1354,15 @@ impl LangString { } }; - call(&mut TagIterator::new(string, extra)); + let mut tag_iter = TagIterator::new(string, extra); + call(&mut tag_iter); // ignore-foo overrides ignore if !ignores.is_empty() { data.ignore = Ignore::Some(ignores); } - data.rust &= !seen_custom_tag && (!seen_other_tags || seen_rust_tags); + data.rust &= !seen_custom_tag && (!seen_other_tags || seen_rust_tags) && !tag_iter.is_error; data } diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index fb74c079c9a4e..23da2f0cc7fb4 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -61,7 +61,7 @@ fn test_lang_string_parse() { ..Default::default() }); // error - t(LangString { original: "{rust}".into(), rust: true, ..Default::default() }); + t(LangString { original: "{rust}".into(), rust: false, ..Default::default() }); t(LangString { original: "{.rust}".into(), rust: true, @@ -233,7 +233,7 @@ fn test_lang_string_parse() { ..Default::default() }); // error - t(LangString { original: "{class=first=second}".into(), rust: true, ..Default::default() }); + t(LangString { original: "{class=first=second}".into(), rust: false, ..Default::default() }); // error t(LangString { original: "{class=first.second}".into(), @@ -261,7 +261,7 @@ fn test_lang_string_parse() { ..Default::default() }); // error - t(LangString { original: r#"{class=f"irst"}"#.into(), rust: true, ..Default::default() }); + t(LangString { original: r#"{class=f"irst"}"#.into(), rust: false, ..Default::default() }); } #[test] diff --git a/tests/rustdoc/doctest/doctest-no-run-invalid-langstring-124577.rs b/tests/rustdoc/doctest/doctest-no-run-invalid-langstring-124577.rs new file mode 100644 index 0000000000000..b3e993e8ee939 --- /dev/null +++ b/tests/rustdoc/doctest/doctest-no-run-invalid-langstring-124577.rs @@ -0,0 +1,11 @@ +//@ compile-flags:--test +#![allow(rustdoc::invalid_codeblock_attributes)] + +// https://github.com/rust-lang/rust/pull/124577#issuecomment-2276034737 + +// Test that invalid langstrings don't get run. + +/// ```{rust,ignore} +/// panic!(); +/// ``` +pub struct Foo; From 6f593122b26e574e833c5876ea922c52d5c695cb Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 9 Aug 2024 07:57:46 -0700 Subject: [PATCH 4/6] rustdoc: move invalid langstring test to UI (cherry picked from commit 1d19c2c009529fff08a95cbe548bcb1a6e02651c) --- .../doctest/doctest-no-run-invalid-langstring-124577.rs | 1 + .../doctest/doctest-no-run-invalid-langstring-124577.stdout | 5 +++++ 2 files changed, 6 insertions(+) rename tests/{rustdoc => rustdoc-ui}/doctest/doctest-no-run-invalid-langstring-124577.rs (94%) create mode 100644 tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.stdout diff --git a/tests/rustdoc/doctest/doctest-no-run-invalid-langstring-124577.rs b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.rs similarity index 94% rename from tests/rustdoc/doctest/doctest-no-run-invalid-langstring-124577.rs rename to tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.rs index b3e993e8ee939..571bc94e30f98 100644 --- a/tests/rustdoc/doctest/doctest-no-run-invalid-langstring-124577.rs +++ b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.rs @@ -1,4 +1,5 @@ //@ compile-flags:--test +//@ check-pass #![allow(rustdoc::invalid_codeblock_attributes)] // https://github.com/rust-lang/rust/pull/124577#issuecomment-2276034737 diff --git a/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.stdout b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.stdout new file mode 100644 index 0000000000000..e5c27bebbdb23 --- /dev/null +++ b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.stdout @@ -0,0 +1,5 @@ + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + From 361a050c0029583b9edb6ddbf53a62643500afc3 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Fri, 30 Aug 2024 18:03:04 -0700 Subject: [PATCH 5/6] ci: Use mv instead of cp in upload step --- src/ci/scripts/upload-artifacts.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ci/scripts/upload-artifacts.sh b/src/ci/scripts/upload-artifacts.sh index c9c85ec20b45a..587b324ce10e5 100755 --- a/src/ci/scripts/upload-artifacts.sh +++ b/src/ci/scripts/upload-artifacts.sh @@ -19,18 +19,18 @@ fi if [[ "${DEPLOY-0}" -eq "1" ]] || [[ "${DEPLOY_ALT-0}" -eq "1" ]]; then dist_dir="${build_dir}/dist" rm -rf "${dist_dir}/doc" - cp -r "${dist_dir}"/* "${upload_dir}" + mv "${dist_dir}"/* "${upload_dir}" fi # CPU usage statistics. -cp build/cpu-usage.csv "${upload_dir}/cpu-${CI_JOB_NAME}.csv" +mv build/cpu-usage.csv "${upload_dir}/cpu-${CI_JOB_NAME}.csv" # Build metrics generated by x.py. -cp "${build_dir}/metrics.json" "${upload_dir}/metrics-${CI_JOB_NAME}.json" +mv "${build_dir}/metrics.json" "${upload_dir}/metrics-${CI_JOB_NAME}.json" # Toolstate data. if [[ -n "${DEPLOY_TOOLSTATES_JSON+x}" ]]; then - cp /tmp/toolstate/toolstates.json "${upload_dir}/${DEPLOY_TOOLSTATES_JSON}" + mv /tmp/toolstate/toolstates.json "${upload_dir}/${DEPLOY_TOOLSTATES_JSON}" fi echo "Files that will be uploaded:" From a4461dfb58cdcdac0480562dfe4d9e6391e5f517 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Fri, 30 Aug 2024 18:02:03 -0700 Subject: [PATCH 6/6] ci: Try to remove unused Xcode dirs --- src/ci/scripts/select-xcode.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/ci/scripts/select-xcode.sh b/src/ci/scripts/select-xcode.sh index 569c4a4136d97..d635d4384727f 100755 --- a/src/ci/scripts/select-xcode.sh +++ b/src/ci/scripts/select-xcode.sh @@ -1,5 +1,6 @@ #!/bin/bash # This script selects the Xcode instance to use. +# It also tries to do some cleanup in CI jobs of unused Xcodes. set -euo pipefail IFS=$'\n\t' @@ -7,5 +8,21 @@ IFS=$'\n\t' source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" if isMacOS; then + # This additional step is to try to remove an Xcode we aren't using because each one is HUGE + old_xcode="$(xcode-select --print-path)" + old_xcode="${old_xcode%/*}" # pop a dir + old_xcode="${old_xcode%/*}" # twice + if [[ $old_xcode =~ $SELECT_XCODE ]]; then + echo "xcode-select.sh's brutal hack may not be necessary?" + exit 1 + elif [[ $SELECT_XCODE =~ "16" ]]; then + echo "Using Xcode 16? Please fix xcode-select.sh" + exit 1 + fi + if [ $CI ]; then # just in case someone sources this on their real computer + sudo rm -rf "${old_xcode}" + xcode_16="${old_xcode%/*}/Xcode-16.0.0.app" + sudo rm -rf "${xcode_16}" + fi sudo xcode-select -s "${SELECT_XCODE}" fi