summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-08-31 23:26:29 +0000
committerbors <bors@rust-lang.org>2024-08-31 23:26:29 +0000
commit4a101b4b5db701edee2b705d1cc1c58c6058c43f (patch)
tree622607bf45b10c9eeb77525865c283e4493e873e
parent4a765c0b8754bdbc1d841d080e8c8a47ea774a80 (diff)
parenta4461dfb58cdcdac0480562dfe4d9e6391e5f517 (diff)
Auto merge of #129758 - cuviper:beta-next, r=cuviper
[beta] backports - Emit specific message for `time<0.3.35` inference failure #129343 - Use a reduced recursion limit in the MIR inliner's cycle breaker #129714 - rustdoc: do not run doctests with invalid langstrings #128838 r? cuviper
-rw-r--r--compiler/rustc_infer/messages.ftl2
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/need_type_info.rs46
-rw-r--r--compiler/rustc_infer/src/lib.rs1
-rw-r--r--compiler/rustc_mir_transform/src/inline/cycle.rs10
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rwxr-xr-xsrc/ci/scripts/select-xcode.sh17
-rwxr-xr-xsrc/ci/scripts/upload-artifacts.sh8
-rw-r--r--src/librustdoc/html/markdown.rs20
-rw-r--r--src/librustdoc/html/markdown/tests.rs6
-rw-r--r--tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.rs12
-rw-r--r--tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.stdout5
-rw-r--r--tests/ui/inference/detect-old-time-version-format_description-parse.rs8
-rw-r--r--tests/ui/inference/detect-old-time-version-format_description-parse.stderr11
14 files changed, 135 insertions, 14 deletions
diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl
index c279195a7e9..b40c353f077 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 2ce712e0bff..10b6ddeb177 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 4f3dcd9043f..4ac5b521926 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.
+ /// <https://github.com/rust-lang/rust/issues/127343>
+ // 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<Span>,
+ kind: &InferSourceKind<'_>,
+ // We will clear the non-actionable suggestion from the error to reduce noise.
+ infer_subdiags: &mut Vec<SourceKindSubdiag<'_>>,
+ ) -> 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 02ebf933f53..fc47f5c11b7 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 d4477563e3a..9ef6b20e77a 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 b64efadb261..99d80eda374 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/select-xcode.sh b/src/ci/scripts/select-xcode.sh
index 569c4a4136d..d635d438472 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
diff --git a/src/ci/scripts/upload-artifacts.sh b/src/ci/scripts/upload-artifacts.sh
index c9c85ec20b4..587b324ce10 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 a7f0df5afa9..e9fc3a3ffce 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<DiagMessage>) {
+ fn emit_error(&mut self, err: impl Into<DiagMessage>) {
if let Some(extra) = self.extra {
extra.error_invalid_codeblock_attr(err);
}
+ self.is_error = true;
}
fn skip_separators(&mut self) -> Option<usize> {
@@ -1155,6 +1163,9 @@ impl<'a, 'tcx> Iterator for TagIterator<'a, 'tcx> {
type Item = LangStringToken<'a>;
fn next(&mut self) -> Option<Self::Item> {
+ 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 fb74c079c9a..23da2f0cc7f 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 00000000000..571bc94e30f
--- /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 00000000000..e5c27bebbdb
--- /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 00000000000..453a795e768
--- /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 00000000000..2949a5dcfec
--- /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<Vec<_>>`
+ --> $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`.