Skip to content

Commit

Permalink
Auto merge of #129758 - cuviper:beta-next, r=cuviper
Browse files Browse the repository at this point in the history
[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
  • Loading branch information
bors committed Aug 31, 2024
2 parents 4a765c0 + a4461df commit 4a101b4
Show file tree
Hide file tree
Showing 14 changed files with 135 additions and 14 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_infer/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_infer/src/errors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
46 changes: 44 additions & 2 deletions compiler/rustc_infer/src/infer/need_type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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)]
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_infer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
10 changes: 9 additions & 1 deletion compiler/rustc_mir_transform/src/inline/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
)
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1883,6 +1883,7 @@ symbols! {
three_way_compare,
thumb2,
thumb_mode: "thumb-mode",
time,
tmm_reg,
to_owned_method,
to_string,
Expand Down
17 changes: 17 additions & 0 deletions src/ci/scripts/select-xcode.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
#!/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'

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
8 changes: 4 additions & 4 deletions src/ci/scripts/upload-artifacts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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:"
Expand Down
20 changes: 16 additions & 4 deletions src/librustdoc/html/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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> {
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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
}
Expand Down
6 changes: 3 additions & 3 deletions src/librustdoc/html/markdown/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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]
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
@@ -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();
}
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 4a101b4

Please sign in to comment.