diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2458eb5fafb1c..0fe906cb86223 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,11 +11,9 @@ name: CI on: push: branches: - - auto - - try - - try-perf - - automation/bors/try - automation/bors/auto + - automation/bors/try + - try-perf pull_request: branches: - "**" @@ -33,9 +31,10 @@ defaults: concurrency: # For a given workflow, if we push to the same branch, cancel all previous builds on that branch. - # We add an exception for try builds (try branch) and unrolled rollup builds (try-perf), which - # are all triggered on the same branch, but which should be able to run concurrently. - group: ${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try') && github.sha) || github.ref }} + # We add an exception for try builds (automation/bors/try branch) and unrolled rollup builds + # (try-perf), which are all triggered on the same branch, but which should be able to run + # concurrently. + group: ${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try') && github.sha) || github.ref }} cancel-in-progress: true env: TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate" @@ -57,7 +56,7 @@ jobs: - name: Test citool # Only test citool on the auto branch, to reduce latency of the calculate matrix job # on PR/try builds. - if: ${{ github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto' }} + if: ${{ github.ref == 'refs/heads/automation/bors/auto' }} run: | cd src/ci/citool CARGO_INCREMENTAL=0 cargo test @@ -80,7 +79,7 @@ jobs: # access the environment. # # We only enable the environment for the rust-lang/rust repository, so that CI works on forks. - environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }} + environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }} env: CI_JOB_NAME: ${{ matrix.name }} CI_JOB_DOC_URL: ${{ matrix.doc_url }} @@ -314,7 +313,7 @@ jobs: needs: [ calculate_matrix, job ] # !cancelled() executes the job regardless of whether the previous jobs passed or failed if: ${{ !cancelled() && contains(fromJSON('["auto", "try"]'), needs.calculate_matrix.outputs.run_type) }} - environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }} + environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }} steps: - name: checkout the source code uses: actions/checkout@v5 diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index e02d71a261581..26db2992d8af3 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -57,6 +57,7 @@ pub(crate) mod pin_v2; pub(crate) mod proc_macro_attrs; pub(crate) mod prototype; pub(crate) mod repr; +pub(crate) mod rustc_dump; pub(crate) mod rustc_internal; pub(crate) mod semantics; pub(crate) mod stability; diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs new file mode 100644 index 0000000000000..53120dece916e --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs @@ -0,0 +1,62 @@ +use rustc_hir::Target; +use rustc_hir::attrs::AttributeKind; +use rustc_span::{Span, Symbol, sym}; + +use crate::attributes::prelude::Allow; +use crate::attributes::{NoArgsAttributeParser, OnDuplicate}; +use crate::context::Stage; +use crate::target_checking::AllowedTargets; + +pub(crate) struct RustcDumpUserArgs; + +impl NoArgsAttributeParser for RustcDumpUserArgs { + const PATH: &[Symbol] = &[sym::rustc_dump_user_args]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpUserArgs; +} + +pub(crate) struct RustcDumpDefParents; + +impl NoArgsAttributeParser for RustcDumpDefParents { + const PATH: &[Symbol] = &[sym::rustc_dump_def_parents]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpDefParents; +} + +pub(crate) struct RustcDumpItemBounds; + +impl NoArgsAttributeParser for RustcDumpItemBounds { + const PATH: &[Symbol] = &[sym::rustc_dump_item_bounds]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::AssocTy)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpItemBounds; +} + +pub(crate) struct RustcDumpPredicates; + +impl NoArgsAttributeParser for RustcDumpPredicates { + const PATH: &[Symbol] = &[sym::rustc_dump_predicates]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Struct), + Allow(Target::Enum), + Allow(Target::Union), + Allow(Target::Trait), + Allow(Target::AssocTy), + ]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpPredicates; +} + +pub(crate) struct RustcDumpVtable; + +impl NoArgsAttributeParser for RustcDumpVtable { + const PATH: &[Symbol] = &[sym::rustc_dump_vtable]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Impl { of_trait: true }), + Allow(Target::TyAlias), + ]); + const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDumpVtable; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 6b1b1d484283f..8305d027d13ca 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -63,6 +63,10 @@ use crate::attributes::proc_macro_attrs::{ }; use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; +use crate::attributes::rustc_dump::{ + RustcDumpDefParents, RustcDumpItemBounds, RustcDumpPredicates, RustcDumpUserArgs, + RustcDumpVtable, +}; use crate::attributes::rustc_internal::{ RustcHasIncoherentInherentImplsParser, RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, RustcLegacyConstGenericsParser, @@ -267,6 +271,11 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, + Single>, + Single>, + Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index f932b198b4260..814c81278a104 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -3,7 +3,7 @@ use rustc_hir::LangItem; use rustc_middle::mir::interpret::CtfeProvenance; use rustc_middle::span_bug; use rustc_middle::ty::layout::TyAndLayout; -use rustc_middle::ty::{self, ScalarInt, Ty}; +use rustc_middle::ty::{self, Const, ScalarInt, Ty}; use rustc_span::{Symbol, sym}; use crate::const_eval::CompileTimeMachine; @@ -56,6 +56,14 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { self.write_tuple_fields(tuple_place, fields, ty)?; variant } + ty::Array(ty, len) => { + let (variant, variant_place) = downcast(sym::Array)?; + let array_place = self.project_field(&variant_place, FieldIdx::ZERO)?; + + self.write_array_type_info(array_place, *ty, *len)?; + + variant + } // For now just merge all primitives into one `Leaf` variant with no data ty::Uint(_) | ty::Int(_) | ty::Float(_) | ty::Char | ty::Bool => { downcast(sym::Leaf)?.0 @@ -63,7 +71,6 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { ty::Adt(_, _) | ty::Foreign(_) | ty::Str - | ty::Array(_, _) | ty::Pat(_, _) | ty::Slice(_) | ty::RawPtr(..) @@ -172,4 +179,28 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { } interp_ok(()) } + + pub(crate) fn write_array_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + ty: Ty<'tcx>, + len: Const<'tcx>, + ) -> InterpResult<'tcx> { + // Iterate over all fields of `type_info::Array`. + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + + match field.name { + // Write the `TypeId` of the array's elements to the `element_ty` field. + sym::element_ty => self.write_type_id(ty, &field_place)?, + // Write the length of the array to the `len` field. + sym::len => self.write_scalar(len.to_leaf(), &field_place)?, + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + + interp_ok(()) + } } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 2a8efd25a375f..9b2eab3a73ed5 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -765,30 +765,35 @@ fn print_crate_info( for (name, expected_values) in &sess.psess.check_config.expecteds { use crate::config::ExpectedValues; match expected_values { - ExpectedValues::Any => check_cfgs.push(format!("{name}=any()")), + ExpectedValues::Any => { + check_cfgs.push(format!("cfg({name}, values(any()))")) + } ExpectedValues::Some(values) => { - if !values.is_empty() { - check_cfgs.extend(values.iter().map(|value| { + let mut values: Vec<_> = values + .iter() + .map(|value| { if let Some(value) = value { - format!("{name}=\"{value}\"") + format!("\"{value}\"") } else { - name.to_string() + "none()".to_string() } - })) - } else { - check_cfgs.push(format!("{name}=")) - } + }) + .collect(); + + values.sort_unstable(); + + let values = values.join(", "); + + check_cfgs.push(format!("cfg({name}, values({values}))")) } } } check_cfgs.sort_unstable(); - if !sess.psess.check_config.exhaustive_names { - if !sess.psess.check_config.exhaustive_values { - println_info!("any()=any()"); - } else { - println_info!("any()"); - } + if !sess.psess.check_config.exhaustive_names + && sess.psess.check_config.exhaustive_values + { + println_info!("cfg(any())"); } for check_cfg in check_cfgs { println_info!("{check_cfg}"); diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 8d18d335b355b..3d9362d2d923c 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -906,6 +906,21 @@ pub enum AttributeKind { /// Represents `#[rustc_coherence_is_core]` RustcCoherenceIsCore(Span), + /// Represents `#[rustc_dump_def_parents]` + RustcDumpDefParents, + + /// Represents `#[rustc_dump_item_bounds]` + RustcDumpItemBounds, + + /// Represents `#[rustc_dump_predicates]` + RustcDumpPredicates, + + /// Represents `#[rustc_dump_user_args]` + RustcDumpUserArgs, + + /// Represents `#[rustc_dump_vtable]` + RustcDumpVtable(Span), + /// Represents `#[rustc_has_incoherent_inherent_impls]` RustcHasIncoherentInherentImpls, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 33655f4f00635..48f3ceba9c399 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -97,6 +97,11 @@ impl AttributeKind { Repr { .. } => No, RustcBuiltinMacro { .. } => Yes, RustcCoherenceIsCore(..) => No, + RustcDumpDefParents => No, + RustcDumpItemBounds => No, + RustcDumpPredicates => No, + RustcDumpUserArgs => No, + RustcDumpVtable(..) => No, RustcHasIncoherentInherentImpls => Yes, RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 416a6b19edfc8..fa3c4cb05f961 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -166,8 +166,9 @@ hir_analysis_duplicate_precise_capture = cannot capture parameter `{$name}` twic .label = parameter captured again here hir_analysis_eii_with_generics = - #[{$eii_name}] cannot have generic parameters other than lifetimes + `{$impl_name}` cannot have generic parameters other than lifetimes .label = required by this attribute + .help = `#[{$eii_name}]` marks the implementation of an "externally implementable item" hir_analysis_empty_specialization = specialization impl does not specialize any associated items .note = impl is a specialization of this impl diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 4664bfcce853a..c37611ab2ee70 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -974,12 +974,19 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), (0, _) => ("const", "consts", None), _ => ("type or const", "types or consts", None), }; + let name = + if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::EiiForeignItem) { + "externally implementable items" + } else { + "foreign items" + }; + let span = tcx.def_span(def_id); struct_span_code_err!( tcx.dcx(), span, E0044, - "foreign items may not have {kinds} parameters", + "{name} may not have {kinds} parameters", ) .with_span_label(span, format!("can't have {kinds} parameters")) .with_help( diff --git a/compiler/rustc_hir_analysis/src/check/compare_eii.rs b/compiler/rustc_hir_analysis/src/check/compare_eii.rs index d8afee9aafc98..2beb7eb09c119 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_eii.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_eii.rs @@ -8,8 +8,9 @@ use std::iter; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{Applicability, E0806, struct_span_code_err}; +use rustc_hir::attrs::{AttributeKind, EiiImplResolution}; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::{self as hir, FnSig, HirId, ItemKind}; +use rustc_hir::{self as hir, FnSig, HirId, ItemKind, find_attr}; use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::error::{ExpectedFound, TypeError}; @@ -169,11 +170,23 @@ fn check_no_generics<'tcx>( eii_attr_span: Span, ) -> Result<(), ErrorGuaranteed> { let generics = tcx.generics_of(external_impl); - if generics.own_requires_monomorphization() { + if generics.own_requires_monomorphization() + // When an EII implementation is automatically generated by the `#[eii]` macro, + // it will directly refer to the foreign item, not through a macro. + // We don't want to emit this error if it's an implementation that's generated by the `#[eii]` macro, + // since in that case it looks like a duplicate error: the declaration of the EII already can't contain generics. + // So, we check here if at least one of the eii impls has ImplResolution::Macro, which indicates it's + // not generated as part of the declaration. + && find_attr!( + tcx.get_all_attrs(external_impl), + AttributeKind::EiiImpls(impls) if impls.iter().any(|i| matches!(i.resolution, EiiImplResolution::Macro(_))) + ) + { tcx.dcx().emit_err(EiiWithGenerics { span: tcx.def_span(external_impl), attr: eii_attr_span, eii_name, + impl_name: tcx.item_name(external_impl), }); } diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs index b167f31a246c6..2dfd4ab6111fe 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -1,6 +1,7 @@ use rustc_hir as hir; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; -use rustc_hir::intravisit; +use rustc_hir::{find_attr, intravisit}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_span::sym; @@ -28,7 +29,7 @@ pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) { pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) { for id in tcx.hir_crate_items(()).owners() { - if tcx.has_attr(id, sym::rustc_dump_predicates) { + if find_attr!(tcx.get_all_attrs(id), AttributeKind::RustcDumpPredicates) { let preds = tcx.predicates_of(id).instantiate_identity(tcx).predicates; let span = tcx.def_span(id); @@ -38,7 +39,7 @@ pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) { } diag.emit(); } - if tcx.has_attr(id, sym::rustc_dump_item_bounds) { + if find_attr!(tcx.get_all_attrs(id), AttributeKind::RustcDumpItemBounds) { let bounds = tcx.item_bounds(id).instantiate_identity(); let span = tcx.def_span(id); @@ -54,7 +55,7 @@ pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) { pub(crate) fn def_parents(tcx: TyCtxt<'_>) { for iid in tcx.hir_free_items() { let did = iid.owner_id.def_id; - if tcx.has_attr(did, sym::rustc_dump_def_parents) { + if find_attr!(tcx.get_all_attrs(did), AttributeKind::RustcDumpDefParents) { struct AnonConstFinder<'tcx> { tcx: TyCtxt<'tcx>, anon_consts: Vec, @@ -102,7 +103,9 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) { for id in tcx.hir_free_items() { let def_id = id.owner_id.def_id; - let Some(attr) = tcx.get_attr(def_id, sym::rustc_dump_vtable) else { + let Some(&attr_span) = + find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcDumpVtable(span) => span) + else { continue; }; @@ -111,14 +114,14 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) { let trait_ref = tcx.impl_trait_ref(def_id).instantiate_identity(); if trait_ref.has_non_region_param() { tcx.dcx().span_err( - attr.span(), + attr_span, "`rustc_dump_vtable` must be applied to non-generic impl", ); continue; } if !tcx.is_dyn_compatible(trait_ref.def_id) { tcx.dcx().span_err( - attr.span(), + attr_span, "`rustc_dump_vtable` must be applied to dyn-compatible trait", ); continue; @@ -127,7 +130,7 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) { .try_normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref) else { tcx.dcx().span_err( - attr.span(), + attr_span, "`rustc_dump_vtable` applied to impl header that cannot be normalized", ); continue; @@ -138,7 +141,7 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) { let ty = tcx.type_of(def_id).instantiate_identity(); if ty.has_non_region_param() { tcx.dcx().span_err( - attr.span(), + attr_span, "`rustc_dump_vtable` must be applied to non-generic type", ); continue; @@ -147,14 +150,13 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) { tcx.try_normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty) else { tcx.dcx().span_err( - attr.span(), + attr_span, "`rustc_dump_vtable` applied to type alias that cannot be normalized", ); continue; }; let ty::Dynamic(data, _) = *ty.kind() else { - tcx.dcx() - .span_err(attr.span(), "`rustc_dump_vtable` to type alias of dyn type"); + tcx.dcx().span_err(attr_span, "`rustc_dump_vtable` to type alias of dyn type"); continue; }; if let Some(principal) = data.principal() { @@ -167,7 +169,7 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) { } _ => { tcx.dcx().span_err( - attr.span(), + attr_span, "`rustc_dump_vtable` only applies to impl, or type alias of dyn type", ); continue; diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index b388396ac4fcd..185a822bdfa6a 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1655,10 +1655,12 @@ pub(crate) struct LifetimesOrBoundsMismatchOnEii { #[derive(Diagnostic)] #[diag(hir_analysis_eii_with_generics)] +#[help] pub(crate) struct EiiWithGenerics { #[primary_span] pub span: Span, #[label] pub attr: Span, pub eii_name: Symbol, + pub impl_name: Symbol, } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index d2cbf89336d8b..a66a521975c53 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2415,11 +2415,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }; let ty::Array(elem_ty, _) = ty.kind() else { - return Const::new_error_with_message( - tcx, - array_expr.span, - "const array must have an array type", - ); + let e = tcx + .dcx() + .span_err(array_expr.span, format!("expected `{}`, found const array", ty)); + return Const::new_error(tcx, e); }; let elems = array_expr diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 960a8497a2668..0078cd9d06833 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -14,9 +14,10 @@ use std::ops::ControlFlow; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::unord::ExtendUnord; use rustc_errors::{E0720, ErrorGuaranteed}; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, InferKind, Visitor}; -use rustc_hir::{self as hir, AmbigArg, HirId}; +use rustc_hir::{self as hir, AmbigArg, HirId, find_attr}; use rustc_infer::traits::solve::Goal; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; @@ -25,7 +26,7 @@ use rustc_middle::ty::{ TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, fold_regions, }; -use rustc_span::{Span, sym}; +use rustc_span::Span; use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded; use rustc_trait_selection::opaque_types::opaque_type_has_defining_use_args; use rustc_trait_selection::solve; @@ -45,8 +46,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // This attribute causes us to dump some writeback information // in the form of errors, which is used for unit tests. - let rustc_dump_user_args = - self.has_rustc_attrs && self.tcx.has_attr(item_def_id, sym::rustc_dump_user_args); + let rustc_dump_user_args = self.has_rustc_attrs + && find_attr!(self.tcx.get_all_attrs(item_def_id), AttributeKind::RustcDumpUserArgs); let mut wbcx = WritebackCx::new(self, body, rustc_dump_user_args); for param in body.params { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 8f80822a81ab1..f047d66a82542 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -309,6 +309,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::CfiEncoding { .. } | AttributeKind::RustcHasIncoherentInherentImpls | AttributeKind::MustNotSupend { .. } + | AttributeKind::RustcDumpUserArgs + | AttributeKind::RustcDumpItemBounds + | AttributeKind::RustcDumpPredicates + | AttributeKind::RustcDumpDefParents + | AttributeKind::RustcDumpVtable(..) ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); @@ -368,25 +373,20 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_abi | sym::rustc_layout | sym::rustc_proc_macro_decls - | sym::rustc_dump_def_parents | sym::rustc_never_type_options | sym::rustc_autodiff | sym::rustc_capture_analysis | sym::rustc_regions | sym::rustc_strict_coherence - | sym::rustc_dump_predicates | sym::rustc_variance | sym::rustc_variance_of_opaques | sym::rustc_hidden_type_of_opaques | sym::rustc_mir - | sym::rustc_dump_user_args | sym::rustc_effective_visibility | sym::rustc_outlives | sym::rustc_symbol_name | sym::rustc_evaluate_where_clauses - | sym::rustc_dump_vtable | sym::rustc_delayed_bug_from_inside_query - | sym::rustc_dump_item_bounds | sym::rustc_def_path | sym::rustc_partition_reused | sym::rustc_partition_codegened diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index f56c3421ce0f5..34804160ed398 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -162,6 +162,7 @@ symbols! { Arc, ArcWeak, Argument, + Array, ArrayIntoIter, AsMut, AsRef, @@ -939,6 +940,7 @@ symbols! { eii_impl, eii_internals, eii_shared_macro, + element_ty, emit, emit_enum, emit_enum_variant, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 81b921b3744f4..ea98d326eeb91 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1391,25 +1391,45 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // return early in the caller. let mut label = || { + // Special case `Sized` as `old_pred` will be the trait itself instead of + // `Sized` when the trait bound is the source of the error. + let is_sized = match obligation.predicate.kind().skip_binder() { + ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => { + self.tcx.is_lang_item(trait_pred.def_id(), LangItem::Sized) + } + _ => false, + }; + let msg = format!( "the trait bound `{}` is not satisfied", self.tcx.short_string(old_pred, err.long_ty_path()), ); - let self_ty_str = - self.tcx.short_string(old_pred.self_ty().skip_binder(), err.long_ty_path()); + let self_ty_str = self.tcx.short_string(old_pred.self_ty(), err.long_ty_path()); let trait_path = self .tcx .short_string(old_pred.print_modifiers_and_trait_path(), err.long_ty_path()); if has_custom_message { + let msg = if is_sized { + "the trait bound `Sized` is not satisfied".into() + } else { + msg + }; err.note(msg); } else { err.messages = vec![(rustc_errors::DiagMessage::from(msg), Style::NoStyle)]; } - err.span_label( - span, - format!("the trait `{trait_path}` is not implemented for `{self_ty_str}`"), - ); + if is_sized { + err.span_label( + span, + format!("the trait `Sized` is not implemented for `{self_ty_str}`"), + ); + } else { + err.span_label( + span, + format!("the trait `{trait_path}` is not implemented for `{self_ty_str}`"), + ); + } }; let mut sugg_prefixes = vec![]; @@ -3578,10 +3598,27 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { "unsatisfied trait bound introduced in this `derive` macro", ); } else if !data.span.is_dummy() && !data.span.overlaps(self_ty.span) { - spans.push_span_label( - data.span, - "unsatisfied trait bound introduced here", - ); + // `Sized` may be an explicit or implicit trait bound. If it is + // implicit, mention it as such. + if let Some(pred) = predicate.as_trait_clause() + && self.tcx.is_lang_item(pred.def_id(), LangItem::Sized) + && self + .tcx + .generics_of(data.impl_or_alias_def_id) + .own_params + .iter() + .any(|param| self.tcx.def_span(param.def_id) == data.span) + { + spans.push_span_label( + data.span, + "unsatisfied trait bound implicitly introduced here", + ); + } else { + spans.push_span_label( + data.span, + "unsatisfied trait bound introduced here", + ); + } } err.span_note(spans, msg); point_at_assoc_type_restriction( diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs index 7938e2b52ed02..e4ccc408f1c65 100644 --- a/library/core/src/mem/type_info.rs +++ b/library/core/src/mem/type_info.rs @@ -31,7 +31,7 @@ impl Type { #[unstable(feature = "type_info", issue = "146922")] #[rustc_const_unstable(feature = "type_info", issue = "146922")] // FIXME(reflection): don't require the 'static bound - pub const fn of() -> Self { + pub const fn of() -> Self { const { TypeId::of::().info() } } } @@ -43,6 +43,8 @@ impl Type { pub enum TypeKind { /// Tuples. Tuple(Tuple), + /// Arrays. + Array(Array), /// Primitives /// FIXME(#146922): disambiguate further Leaf, @@ -69,3 +71,14 @@ pub struct Field { /// Offset in bytes from the parent type pub offset: usize, } + +/// Compile-time type information about arrays. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Array { + /// The type of each element in the array. + pub element_ty: TypeId, + /// The length of the array. + pub len: usize, +} diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index ff4fc4c892afe..caa130be1483e 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -115,6 +115,7 @@ #![feature(try_blocks)] #![feature(try_find)] #![feature(try_trait_v2)] +#![feature(type_info)] #![feature(uint_bit_width)] #![feature(uint_gather_scatter_bits)] #![feature(unsize)] diff --git a/library/coretests/tests/mem.rs b/library/coretests/tests/mem.rs index 5247e01fba01b..193d5416b06a7 100644 --- a/library/coretests/tests/mem.rs +++ b/library/coretests/tests/mem.rs @@ -1,3 +1,5 @@ +mod type_info; + use core::mem::*; use core::{array, ptr}; use std::cell::Cell; diff --git a/library/coretests/tests/mem/type_info.rs b/library/coretests/tests/mem/type_info.rs new file mode 100644 index 0000000000000..b3b8d96d49b00 --- /dev/null +++ b/library/coretests/tests/mem/type_info.rs @@ -0,0 +1,56 @@ +use std::any::TypeId; +use std::mem::type_info::{Type, TypeKind}; + +#[test] +fn test_arrays() { + // Normal array. + match const { Type::of::<[u16; 4]>() }.kind { + TypeKind::Array(array) => { + assert_eq!(array.element_ty, TypeId::of::()); + assert_eq!(array.len, 4); + } + _ => unreachable!(), + } + + // Zero-length array. + match const { Type::of::<[bool; 0]>() }.kind { + TypeKind::Array(array) => { + assert_eq!(array.element_ty, TypeId::of::()); + assert_eq!(array.len, 0); + } + _ => unreachable!(), + } +} + +#[test] +fn test_tuples() { + fn assert_tuple_arity() { + match const { Type::of::() }.kind { + TypeKind::Tuple(tup) => { + assert_eq!(tup.fields.len(), N); + } + _ => unreachable!(), + } + } + + assert_tuple_arity::<(), 0>(); + assert_tuple_arity::<(u8,), 1>(); + assert_tuple_arity::<(u8, u8), 2>(); + + const { + match Type::of::<(u8, u8)>().kind { + TypeKind::Tuple(tup) => { + let [a, b] = tup.fields else { unreachable!() }; + + assert!(a.offset == 0); + assert!(b.offset == 1); + + match (a.ty.info().kind, b.ty.info().kind) { + (TypeKind::Leaf, TypeKind::Leaf) => {} + _ => unreachable!(), + } + } + _ => unreachable!(), + } + } +} diff --git a/library/std/src/path.rs b/library/std/src/path.rs index e8eda3c5f76bb..25bd7005b9942 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2972,6 +2972,15 @@ impl Path { /// /// If `path` is absolute, it replaces the current path. /// + /// On Windows: + /// + /// * if `path` has a root but no prefix (e.g., `\windows`), it + /// replaces and returns everything except for the prefix (if any) of `self`. + /// * if `path` has a prefix but no root, `self` is ignored and `path` is returned. + /// * if `self` has a verbatim prefix (e.g. `\\?\C:\windows`) + /// and `path` is not empty, the new path is normalized: all references + /// to `.` and `..` are removed. + /// /// See [`PathBuf::push`] for more details on what it means to adjoin a path. /// /// # Examples diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index d7b491d38f41f..01c0650b3c98f 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -41,14 +41,12 @@ impl GitHubContext { match (self.event_name.as_str(), self.branch_ref.as_str()) { ("pull_request", _) => Some(RunType::PullRequest), ("push", "refs/heads/try-perf") => Some(RunType::TryJob { job_patterns: None }), - ("push", "refs/heads/try" | "refs/heads/automation/bors/try") => { + ("push", "refs/heads/automation/bors/try") => { let patterns = self.get_try_job_patterns(); let patterns = if !patterns.is_empty() { Some(patterns) } else { None }; Some(RunType::TryJob { job_patterns: patterns }) } - ("push", "refs/heads/auto" | "refs/heads/automation/bors/auto") => { - Some(RunType::AutoJob) - } + ("push", "refs/heads/automation/bors/auto") => Some(RunType::AutoJob), ("push", "refs/heads/main") => Some(RunType::MainJob), _ => None, } diff --git a/src/ci/citool/tests/jobs.rs b/src/ci/citool/tests/jobs.rs index 5231d4616e049..6787f00d9af83 100644 --- a/src/ci/citool/tests/jobs.rs +++ b/src/ci/citool/tests/jobs.rs @@ -4,7 +4,7 @@ const TEST_JOBS_YML_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/tes #[test] fn auto_jobs() { - let stdout = get_matrix("push", "commit", "refs/heads/auto"); + let stdout = get_matrix("push", "commit", "refs/heads/automation/bors/auto"); insta::assert_snapshot!(stdout, @r#" jobs=[{"name":"aarch64-gnu","full_name":"auto - aarch64-gnu","os":"ubuntu-22.04-arm","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"x86_64-gnu-llvm-18-1","full_name":"auto - x86_64-gnu-llvm-18-1","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","DOCKER_SCRIPT":"stage_2_test_set1.sh","IMAGE":"x86_64-gnu-llvm-18","READ_ONLY_SRC":"0","RUST_BACKTRACE":1,"TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"aarch64-apple","full_name":"auto - aarch64-apple","os":"macos-14","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","MACOSX_DEPLOYMENT_TARGET":11.0,"MACOSX_STD_DEPLOYMENT_TARGET":11.0,"NO_DEBUG_ASSERTIONS":1,"NO_LLVM_ASSERTIONS":1,"NO_OVERFLOW_CHECKS":1,"RUSTC_RETRY_LINKER_ON_SEGFAULT":1,"RUST_CONFIGURE_ARGS":"--enable-sanitizers --enable-profiler --set rust.jemalloc","SCRIPT":"./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin","SELECT_XCODE":"/Applications/Xcode_15.4.app","TOOLSTATE_PUBLISH":1,"USE_XCODE_CLANG":1}},{"name":"dist-i686-msvc","full_name":"auto - dist-i686-msvc","os":"windows-2022","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_REQUIRE_ALL_TOOLS":1,"RUST_CONFIGURE_ARGS":"--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler","SCRIPT":"python x.py dist bootstrap --include-default-paths","TOOLSTATE_PUBLISH":1}},{"name":"pr-check-1","full_name":"auto - pr-check-1","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true},{"name":"pr-check-2","full_name":"auto - pr-check-2","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true},{"name":"tidy","full_name":"auto - tidy","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true,"doc_url":"https://foo.bar"}] run_type=auto @@ -13,7 +13,7 @@ fn auto_jobs() { #[test] fn try_jobs() { - let stdout = get_matrix("push", "commit", "refs/heads/try"); + let stdout = get_matrix("push", "commit", "refs/heads/automation/bors/try"); insta::assert_snapshot!(stdout, @r###" jobs=[{"name":"dist-x86_64-linux","full_name":"try - dist-x86_64-linux","os":"ubuntu-22.04-16core-64gb","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_TRY_BUILD":1,"TOOLSTATE_PUBLISH":1}}] run_type=try @@ -28,7 +28,7 @@ fn try_custom_jobs() { try-job: aarch64-gnu try-job: dist-i686-msvc"#, - "refs/heads/try", + "refs/heads/automation/bors/try", ); insta::assert_snapshot!(stdout, @r###" jobs=[{"name":"aarch64-gnu","full_name":"try - aarch64-gnu","os":"ubuntu-22.04-arm","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"dist-i686-msvc","full_name":"try - dist-i686-msvc","os":"windows-2022","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_REQUIRE_ALL_TOOLS":1,"RUST_CONFIGURE_ARGS":"--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler","SCRIPT":"python x.py dist bootstrap --include-default-paths","TOOLSTATE_PUBLISH":1}}] diff --git a/src/ci/scripts/verify-channel.sh b/src/ci/scripts/verify-channel.sh index cac8ba332ed19..286869e8a411b 100755 --- a/src/ci/scripts/verify-channel.sh +++ b/src/ci/scripts/verify-channel.sh @@ -8,8 +8,7 @@ IFS=$'\n\t' source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" -if isCiBranch auto || isCiBranch try || isCiBranch try-perf || \ - isCiBranch automation/bors/try || isCiBranch automation/bors/auto; then +if isCiBranch try-perf || isCiBranch automation/bors/try || isCiBranch automation/bors/auto; then echo "channel verification is only executed on PR builds" exit fi diff --git a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md index 9fb24906b4fc3..d2635f12db21b 100644 --- a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md +++ b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md @@ -21,7 +21,7 @@ This target is cross compiled, and requires a cross toolchain. You can find sui Compiling rust for this target has been tested on `x86_64` linux hosts. Other host types have not been tested, but may work, if you can find a suitable cross compilation toolchain for them. -If you don't already have a suitable toolchain, download one [here](https://toolchains.bootlin.com/downloads/releases/toolchains/armv7-eabihf/tarballs/armv7-eabihf--uclibc--bleeding-edge-2021.11-1.tar.bz2), and unpack it into a directory. +If you don't already have a suitable toolchain, download one [here](https://toolchains.bootlin.com/downloads/releases/toolchains/armv7-eabihf/tarballs/armv7-eabihf--uclibc--bleeding-edge-2025.08-1.tar.xz), and unpack it into a directory. ### Configure rust @@ -30,7 +30,7 @@ The target can be built by enabling it for a `rustc` build, by placing the follo ```toml [build] target = ["armv7-unknown-linux-uclibceabihf"] -stage = 2 +build-stage = 2 [target.armv7-unknown-linux-uclibceabihf] # ADJUST THIS PATH TO POINT AT YOUR TOOLCHAIN diff --git a/src/doc/unstable-book/src/compiler-flags/print-check-cfg.md b/src/doc/unstable-book/src/compiler-flags/print-check-cfg.md index 8d314aa62d4cc..1b41a0cd728fc 100644 --- a/src/doc/unstable-book/src/compiler-flags/print-check-cfg.md +++ b/src/doc/unstable-book/src/compiler-flags/print-check-cfg.md @@ -9,18 +9,20 @@ This option of the `--print` flag print the list of all the expected cfgs. This is related to the [`--check-cfg` flag][check-cfg] which allows specifying arbitrary expected names and values. -This print option works similarly to `--print=cfg` (modulo check-cfg specifics). - -| `--check-cfg` | `--print=check-cfg` | -|-----------------------------------|-----------------------------| -| `cfg(foo)` | `foo` | -| `cfg(foo, values("bar"))` | `foo="bar"` | -| `cfg(foo, values(none(), "bar"))` | `foo` & `foo="bar"` | -| | *check-cfg specific syntax* | -| `cfg(foo, values(any())` | `foo=any()` | -| `cfg(foo, values())` | `foo=` | -| `cfg(any())` | `any()` | -| *none* | `any()=any()` | +This print option outputs compatible `--check-cfg` arguments with a reduced syntax where all the +expected values are on the same line and `values(...)` is always explicit. + +| `--check-cfg` | `--print=check-cfg` | +|-----------------------------------|-----------------------------------| +| `cfg(foo)` | `cfg(foo, values(none())) | +| `cfg(foo, values("bar"))` | `cfg(foo, values("bar"))` | +| `cfg(foo, values(none(), "bar"))` | `cfg(foo, values(none(), "bar"))` | +| `cfg(foo, values(any())` | `cfg(foo, values(any())` | +| `cfg(foo, values())` | `cfg(foo, values())` | +| `cfg(any())` | `cfg(any())` | +| *nothing* | *nothing* | + +The print option includes well known cfgs. To be used like this: @@ -28,4 +30,7 @@ To be used like this: rustc --print=check-cfg -Zunstable-options lib.rs ``` +> **Note:** Users should be resilient when parsing, in particular against new predicates that +may be added in the future. + [check-cfg]: https://doc.rust-lang.org/nightly/rustc/check-cfg.html diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index a2f3a8f00dac0..106e521d5805f 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -1070,11 +1070,27 @@ fn builtin_cfg_names(config: &Config) -> HashSet { Default::default(), ) .lines() - .map(|l| if let Some((name, _)) = l.split_once('=') { name.to_string() } else { l.to_string() }) + .map(|l| extract_cfg_name(&l).unwrap().to_string()) .chain(std::iter::once(String::from("test"))) .collect() } +/// Extract the cfg name from `cfg(name, values(...))` lines +fn extract_cfg_name(check_cfg_line: &str) -> Result<&str, &'static str> { + let trimmed = check_cfg_line.trim(); + + #[rustfmt::skip] + let inner = trimmed + .strip_prefix("cfg(") + .ok_or("missing cfg(")? + .strip_suffix(")") + .ok_or("missing )")?; + + let first_comma = inner.find(',').ok_or("no comma found")?; + + Ok(inner[..first_comma].trim()) +} + pub const KNOWN_CRATE_TYPES: &[&str] = &["bin", "cdylib", "dylib", "lib", "proc-macro", "rlib", "staticlib"]; diff --git a/tests/run-make/print-check-cfg/rmake.rs b/tests/run-make/print-check-cfg/rmake.rs index f6f7f7cece6e7..e102d2904a80f 100644 --- a/tests/run-make/print-check-cfg/rmake.rs +++ b/tests/run-make/print-check-cfg/rmake.rs @@ -14,51 +14,55 @@ struct CheckCfg { enum Contains { Some { contains: &'static [&'static str], doesnt_contain: &'static [&'static str] }, - Only(&'static str), + Nothing, } fn main() { - check(CheckCfg { args: &[], contains: Contains::Only("any()=any()") }); + check(CheckCfg { args: &[], contains: Contains::Nothing }); check(CheckCfg { args: &["--check-cfg=cfg()"], contains: Contains::Some { - contains: &["unix", "miri"], - doesnt_contain: &["any()", "any()=any()"], + contains: &["cfg(unix, values(none()))", "cfg(miri, values(none()))"], + doesnt_contain: &["cfg(any())"], }, }); check(CheckCfg { args: &["--check-cfg=cfg(any())"], contains: Contains::Some { - contains: &["any()", "unix", r#"target_feature="crt-static""#], + contains: &["cfg(any())", "cfg(unix, values(none()))"], doesnt_contain: &["any()=any()"], }, }); check(CheckCfg { args: &["--check-cfg=cfg(feature)"], contains: Contains::Some { - contains: &["unix", "miri", "feature"], - doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature="], + contains: &[ + "cfg(unix, values(none()))", + "cfg(miri, values(none()))", + "cfg(feature, values(none()))", + ], + doesnt_contain: &["cfg(any())", "cfg(feature)"], }, }); check(CheckCfg { args: &[r#"--check-cfg=cfg(feature, values(none(), "", "test", "lol"))"#], contains: Contains::Some { - contains: &["feature", "feature=\"\"", "feature=\"test\"", "feature=\"lol\""], - doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature="], + contains: &[r#"cfg(feature, values("", "lol", "test", none()))"#], + doesnt_contain: &["cfg(any())", "cfg(feature, values(none()))", "cfg(feature)"], }, }); check(CheckCfg { args: &["--check-cfg=cfg(feature, values())"], contains: Contains::Some { - contains: &["feature="], - doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature"], + contains: &["cfg(feature, values())"], + doesnt_contain: &["cfg(any())", "cfg(feature, values(none()))", "cfg(feature)"], }, }); check(CheckCfg { args: &["--check-cfg=cfg(feature, values())", "--check-cfg=cfg(feature, values(none()))"], contains: Contains::Some { - contains: &["feature"], - doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature="], + contains: &["cfg(feature, values(none()))"], + doesnt_contain: &["cfg(any())", "cfg(feature, values())"], }, }); check(CheckCfg { @@ -67,8 +71,8 @@ fn main() { r#"--check-cfg=cfg(feature, values("tmp"))"#, ], contains: Contains::Some { - contains: &["unix", "miri", "feature=any()"], - doesnt_contain: &["any()", "any()=any()", "feature", "feature=", "feature=\"tmp\""], + contains: &["cfg(feature, values(any()))"], + doesnt_contain: &["cfg(any())", r#"cfg(feature, values("tmp"))"#], }, }); check(CheckCfg { @@ -78,8 +82,12 @@ fn main() { r#"--check-cfg=cfg(feature, values("tmp"))"#, ], contains: Contains::Some { - contains: &["has_foo", "has_bar", "feature=\"tmp\""], - doesnt_contain: &["any()", "any()=any()", "feature"], + contains: &[ + "cfg(has_foo, values(none()))", + "cfg(has_bar, values(none()))", + r#"cfg(feature, values("tmp"))"#, + ], + doesnt_contain: &["cfg(any())", "cfg(feature)"], }, }); } @@ -94,16 +102,15 @@ fn check(CheckCfg { args, contains }: CheckCfg) { for l in stdout.lines() { assert!(l == l.trim()); - if let Some((left, right)) = l.split_once('=') { - if right != "any()" && right != "" { - assert!(right.starts_with("\"")); - assert!(right.ends_with("\"")); - } - assert!(!left.contains("\"")); - } else { - assert!(!l.contains("\"")); - } - assert!(found.insert(l.to_string()), "{}", &l); + assert!(l.starts_with("cfg("), "{l}"); + assert!(l.ends_with(")"), "{l}"); + assert_eq!( + l.chars().filter(|c| *c == '(').count(), + l.chars().filter(|c| *c == ')').count(), + "{l}" + ); + assert!(l.chars().filter(|c| *c == '"').count() % 2 == 0, "{l}"); + assert!(found.insert(l.to_string()), "{l}"); } match contains { @@ -131,9 +138,8 @@ fn check(CheckCfg { args, contains }: CheckCfg) { ); } } - Contains::Only(only) => { - assert!(found.contains(&only.to_string()), "{:?} != {:?}", &only, &found); - assert!(found.len() == 1, "len: {}, instead of 1", found.len()); + Contains::Nothing => { + assert!(found.len() == 0, "len: {}, instead of 0", found.len()); } } } diff --git a/tests/rustdoc-gui/notable-trait.goml b/tests/rustdoc-gui/notable-trait.goml index 839988021fce5..8e4c180e0ef17 100644 --- a/tests/rustdoc-gui/notable-trait.goml +++ b/tests/rustdoc-gui/notable-trait.goml @@ -250,7 +250,7 @@ set-window-size: (1100, 600) reload: assert-count: ("//*[@class='tooltip popover']", 0) click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" -assert-count: ("//*[@class='tooltip popover']", 1) +wait-for-count: ("//*[@class='tooltip popover']", 1) call-function: ("open-settings-menu", {}) -assert-count: ("//*[@class='tooltip popover']", 0) +wait-for-count: ("//*[@class='tooltip popover']", 0) assert-false: "#method\.create_an_iterator_from_read .tooltip:focus" diff --git a/tests/ui/associated-types/substs-ppaux.normal.stderr b/tests/ui/associated-types/substs-ppaux.normal.stderr index aa2aca7426e1a..b1c9ce3f22b6a 100644 --- a/tests/ui/associated-types/substs-ppaux.normal.stderr +++ b/tests/ui/associated-types/substs-ppaux.normal.stderr @@ -88,7 +88,7 @@ note: required for `str` to implement `Foo<'_, '_, u8>` LL | impl<'a, 'b, T, S> Foo<'a, 'b, S> for T {} | - ^^^^^^^^^^^^^^ ^ | | - | unsatisfied trait bound introduced here + | unsatisfied trait bound implicitly introduced here error: aborting due to 5 previous errors diff --git a/tests/ui/associated-types/substs-ppaux.verbose.stderr b/tests/ui/associated-types/substs-ppaux.verbose.stderr index 23cf222a1d37e..46cae5db56fdd 100644 --- a/tests/ui/associated-types/substs-ppaux.verbose.stderr +++ b/tests/ui/associated-types/substs-ppaux.verbose.stderr @@ -88,7 +88,7 @@ note: required for `str` to implement `Foo<'?0, '?1, u8>` LL | impl<'a, 'b, T, S> Foo<'a, 'b, S> for T {} | - ^^^^^^^^^^^^^^ ^ | | - | unsatisfied trait bound introduced here + | unsatisfied trait bound implicitly introduced here error: aborting due to 5 previous errors diff --git a/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.rs b/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.rs new file mode 100644 index 0000000000000..cda519b96d4d8 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.rs @@ -0,0 +1,21 @@ +//! regression test for +#![feature(min_generic_const_args)] +#![feature(adt_const_params)] +#![expect(incomplete_features)] + +trait Trait1 {} +trait Trait2 {} + +fn foo() +where + T: Trait1<{ [] }>, //~ ERROR: expected `usize`, found const array +{ +} + +fn bar() +where + T: Trait2<3>, //~ ERROR: mismatched types +{ +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.stderr b/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.stderr new file mode 100644 index 0000000000000..be40e44742267 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.stderr @@ -0,0 +1,15 @@ +error: expected `usize`, found const array + --> $DIR/array-expr-type-mismatch-in-where-bound.rs:11:17 + | +LL | T: Trait1<{ [] }>, + | ^^ + +error[E0308]: mismatched types + --> $DIR/array-expr-type-mismatch-in-where-bound.rs:17:15 + | +LL | T: Trait2<3>, + | ^ expected `[u8; 3]`, found integer + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/eii/type_checking/generic_implementation.rs b/tests/ui/eii/type_checking/generic_implementation.rs new file mode 100644 index 0000000000000..489fd2e645d84 --- /dev/null +++ b/tests/ui/eii/type_checking/generic_implementation.rs @@ -0,0 +1,13 @@ +//@ check-fail +// Check that type parameters on EIIs are properly rejected. +// Specifically a regression test for https://github.com/rust-lang/rust/issues/149983. +#![feature(extern_item_impls)] + +#[eii] +fn foo(); + +#[foo] +fn foo_impl() {} +//~^ ERROR `foo_impl` cannot have generic parameters other than lifetimes + +fn main() {} diff --git a/tests/ui/eii/type_checking/generic_implementation.stderr b/tests/ui/eii/type_checking/generic_implementation.stderr new file mode 100644 index 0000000000000..17a71998423d7 --- /dev/null +++ b/tests/ui/eii/type_checking/generic_implementation.stderr @@ -0,0 +1,12 @@ +error: `foo_impl` cannot have generic parameters other than lifetimes + --> $DIR/generic_implementation.rs:10:1 + | +LL | #[foo] + | ------ required by this attribute +LL | fn foo_impl() {} + | ^^^^^^^^^^^^^^^^ + | + = help: `#[foo]` marks the implementation of an "externally implementable item" + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/type_checking/type_params_149983.rs b/tests/ui/eii/type_checking/type_params_149983.rs new file mode 100644 index 0000000000000..6dc9b309712e1 --- /dev/null +++ b/tests/ui/eii/type_checking/type_params_149983.rs @@ -0,0 +1,10 @@ +//@ check-fail +// Check that type parameters on EIIs are properly rejected. +// Specifically a regression test for https://github.com/rust-lang/rust/issues/149983. +#![feature(extern_item_impls)] + +#[eii] +fn foo() {} +//~^ ERROR externally implementable items may not have type parameters + +fn main() {} diff --git a/tests/ui/eii/type_checking/type_params_149983.stderr b/tests/ui/eii/type_checking/type_params_149983.stderr new file mode 100644 index 0000000000000..11f06e6c88e20 --- /dev/null +++ b/tests/ui/eii/type_checking/type_params_149983.stderr @@ -0,0 +1,11 @@ +error[E0044]: externally implementable items may not have type parameters + --> $DIR/type_params_149983.rs:7:1 + | +LL | fn foo() {} + | ^^^^^^^^^^^ can't have type parameters + | + = help: replace the type parameters with concrete types like `u32` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0044`. diff --git a/tests/ui/error-codes/E0277-4.rs b/tests/ui/error-codes/E0277-4.rs new file mode 100644 index 0000000000000..ead57f00dde50 --- /dev/null +++ b/tests/ui/error-codes/E0277-4.rs @@ -0,0 +1,50 @@ +use std::fmt::Display; + +trait ImplicitTrait { + fn foo(&self); +} + +trait ExplicitTrait { + fn foo(&self); +} + +trait DisplayTrait { + fn foo(&self); +} + +trait UnimplementedTrait { + fn foo(&self); +} + +// Implicitly requires `T: Sized`. +impl ImplicitTrait for T { + fn foo(&self) {} +} + +// Explicitly requires `T: Sized`. +impl ExplicitTrait for T { + fn foo(&self) {} +} + +// Requires `T: Display`. +impl DisplayTrait for T { + fn foo(&self) {} +} + +fn main() { + // `[u8]` does not implement `Sized`. + let x: &[u8] = &[]; + ImplicitTrait::foo(x); + //~^ ERROR: the trait bound `[u8]: ImplicitTrait` is not satisfied [E0277] + ExplicitTrait::foo(x); + //~^ ERROR: the trait bound `[u8]: ExplicitTrait` is not satisfied [E0277] + + // `UnimplementedTrait` has no implementations. + UnimplementedTrait::foo(x); + //~^ ERROR: the trait bound `[u8]: UnimplementedTrait` is not satisfied [E0277] + + // `[u8; 0]` implements `Sized` but not `Display`. + let x: &[u8; 0] = &[]; + DisplayTrait::foo(x); + //~^ ERROR: the trait bound `[u8; 0]: DisplayTrait` is not satisfied [E0277] +} diff --git a/tests/ui/error-codes/E0277-4.stderr b/tests/ui/error-codes/E0277-4.stderr new file mode 100644 index 0000000000000..f38b8146a63d2 --- /dev/null +++ b/tests/ui/error-codes/E0277-4.stderr @@ -0,0 +1,77 @@ +error[E0277]: the trait bound `[u8]: ImplicitTrait` is not satisfied + --> $DIR/E0277-4.rs:37:24 + | +LL | ImplicitTrait::foo(x); + | ------------------ ^ the trait `Sized` is not implemented for `[u8]` + | | + | required by a bound introduced by this call + | +note: required for `[u8]` to implement `ImplicitTrait` + --> $DIR/E0277-4.rs:20:9 + | +LL | impl ImplicitTrait for T { + | - ^^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound implicitly introduced here +help: consider borrowing here + | +LL | ImplicitTrait::foo(&x); + | + +LL | ImplicitTrait::foo(&mut x); + | ++++ + +error[E0277]: the trait bound `[u8]: ExplicitTrait` is not satisfied + --> $DIR/E0277-4.rs:39:24 + | +LL | ExplicitTrait::foo(x); + | ------------------ ^ the trait `Sized` is not implemented for `[u8]` + | | + | required by a bound introduced by this call + | +note: required for `[u8]` to implement `ExplicitTrait` + --> $DIR/E0277-4.rs:25:16 + | +LL | impl ExplicitTrait for T { + | ----- ^^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +help: consider borrowing here + | +LL | ExplicitTrait::foo(&x); + | + +LL | ExplicitTrait::foo(&mut x); + | ++++ + +error[E0277]: the trait bound `[u8]: UnimplementedTrait` is not satisfied + --> $DIR/E0277-4.rs:43:29 + | +LL | UnimplementedTrait::foo(x); + | ----------------------- ^ the trait `UnimplementedTrait` is not implemented for `[u8]` + | | + | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/E0277-4.rs:15:1 + | +LL | trait UnimplementedTrait { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `[u8; 0]: DisplayTrait` is not satisfied + --> $DIR/E0277-4.rs:48:23 + | +LL | DisplayTrait::foo(x); + | ----------------- ^ the trait `std::fmt::Display` is not implemented for `[u8; 0]` + | | + | required by a bound introduced by this call + | +note: required for `[u8; 0]` to implement `DisplayTrait` + --> $DIR/E0277-4.rs:30:18 + | +LL | impl DisplayTrait for T { + | ------- ^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/recursion/issue-23122-2.stderr b/tests/ui/recursion/issue-23122-2.stderr index de402d65e6d6a..39cd0eb35a630 100644 --- a/tests/ui/recursion/issue-23122-2.stderr +++ b/tests/ui/recursion/issue-23122-2.stderr @@ -11,7 +11,7 @@ note: required for `GetNext<<<<... as Next>::Next as Next>::Next as Next>::Next> LL | impl Next for GetNext { | - ^^^^ ^^^^^^^^^^ | | - | unsatisfied trait bound introduced here + | unsatisfied trait bound implicitly introduced here = note: the full name for the type has been written to '$TEST_BUILD_DIR/issue-23122-2.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console diff --git a/tests/ui/reflection/dump.rs b/tests/ui/reflection/dump.rs index 3bf4f32b6641d..0adcda481b5a8 100644 --- a/tests/ui/reflection/dump.rs +++ b/tests/ui/reflection/dump.rs @@ -22,9 +22,12 @@ struct Unsized { fn main() { println!("{:#?}", const { Type::of::<(u8, u8, ())>() }.kind); + println!("{:#?}", const { Type::of::<[u8; 2]>() }.kind); println!("{:#?}", const { Type::of::() }.kind); println!("{:#?}", const { Type::of::() }.kind); println!("{:#?}", const { Type::of::<&Unsized>() }.kind); println!("{:#?}", const { Type::of::<&str>() }.kind); println!("{:#?}", const { Type::of::<&[u8]>() }.kind); + println!("{:#?}", const { Type::of::() }.kind); + println!("{:#?}", const { Type::of::<[u8]>() }.kind); } diff --git a/tests/ui/reflection/dump.run.stdout b/tests/ui/reflection/dump.run.stdout index 71fd80b466580..dfd128664e2d9 100644 --- a/tests/ui/reflection/dump.run.stdout +++ b/tests/ui/reflection/dump.run.stdout @@ -16,6 +16,14 @@ Tuple( ], }, ) +Array( + Array { + element_ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), + len: 2, + }, +) +Other +Other Other Other Other diff --git a/tests/ui/reflection/tuples.rs b/tests/ui/reflection/tuples.rs deleted file mode 100644 index eab25a691efe2..0000000000000 --- a/tests/ui/reflection/tuples.rs +++ /dev/null @@ -1,36 +0,0 @@ -#![feature(type_info)] - -//@ run-pass - -use std::mem::type_info::{Type, TypeKind}; - -fn assert_tuple_arity() { - const { - match &Type::of::().kind { - TypeKind::Tuple(tup) => { - assert!(tup.fields.len() == N); - } - _ => unreachable!(), - } - } -} - -fn main() { - assert_tuple_arity::<(), 0>(); - assert_tuple_arity::<(u8,), 1>(); - assert_tuple_arity::<(u8, u8), 2>(); - const { - match &Type::of::<(u8, u8)>().kind { - TypeKind::Tuple(tup) => { - let [a, b] = tup.fields else { unreachable!() }; - assert!(a.offset == 0); - assert!(b.offset == 1); - match (&a.ty.info().kind, &b.ty.info().kind) { - (TypeKind::Leaf, TypeKind::Leaf) => {} - _ => unreachable!(), - } - } - _ => unreachable!(), - } - } -} diff --git a/tests/ui/resolve/decl-macro-use-no-ice.rs b/tests/ui/resolve/decl-macro-use-no-ice.rs new file mode 100644 index 0000000000000..39b9cb03fea0d --- /dev/null +++ b/tests/ui/resolve/decl-macro-use-no-ice.rs @@ -0,0 +1,20 @@ +//@ edition: 2024 +#![feature(decl_macro)] + +// Regression test for issue +// The compiler previously ICE'd during identifier resolution +// involving `macro` items and `use` inside a public macro. + + +mod foo { + macro f() {} + + pub macro m() { + use f; //~ ERROR `f` is private, and cannot be re-exported + f!(); //~ ERROR macro import `f` is private + } +} + +fn main() { + foo::m!(); +} diff --git a/tests/ui/resolve/decl-macro-use-no-ice.stderr b/tests/ui/resolve/decl-macro-use-no-ice.stderr new file mode 100644 index 0000000000000..9fb75b48b428c --- /dev/null +++ b/tests/ui/resolve/decl-macro-use-no-ice.stderr @@ -0,0 +1,47 @@ +error[E0364]: `f` is private, and cannot be re-exported + --> $DIR/decl-macro-use-no-ice.rs:13:13 + | +LL | use f; + | ^ +... +LL | foo::m!(); + | --------- in this macro invocation + | +note: consider marking `f` as `pub` in the imported module + --> $DIR/decl-macro-use-no-ice.rs:13:13 + | +LL | use f; + | ^ +... +LL | foo::m!(); + | --------- in this macro invocation + = note: this error originates in the macro `foo::m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0603]: macro import `f` is private + --> $DIR/decl-macro-use-no-ice.rs:14:9 + | +LL | f!(); + | ^ private macro import +... +LL | foo::m!(); + | --------- in this macro invocation + | +note: the macro import `f` is defined here... + --> $DIR/decl-macro-use-no-ice.rs:13:13 + | +LL | use f; + | ^ +... +LL | foo::m!(); + | --------- in this macro invocation +note: ...and refers to the macro `f` which is defined here + --> $DIR/decl-macro-use-no-ice.rs:10:5 + | +LL | macro f() {} + | ^^^^^^^^^ + = note: this error originates in the macro `foo::m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0364, E0603. +For more information about an error, try `rustc --explain E0364`. diff --git a/tests/ui/suggestions/slice-issue-87994.stderr b/tests/ui/suggestions/slice-issue-87994.stderr index 22ad5d352120d..dd5c00af90b22 100644 --- a/tests/ui/suggestions/slice-issue-87994.stderr +++ b/tests/ui/suggestions/slice-issue-87994.stderr @@ -17,11 +17,10 @@ error[E0277]: `[i32]` is not an iterator --> $DIR/slice-issue-87994.rs:3:12 | LL | for _ in v[1..] { - | ^^^^^^ the trait `IntoIterator` is not implemented for `[i32]` + | ^^^^^^ the trait `Sized` is not implemented for `[i32]` | - = note: the trait bound `[i32]: IntoIterator` is not satisfied + = note: the trait bound `Sized` is not satisfied = note: required for `[i32]` to implement `IntoIterator` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider borrowing here | LL | for _ in &v[1..] { @@ -48,11 +47,10 @@ error[E0277]: `[K]` is not an iterator --> $DIR/slice-issue-87994.rs:11:13 | LL | for i2 in v2[1..] { - | ^^^^^^^ the trait `IntoIterator` is not implemented for `[K]` + | ^^^^^^^ the trait `Sized` is not implemented for `[K]` | - = note: the trait bound `[K]: IntoIterator` is not satisfied + = note: the trait bound `Sized` is not satisfied = note: required for `[K]` to implement `IntoIterator` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider borrowing here | LL | for i2 in &v2[1..] { diff --git a/tests/ui/traits/dyn-iterator-deref-in-for-loop.current.stderr b/tests/ui/traits/dyn-iterator-deref-in-for-loop.current.stderr index b5a9b82a93a3e..0dd2ffffdfeaf 100644 --- a/tests/ui/traits/dyn-iterator-deref-in-for-loop.current.stderr +++ b/tests/ui/traits/dyn-iterator-deref-in-for-loop.current.stderr @@ -2,9 +2,9 @@ error[E0277]: `dyn Iterator` is not an iterator --> $DIR/dyn-iterator-deref-in-for-loop.rs:9:17 | LL | for item in *things { - | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator` + | ^^^^^^^ the trait `Sized` is not implemented for `dyn Iterator` | - = note: the trait bound `dyn Iterator: IntoIterator` is not satisfied + = note: the trait bound `Sized` is not satisfied = note: required for `dyn Iterator` to implement `IntoIterator` help: consider mutably borrowing here | diff --git a/tests/ui/traits/dyn-iterator-deref-in-for-loop.next.stderr b/tests/ui/traits/dyn-iterator-deref-in-for-loop.next.stderr index b5a9b82a93a3e..0dd2ffffdfeaf 100644 --- a/tests/ui/traits/dyn-iterator-deref-in-for-loop.next.stderr +++ b/tests/ui/traits/dyn-iterator-deref-in-for-loop.next.stderr @@ -2,9 +2,9 @@ error[E0277]: `dyn Iterator` is not an iterator --> $DIR/dyn-iterator-deref-in-for-loop.rs:9:17 | LL | for item in *things { - | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator` + | ^^^^^^^ the trait `Sized` is not implemented for `dyn Iterator` | - = note: the trait bound `dyn Iterator: IntoIterator` is not satisfied + = note: the trait bound `Sized` is not satisfied = note: required for `dyn Iterator` to implement `IntoIterator` help: consider mutably borrowing here | diff --git a/tests/ui/traits/issue-18400.stderr b/tests/ui/traits/issue-18400.stderr index 146ba16397a20..af5519a15c23d 100644 --- a/tests/ui/traits/issue-18400.stderr +++ b/tests/ui/traits/issue-18400.stderr @@ -11,7 +11,7 @@ note: required for `{integer}` to implement `Set<&[_]>` LL | impl<'a, T, S> Set<&'a [T]> for S where | - ^^^^^^^^^^^^ ^ | | - | unsatisfied trait bound introduced here + | unsatisfied trait bound implicitly introduced here = note: 128 redundant requirements hidden = note: required for `{integer}` to implement `Set<&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[_]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]>` diff --git a/triagebot.toml b/triagebot.toml index f00b4b9daffc8..456fd696af435 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -332,6 +332,14 @@ trigger_labels = [ "A-type-based-search", ] +[autolabel."A-rustdoc-js"] +trigger_files = [ + "src/librustdoc/html/static/js/", + "src/librustdoc/html/static/css/", + "tests/rustdoc-js/", + "tests/rustdoc-js-std/", +] + [autolabel."T-compiler"] trigger_files = [ # Source code