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_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, ) } 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/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:" 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-ui/doctest/doctest-no-run-invalid-langstring-124577.rs b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.rs new file mode 100644 index 0000000000000..571bc94e30f98 --- /dev/null +++ b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.rs @@ -0,0 +1,12 @@ +//@ compile-flags:--test +//@ check-pass +#![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; 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 + 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`.