diff --git a/.github/workflows/ghcr.yml b/.github/workflows/ghcr.yml index 0fcd1b178163e..4793b28e72263 100644 --- a/.github/workflows/ghcr.yml +++ b/.github/workflows/ghcr.yml @@ -9,7 +9,7 @@ # for PR jobs, because forks can't access secrets. # That's why we use ghcr.io: it has no rate limit and it doesn't require authentication. -name: GHCR +name: GHCR image mirroring on: workflow_dispatch: diff --git a/Cargo.lock b/Cargo.lock index 85e5e6c97105c..a08d43a014c06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4259,6 +4259,7 @@ dependencies = [ "rustc_serialize", "rustc_type_ir", "rustc_type_ir_macros", + "smallvec", "tracing", ] diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 45764f9c6b867..c6e6d962ce5fd 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -182,9 +182,6 @@ fn do_mir_borrowck<'tcx>( let location_table = PoloniusLocationTable::new(body); let move_data = MoveData::gather_moves(body, tcx, |_| true); - let promoted_move_data = promoted - .iter_enumerated() - .map(|(idx, body)| (idx, MoveData::gather_moves(body, tcx, |_| true))); let flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data) .iterate_to_fixpoint(tcx, body, Some("borrowck")) @@ -242,10 +239,14 @@ fn do_mir_borrowck<'tcx>( false }; - for (idx, move_data) in promoted_move_data { + // While promoteds should mostly be correct by construction, we need to check them for + // invalid moves to detect moving out of arrays:`struct S; fn main() { &([S][0]); }`. + for promoted_body in &promoted { use rustc_middle::mir::visit::Visitor; - - let promoted_body = &promoted[idx]; + // This assumes that we won't use some of the fields of the `promoted_mbcx` + // when detecting and reporting move errors. While it would be nice to move + // this check out of `MirBorrowckCtxt`, actually doing so is far from trivial. + let move_data = MoveData::gather_moves(promoted_body, tcx, |_| true); let mut promoted_mbcx = MirBorrowckCtxt { infcx: &infcx, body: promoted_body, @@ -270,9 +271,6 @@ fn do_mir_borrowck<'tcx>( move_errors: Vec::new(), diags_buffer, }; - MoveVisitor { ctxt: &mut promoted_mbcx }.visit_body(promoted_body); - promoted_mbcx.report_move_errors(); - struct MoveVisitor<'a, 'b, 'infcx, 'tcx> { ctxt: &'a mut MirBorrowckCtxt<'b, 'infcx, 'tcx>, } @@ -284,6 +282,8 @@ fn do_mir_borrowck<'tcx>( } } } + MoveVisitor { ctxt: &mut promoted_mbcx }.visit_body(promoted_body); + promoted_mbcx.report_move_errors(); } let mut mbcx = MirBorrowckCtxt { diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index ec82644ea5ba4..b0a6922ff72bb 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1637,7 +1637,6 @@ fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalD let ty = tcx.type_of(def_id).instantiate_identity(); if ty.references_error() { // If there is already another error, do not emit an error for not using a type parameter. - assert!(tcx.dcx().has_errors().is_some()); return; } diff --git a/compiler/rustc_next_trait_solver/Cargo.toml b/compiler/rustc_next_trait_solver/Cargo.toml index 451c215566be2..f9168112216ab 100644 --- a/compiler/rustc_next_trait_solver/Cargo.toml +++ b/compiler/rustc_next_trait_solver/Cargo.toml @@ -13,6 +13,7 @@ rustc_macros = { path = "../rustc_macros", optional = true } rustc_serialize = { path = "../rustc_serialize", optional = true } rustc_type_ir = { path = "../rustc_type_ir", default-features = false } rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } +smallvec = "1.8.1" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index f4d7c3ce76cf2..4faa243c02a64 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -8,6 +8,7 @@ use rustc_type_ir::lang_items::TraitSolverLangItem; use rustc_type_ir::solve::CanonicalResponse; use rustc_type_ir::visit::TypeVisitableExt as _; use rustc_type_ir::{self as ty, Interner, TraitPredicate, TypingMode, Upcast as _, elaborate}; +use smallvec::SmallVec; use tracing::{instrument, trace}; use crate::delegate::SolverDelegate; @@ -225,7 +226,7 @@ where } ecx.probe_and_evaluate_goal_for_constituent_tys( - CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), + CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial), goal, structural_traits::instantiate_constituent_tys_for_sized_trait, ) @@ -1194,7 +1195,30 @@ where }; } - // FIXME: prefer trivial builtin impls + // We prefer trivial builtin candidates, i.e. builtin impls without any + // nested requirements, over all others. This is a fix for #53123 and + // prevents where-bounds from accidentally extending the lifetime of a + // variable. + if candidates + .iter() + .any(|c| matches!(c.source, CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial))) + { + let trivial_builtin_impls: SmallVec<[_; 1]> = candidates + .iter() + .filter(|c| { + matches!(c.source, CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial)) + }) + .map(|c| c.result) + .collect(); + // There should only ever be a single trivial builtin candidate + // as they would otherwise overlap. + assert_eq!(trivial_builtin_impls.len(), 1); + return if let Some(response) = self.try_merge_responses(&trivial_builtin_impls) { + Ok((response, Some(TraitGoalProvenVia::Misc))) + } else { + Ok((self.bail_with_ambiguity(&trivial_builtin_impls), None)) + }; + } // If there are non-global where-bounds, prefer where-bounds // (including global ones) over everything else. diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index aae0e34ddf393..d59cf88875ea7 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -991,7 +991,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( Err(ErrorGuaranteed { .. }) => true, } } - ImplSource::Builtin(BuiltinImplSource::Misc, _) => { + ImplSource::Builtin(BuiltinImplSource::Misc | BuiltinImplSource::Trivial, _) => { // While a builtin impl may be known to exist, the associated type may not yet // be known. Any type with multiple potential associated types is therefore // not eligible. @@ -1296,7 +1296,7 @@ fn confirm_select_candidate<'cx, 'tcx>( ) -> Progress<'tcx> { match impl_source { ImplSource::UserDefined(data) => confirm_impl_candidate(selcx, obligation, data), - ImplSource::Builtin(BuiltinImplSource::Misc, data) => { + ImplSource::Builtin(BuiltinImplSource::Misc | BuiltinImplSource::Trivial, data) => { let tcx = selcx.tcx(); let trait_def_id = obligation.predicate.trait_def_id(tcx); if tcx.is_lang_item(trait_def_id, LangItem::Coroutine) { diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index fc76a86f79772..d5e1937efaa45 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -248,7 +248,7 @@ fn resolve_associated_item<'tcx>( }) } } - traits::ImplSource::Builtin(BuiltinImplSource::Misc, _) => { + traits::ImplSource::Builtin(BuiltinImplSource::Misc | BuiltinImplSource::Trivial, _) => { if tcx.is_lang_item(trait_ref.def_id, LangItem::Clone) { // FIXME(eddyb) use lang items for methods instead of names. let name = tcx.item_name(trait_item_id); diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index fbb5c7430eb2a..c06004d4d0f6c 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -169,6 +169,9 @@ pub enum CandidateSource { #[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext, TyEncodable, TyDecodable))] pub enum BuiltinImplSource { + /// A built-in impl that is considered trivial, without any nested requirements. They + /// are preferred over where-clauses, and we want to track them explicitly. + Trivial, /// Some built-in impl we don't need to differentiate. This should be used /// unless more specific information is necessary. Misc, diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 026380a46c685..1c49063ef5c66 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -42,6 +42,8 @@ use crate::utils::helpers::{self, exe, output, t}; #[rustfmt::skip] // We don't want rustfmt to oneline this list pub(crate) const RUSTC_IF_UNCHANGED_ALLOWED_PATHS: &[&str] = &[ ":!src/tools", + ":!src/librustdoc", + ":!src/rustdoc-json-types", ":!tests", ":!triagebot.toml", ]; diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index b6a19147eb7f3..84f2149dbdf52 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -32,7 +32,7 @@ use crate::{ColorConfig, json, stamp_file_path}; mod debugger; // Helper modules that implement test running logic for each test suite. -// tidy-alphabet-start +// tidy-alphabetical-start mod assembly; mod codegen; mod codegen_units; @@ -47,7 +47,7 @@ mod run_make; mod rustdoc; mod rustdoc_json; mod ui; -// tidy-alphabet-end +// tidy-alphabetical-end #[cfg(test)] mod tests; diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index aefcd2bb0ccc0..21b513629ed8d 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -72,6 +72,21 @@ const ANNOTATIONS_TO_IGNORE: &[&str] = &[ "//@ normalize-stderr", ]; +// If you edit this, also edit where it gets used in `check` (calling `contains_ignore_directives`) +const CONFIGURABLE_CHECKS: [&str; 11] = [ + "cr", + "undocumented-unsafe", + "tab", + "linelength", + "filelength", + "end-whitespace", + "trailing-newlines", + "leading-newlines", + "copyright", + "dbg", + "odd-backticks", +]; + fn generate_problems<'a>( consts: &'a [u32], letter_digit: &'a FxHashMap, @@ -220,6 +235,7 @@ fn long_line_is_ok(extension: &str, is_error_code: bool, max_columns: usize, lin } } +#[derive(Clone, Copy)] enum Directive { /// By default, tidy always warns against style issues. Deny, @@ -231,20 +247,28 @@ enum Directive { Ignore(bool), } -fn contains_ignore_directive(can_contain: bool, contents: &str, check: &str) -> Directive { +// Use a fixed size array in the return type to catch mistakes with changing `CONFIGURABLE_CHECKS` +// without changing the code in `check` easier. +fn contains_ignore_directives( + can_contain: bool, + contents: &str, + checks: [&str; N], +) -> [Directive; N] { if !can_contain { - return Directive::Deny; - } - // Update `can_contain` when changing this - if contents.contains(&format!("// ignore-tidy-{check}")) - || contents.contains(&format!("# ignore-tidy-{check}")) - || contents.contains(&format!("/* ignore-tidy-{check} */")) - || contents.contains(&format!("")) - { - Directive::Ignore(false) - } else { - Directive::Deny + return [Directive::Deny; N]; } + checks.map(|check| { + // Update `can_contain` when changing this + if contents.contains(&format!("// ignore-tidy-{check}")) + || contents.contains(&format!("# ignore-tidy-{check}")) + || contents.contains(&format!("/* ignore-tidy-{check} */")) + || contents.contains(&format!("")) + { + Directive::Ignore(false) + } else { + Directive::Deny + } + }) } macro_rules! suppressible_tidy_err { @@ -370,6 +394,7 @@ pub fn check(path: &Path, bad: &mut bool) { COLS }; + // When you change this, also change the `directive_line_starts` variable below let can_contain = contents.contains("// ignore-tidy-") || contents.contains("# ignore-tidy-") || contents.contains("/* ignore-tidy-") @@ -385,22 +410,19 @@ pub fn check(path: &Path, bad: &mut bool) { return; } } - let mut skip_cr = contains_ignore_directive(can_contain, &contents, "cr"); - let mut skip_undocumented_unsafe = - contains_ignore_directive(can_contain, &contents, "undocumented-unsafe"); - let mut skip_tab = contains_ignore_directive(can_contain, &contents, "tab"); - let mut skip_line_length = contains_ignore_directive(can_contain, &contents, "linelength"); - let mut skip_file_length = contains_ignore_directive(can_contain, &contents, "filelength"); - let mut skip_end_whitespace = - contains_ignore_directive(can_contain, &contents, "end-whitespace"); - let mut skip_trailing_newlines = - contains_ignore_directive(can_contain, &contents, "trailing-newlines"); - let mut skip_leading_newlines = - contains_ignore_directive(can_contain, &contents, "leading-newlines"); - let mut skip_copyright = contains_ignore_directive(can_contain, &contents, "copyright"); - let mut skip_dbg = contains_ignore_directive(can_contain, &contents, "dbg"); - let mut skip_odd_backticks = - contains_ignore_directive(can_contain, &contents, "odd-backticks"); + let [ + mut skip_cr, + mut skip_undocumented_unsafe, + mut skip_tab, + mut skip_line_length, + mut skip_file_length, + mut skip_end_whitespace, + mut skip_trailing_newlines, + mut skip_leading_newlines, + mut skip_copyright, + mut skip_dbg, + mut skip_odd_backticks, + ] = contains_ignore_directives(can_contain, &contents, CONFIGURABLE_CHECKS); let mut leading_new_lines = false; let mut trailing_new_lines = 0; let mut lines = 0; @@ -474,6 +496,22 @@ pub fn check(path: &Path, bad: &mut bool) { suppressible_tidy_err!(err, skip_cr, "CR character"); } if !is_this_file { + let directive_line_starts = ["// ", "# ", "/* ", " $DIR/ice-hir-wf-issue-135341.rs:2:10 + | +LL | type B = _; + | ^ not allowed in type signatures + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0121`.