diff options
179 files changed, 1608 insertions, 1453 deletions
diff --git a/Cargo.lock b/Cargo.lock index 2dc6e8ff103..4677d34d2a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1192,6 +1192,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8975ffdaa0ef3661bfe02dbdcc06c9f829dfafe6a3c474de366a8d5e44276921" [[package]] +name = "dyn-clone" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005" + +[[package]] name = "either" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3123,6 +3129,26 @@ dependencies = [ ] [[package]] +name = "ref-cast" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] name = "regex" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4577,6 +4603,7 @@ dependencies = [ "rustc_macros", "rustc_serialize", "rustc_span", + "schemars", "serde", "serde_derive", "serde_json", @@ -4901,6 +4928,31 @@ dependencies = [ ] [[package]] +name = "schemars" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +dependencies = [ + "dyn-clone", + "ref-cast", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d020396d1d138dc19f1165df7545479dcd58d93810dc5d646a16e55abefa80" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.106", +] + +[[package]] name = "scoped-tls" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4975,6 +5027,17 @@ dependencies = [ ] [[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] name = "serde_json" version = "1.0.142" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index bb559bd8921..53351f91c46 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -5,7 +5,9 @@ use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err}; use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{DefKind, PerNS, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; -use rustc_hir::{self as hir, HirId, LifetimeSource, PredicateOrigin, Target, find_attr}; +use rustc_hir::{ + self as hir, HirId, ImplItemImplKind, LifetimeSource, PredicateOrigin, Target, find_attr, +}; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::span_bug; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; @@ -1117,20 +1119,31 @@ impl<'hir> LoweringContext<'_, 'hir> { } }; + let span = self.lower_span(i.span); let item = hir::ImplItem { owner_id: hir_id.expect_owner(), ident: self.lower_ident(ident), generics, + impl_kind: if is_in_trait_impl { + ImplItemImplKind::Trait { + defaultness, + trait_item_def_id: self + .resolver + .get_partial_res(i.id) + .and_then(|r| r.expect_full_res().opt_def_id()) + .ok_or_else(|| { + self.dcx().span_delayed_bug( + span, + "could not resolve trait item being implemented", + ) + }), + } + } else { + ImplItemImplKind::Inherent { vis_span: self.lower_span(i.vis.span) } + }, kind, - vis_span: self.lower_span(i.vis.span), - span: self.lower_span(i.span), - defaultness, + span, has_delayed_lints: !self.delayed_lints.is_empty(), - trait_item_def_id: self - .resolver - .get_partial_res(i.id) - .map(|r| r.expect_full_res().opt_def_id()) - .unwrap_or(None), }; self.arena.alloc(item) } diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index ea264c8064a..6d69040c711 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -716,7 +716,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { return (false, false, None); }; - let implemented_trait_item = self.infcx.tcx.associated_item(my_def).trait_item_def_id; + let implemented_trait_item = self.infcx.tcx.trait_item_of(my_def); ( true, diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index a6c8e7d29cc..d70888205a5 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -569,6 +569,7 @@ fn make_format_args( detect_foreign_fmt, str_style, fmt_str, + uncooked_fmt_str.1.as_str(), fmt_span, ); } @@ -650,6 +651,7 @@ fn report_missing_placeholders( detect_foreign_fmt: bool, str_style: Option<usize>, fmt_str: &str, + uncooked_fmt_str: &str, fmt_span: Span, ) { let mut diag = if let &[(span, named)] = &unused[..] { @@ -773,16 +775,20 @@ fn report_missing_placeholders( diag.note(format!("consider adding {} format specifiers", unused.len())); } } else { - let original_fmt_str = - if fmt_str.len() >= 1 { &fmt_str[..fmt_str.len() - 1] } else { "" }; - let msg = if unused.len() == 1 { "a format specifier".to_string() } else { format!("{} format specifiers", unused.len()) }; - let sugg = format!("\"{}{}\"", original_fmt_str, "{}".repeat(unused.len())); + let sugg = match str_style { + None => format!("\"{}{}\"", uncooked_fmt_str, "{}".repeat(unused.len())), + Some(n_hashes) => format!( + "r{hashes}\"{uncooked_fmt_str}{fmt_specifiers}\"{hashes}", + hashes = "#".repeat(n_hashes), + fmt_specifiers = "{}".repeat(unused.len()) + ), + }; let msg = format!("format specifiers use curly braces, consider adding {msg}"); diag.span_suggestion_verbose(fmt_span, msg, sugg, Applicability::MaybeIncorrect); diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index dd688b8b345..1dd65d38a2b 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -31,7 +31,7 @@ codegen_ssa_cpu_required = target requires explicitly specifying a cpu with `-C codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error} codegen_ssa_dlltool_fail_import_library = - Dlltool could not create import library with {$dlltool_path} {$dlltool_args}: + dlltool could not create import library with {$dlltool_path} {$dlltool_args}: {$stdout} {$stderr} diff --git a/compiler/rustc_codegen_ssa/src/back/command.rs b/compiler/rustc_codegen_ssa/src/back/command.rs index 05351bd6ca3..7420f18aacb 100644 --- a/compiler/rustc_codegen_ssa/src/back/command.rs +++ b/compiler/rustc_codegen_ssa/src/back/command.rs @@ -109,7 +109,7 @@ impl Command { } Program::Lld(ref p, flavor) => { let mut c = process::Command::new(p); - c.arg("-flavor").arg(flavor.as_str()); + c.arg("-flavor").arg(flavor.desc()); c } }; diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 008340e614d..dc500c363f4 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -562,15 +562,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { codegen_fn_attrs } -/// If the provided DefId is a method in a trait impl, return the DefId of the method prototype. -fn opt_trait_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> { - let impl_item = tcx.opt_associated_item(def_id)?; - match impl_item.container { - ty::AssocItemContainer::Impl => impl_item.trait_item_def_id, - _ => None, - } -} - fn disabled_sanitizers_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerSet { // Backtrack to the crate root. let mut disabled = match tcx.opt_local_parent(did) { @@ -600,14 +591,15 @@ fn disabled_sanitizers_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerSet { /// Checks if the provided DefId is a method in a trait impl for a trait which has track_caller /// applied to the method prototype. fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool { - let Some(trait_item) = opt_trait_item(tcx, def_id) else { return false }; - tcx.codegen_fn_attrs(trait_item).flags.intersects(CodegenFnAttrFlags::TRACK_CALLER) + tcx.trait_item_of(def_id).is_some_and(|id| { + tcx.codegen_fn_attrs(id).flags.intersects(CodegenFnAttrFlags::TRACK_CALLER) + }) } /// If the provided DefId is a method in a trait impl, return the value of the `#[align]` /// attribute on the method prototype (if any). fn inherited_align<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Align> { - tcx.codegen_fn_attrs(opt_trait_item(tcx, def_id)?).alignment + tcx.codegen_fn_attrs(tcx.trait_item_of(def_id)?).alignment } /// We now check the #\[rustc_autodiff\] attributes which we generated from the #[autodiff(...)] diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index d00a4c35834..4f875cf99ec 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -668,6 +668,10 @@ fn print_crate_info( TargetSpecJson => { println_info!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap()); } + TargetSpecJsonSchema => { + let schema = rustc_target::spec::json_schema(); + println_info!("{}", serde_json::to_string_pretty(&schema).unwrap()); + } AllTargetSpecsJson => { let mut targets = BTreeMap::new(); for name in rustc_target::spec::TARGETS { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 75551fe4c19..493236718a8 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3220,12 +3220,21 @@ pub struct ImplItem<'hir> { pub owner_id: OwnerId, pub generics: &'hir Generics<'hir>, pub kind: ImplItemKind<'hir>, - pub defaultness: Defaultness, + pub impl_kind: ImplItemImplKind, pub span: Span, - pub vis_span: Span, pub has_delayed_lints: bool, - /// When we are in a trait impl, link to the trait-item's id. - pub trait_item_def_id: Option<DefId>, +} + +#[derive(Debug, Clone, Copy, HashStable_Generic)] +pub enum ImplItemImplKind { + Inherent { + vis_span: Span, + }, + Trait { + defaultness: Defaultness, + /// Item in the trait that this item implements + trait_item_def_id: Result<DefId, ErrorGuaranteed>, + }, } impl<'hir> ImplItem<'hir> { @@ -3239,6 +3248,13 @@ impl<'hir> ImplItem<'hir> { ImplItemId { owner_id: self.owner_id } } + pub fn vis_span(&self) -> Option<Span> { + match self.impl_kind { + ImplItemImplKind::Trait { .. } => None, + ImplItemImplKind::Inherent { vis_span, .. } => Some(vis_span), + } + } + expect_methods_self_kind! { expect_const, (&'hir Ty<'hir>, BodyId), ImplItemKind::Const(ty, body), (ty, *body); expect_fn, (&FnSig<'hir>, BodyId), ImplItemKind::Fn(ty, body), (ty, *body); @@ -4985,7 +5001,7 @@ mod size_asserts { static_assert_size!(GenericBound<'_>, 64); static_assert_size!(Generics<'_>, 56); static_assert_size!(Impl<'_>, 40); - static_assert_size!(ImplItem<'_>, 96); + static_assert_size!(ImplItem<'_>, 88); static_assert_size!(ImplItemKind<'_>, 40); static_assert_size!(Item<'_>, 88); static_assert_size!(ItemKind<'_>, 64); diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 25a7ae239f3..eb682f32111 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1257,18 +1257,21 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>( owner_id: _, ident, ref generics, + ref impl_kind, ref kind, - ref defaultness, span: _, - vis_span: _, has_delayed_lints: _, - trait_item_def_id: _, } = *impl_item; try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_defaultness(defaultness)); try_visit!(visitor.visit_id(impl_item.hir_id())); + match impl_kind { + ImplItemImplKind::Inherent { vis_span: _ } => {} + ImplItemImplKind::Trait { defaultness, trait_item_def_id: _ } => { + try_visit!(visitor.visit_defaultness(defaultness)); + } + } match *kind { ImplItemKind::Const(ref ty, body) => { try_visit!(visitor.visit_ty_unambig(ty)); diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 08b344638dd..886ebddc75c 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1009,8 +1009,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), res = res.and(check_associated_item(tcx, def_id)); let assoc_item = tcx.associated_item(def_id); match assoc_item.container { - ty::AssocItemContainer::Impl => {} - ty::AssocItemContainer::Trait => { + ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {} + ty::AssocContainer::Trait => { res = res.and(check_trait_item(tcx, def_id)); } } @@ -1026,8 +1026,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), res = res.and(check_associated_item(tcx, def_id)); let assoc_item = tcx.associated_item(def_id); match assoc_item.container { - ty::AssocItemContainer::Impl => {} - ty::AssocItemContainer::Trait => { + ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {} + ty::AssocContainer::Trait => { res = res.and(check_trait_item(tcx, def_id)); } } @@ -1043,8 +1043,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), let assoc_item = tcx.associated_item(def_id); let has_type = match assoc_item.container { - ty::AssocItemContainer::Impl => true, - ty::AssocItemContainer::Trait => { + ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => true, + ty::AssocContainer::Trait => { tcx.ensure_ok().explicit_item_bounds(def_id); tcx.ensure_ok().explicit_item_self_bounds(def_id); if tcx.is_conditionally_const(def_id) { @@ -1177,12 +1177,9 @@ fn check_impl_items_against_trait<'tcx>( for &impl_item in impl_item_refs { let ty_impl_item = tcx.associated_item(impl_item); - let ty_trait_item = if let Some(trait_item_id) = ty_impl_item.trait_item_def_id { - tcx.associated_item(trait_item_id) - } else { - // Checked in `associated_item`. - tcx.dcx().span_delayed_bug(tcx.def_span(impl_item), "missing associated item in trait"); - continue; + let ty_trait_item = match ty_impl_item.expect_trait_impl() { + Ok(trait_item_id) => tcx.associated_item(trait_item_id), + Err(ErrorGuaranteed { .. }) => continue, }; let res = tcx.ensure_ok().compare_impl_item(impl_item.expect_local()); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index e4827256193..84fb09b7390 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -37,7 +37,7 @@ pub(super) fn compare_impl_item( impl_item_def_id: LocalDefId, ) -> Result<(), ErrorGuaranteed> { let impl_item = tcx.associated_item(impl_item_def_id); - let trait_item = tcx.associated_item(impl_item.trait_item_def_id.unwrap()); + let trait_item = tcx.associated_item(impl_item.expect_trait_impl()?); let impl_trait_ref = tcx.impl_trait_ref(impl_item.container_id(tcx)).unwrap().instantiate_identity(); debug!(?impl_trait_ref); @@ -446,7 +446,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( impl_m_def_id: LocalDefId, ) -> Result<&'tcx DefIdMap<ty::EarlyBinder<'tcx, Ty<'tcx>>>, ErrorGuaranteed> { let impl_m = tcx.associated_item(impl_m_def_id.to_def_id()); - let trait_m = tcx.associated_item(impl_m.trait_item_def_id.unwrap()); + let trait_m = tcx.associated_item(impl_m.expect_trait_impl()?); let impl_trait_ref = tcx.impl_trait_ref(tcx.parent(impl_m_def_id.to_def_id())).unwrap().instantiate_identity(); // First, check a few of the same things as `compare_impl_method`, @@ -1449,8 +1449,10 @@ fn compare_self_type<'tcx>( let self_string = |method: ty::AssocItem| { let untransformed_self_ty = match method.container { - ty::AssocItemContainer::Impl => impl_trait_ref.self_ty(), - ty::AssocItemContainer::Trait => tcx.types.self_param, + ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => { + impl_trait_ref.self_ty() + } + ty::AssocContainer::Trait => tcx.types.self_param, }; let self_arg_ty = tcx.fn_sig(method.def_id).instantiate_identity().input(0); let (infcx, param_env) = tcx @@ -2458,8 +2460,12 @@ fn param_env_with_gat_bounds<'tcx>( for impl_ty in impl_tys_to_install { let trait_ty = match impl_ty.container { - ty::AssocItemContainer::Trait => impl_ty, - ty::AssocItemContainer::Impl => tcx.associated_item(impl_ty.trait_item_def_id.unwrap()), + ty::AssocContainer::InherentImpl => bug!(), + ty::AssocContainer::Trait => impl_ty, + ty::AssocContainer::TraitImpl(Err(_)) => continue, + ty::AssocContainer::TraitImpl(Ok(trait_item_def_id)) => { + tcx.associated_item(trait_item_def_id) + } }; let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> = diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 22a9446fd4c..d33f1f3e12a 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -944,12 +944,11 @@ pub(crate) fn check_associated_item( // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case // other `Foo` impls are incoherent. - tcx.ensure_ok() - .coherent_trait(tcx.parent(item.trait_item_def_id.unwrap_or(item_id.into())))?; + tcx.ensure_ok().coherent_trait(tcx.parent(item.trait_item_or_self()?))?; let self_ty = match item.container { - ty::AssocItemContainer::Trait => tcx.types.self_param, - ty::AssocItemContainer::Impl => { + ty::AssocContainer::Trait => tcx.types.self_param, + ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => { tcx.type_of(item.container_id(tcx)).instantiate_identity() } }; @@ -978,7 +977,7 @@ pub(crate) fn check_associated_item( check_method_receiver(wfcx, hir_sig, item, self_ty) } ty::AssocKind::Type { .. } => { - if let ty::AssocItemContainer::Trait = item.container { + if let ty::AssocContainer::Trait = item.container { check_associated_type_bounds(wfcx, item, span) } if item.defaultness(tcx).has_value() { diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 126ffabd448..dd3590f9ac5 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -111,9 +111,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen } Some(ImplTraitInTraitData::Impl { fn_def_id }) => { - let assoc_item = tcx.associated_item(def_id); - let trait_assoc_predicates = - tcx.explicit_predicates_of(assoc_item.trait_item_def_id.unwrap()); + let trait_item_def_id = tcx.trait_item_of(def_id).unwrap(); + let trait_assoc_predicates = tcx.explicit_predicates_of(trait_item_def_id); let impl_assoc_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); let impl_def_id = tcx.parent(fn_def_id); diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 62125c99d80..8cbf17162e3 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -125,8 +125,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ Some(ty::ImplTraitInTraitData::Impl { fn_def_id }) => { match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) { Ok(map) => { - let assoc_item = tcx.associated_item(def_id); - return map[&assoc_item.trait_item_def_id.unwrap()]; + let trait_item_def_id = tcx.trait_item_of(def_id).unwrap(); + return map[&trait_item_def_id]; } Err(_) => { return ty::EarlyBinder::bind(Ty::new_error_with_message( @@ -198,7 +198,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ } } ImplItemKind::Type(ty) => { - if tcx.impl_trait_ref(tcx.hir_get_parent_item(hir_id)).is_none() { + if let ImplItemImplKind::Inherent { .. } = item.impl_kind { check_feature_inherent_assoc_ty(tcx, item.span); } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 0b3d50ff219..7370124e800 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1021,7 +1021,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let container_id = assoc_item.container_id(tcx); debug!(?def_id, ?container, ?container_id); match container { - ty::AssocItemContainer::Trait => { + ty::AssocContainer::Trait => { if let Err(e) = callee::check_legal_trait_for_method_call( tcx, path_span, @@ -1033,7 +1033,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.set_tainted_by_errors(e); } } - ty::AssocItemContainer::Impl => { + ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => { if segments.len() == 1 { // `<T>::assoc` will end up here, and so // can `T::assoc`. If this came from an diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 94b635c41b4..44a6084ebd5 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -2354,7 +2354,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We want it to always point to the trait item. // If we're pointing at an inherent function, we don't need to do anything, // so we fetch the parent and verify if it's a trait item. - && let maybe_trait_item_def_id = assoc_item.trait_item_def_id.unwrap_or(def_id) + && let Ok(maybe_trait_item_def_id) = assoc_item.trait_item_or_self() && let maybe_trait_def_id = self.tcx.parent(maybe_trait_item_def_id) // Just an easy way to check "trait_def_id == Fn/FnMut/FnOnce" && let Some(call_kind) = self.tcx.fn_trait_kind_from_def_id(maybe_trait_def_id) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index d7ddbcc8b53..1998a1884b7 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1882,7 +1882,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if segment.ident.name == sym::clone && results.type_dependent_def_id(expr.hir_id).is_some_and(|did| { let assoc_item = self.tcx.associated_item(did); - assoc_item.container == ty::AssocItemContainer::Trait + assoc_item.container == ty::AssocContainer::Trait && assoc_item.container_id(self.tcx) == clone_trait_did }) // If that clone call hasn't already dereferenced the self type (i.e. don't give this diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 129de32fd4a..7f5397a7926 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -278,8 +278,7 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti { if let Some(item) = tcx.opt_associated_item(def_id.into()) && let ty::AssocKind::Const { .. } = item.kind - && let ty::AssocItemContainer::Impl = item.container - && let Some(trait_item_def_id) = item.trait_item_def_id + && let ty::AssocContainer::TraitImpl(Ok(trait_item_def_id)) = item.container { let impl_def_id = item.container_id(tcx); let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity(); diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 52a8eff984b..4185f7f6996 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -18,8 +18,8 @@ use rustc_middle::middle::stability; use rustc_middle::ty::elaborate::supertrait_def_ids; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, simplify_type}; use rustc_middle::ty::{ - self, AssocItem, AssocItemContainer, GenericArgs, GenericArgsRef, GenericParamDefKind, - ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt, Upcast, + self, AssocContainer, AssocItem, GenericArgs, GenericArgsRef, GenericParamDefKind, ParamEnvAnd, + Ty, TyCtxt, TypeVisitableExt, Upcast, }; use rustc_middle::{bug, span_bug}; use rustc_session::lint; @@ -528,7 +528,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ProbeScope::Single(def_id) => { let item = self.tcx.associated_item(def_id); // FIXME(fn_delegation): Delegation to inherent methods is not yet supported. - assert_eq!(item.container, AssocItemContainer::Trait); + assert_eq!(item.container, AssocContainer::Trait); let trait_def_id = self.tcx.parent(def_id); let trait_span = self.tcx.def_span(trait_def_id); @@ -1659,7 +1659,7 @@ impl<'tcx> Pick<'tcx> { /// Do not use for type checking. pub(crate) fn differs_from(&self, other: &Self) -> bool { let Self { - item: AssocItem { def_id, kind: _, container: _, trait_item_def_id: _ }, + item: AssocItem { def_id, kind: _, container: _ }, kind: _, import_ids: _, autoderefs: _, @@ -1702,7 +1702,7 @@ impl<'tcx> Pick<'tcx> { tcx.def_path_str(self.item.def_id), )); } - (ty::AssocKind::Const { name }, ty::AssocItemContainer::Trait) => { + (ty::AssocKind::Const { name }, ty::AssocContainer::Trait) => { let def_id = self.item.container_id(tcx); lint.span_suggestion( span, diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index c3c0a34df71..75a0f89321b 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -29,12 +29,12 @@ use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_hir::intravisit::FnKind as HirFnKind; -use rustc_hir::{Body, FnDecl, PatKind, PredicateOrigin, find_attr}; +use rustc_hir::{Body, FnDecl, ImplItemImplKind, PatKind, PredicateOrigin, find_attr}; use rustc_middle::bug; use rustc_middle::lint::LevelAndSource; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, Upcast, VariantDef}; +use rustc_middle::ty::{self, AssocContainer, Ty, TyCtxt, TypeVisitableExt, Upcast, VariantDef}; use rustc_session::lint::FutureIncompatibilityReason; // hardwired lints from rustc_lint_defs pub use rustc_session::lint::builtin::*; @@ -61,7 +61,6 @@ use crate::lints::{ BuiltinUnreachablePub, BuiltinUnsafe, BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub, BuiltinWhileTrue, InvalidAsmLabel, }; -use crate::nonstandard_style::{MethodLateContext, method_context}; use crate::{ EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext, fluent_generated as fluent, @@ -469,14 +468,14 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) { - let context = method_context(cx, impl_item.owner_id.def_id); + let container = cx.tcx.associated_item(impl_item.owner_id.def_id).container; - match context { + match container { // If the method is an impl for a trait, don't doc. - MethodLateContext::TraitImpl => return, - MethodLateContext::TraitAutoImpl => {} + AssocContainer::TraitImpl(_) => return, + AssocContainer::Trait => {} // If the method is an impl for an item with docs_hidden, don't doc. - MethodLateContext::PlainImpl => { + AssocContainer::InherentImpl => { let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()); let impl_ty = cx.tcx.type_of(parent).instantiate_identity(); let outerdef = match impl_ty.kind() { @@ -1321,9 +1320,8 @@ impl<'tcx> LateLintPass<'tcx> for UnreachablePub { } fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) { - // Only lint inherent impl items. - if cx.tcx.associated_item(impl_item.owner_id).trait_item_def_id.is_none() { - self.perform_lint(cx, "item", impl_item.owner_id.def_id, impl_item.vis_span, false); + if let ImplItemImplKind::Inherent { vis_span } = impl_item.impl_kind { + self.perform_lint(cx, "item", impl_item.owner_id.def_id, vis_span, false); } } } diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 65075cfecfa..7f643a551bb 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{FnKind, Visitor}; use rustc_hir::{Attribute, GenericParamKind, PatExprKind, PatKind, find_attr}; use rustc_middle::hir::nested_filter::All; -use rustc_middle::ty; +use rustc_middle::ty::AssocContainer; use rustc_session::config::CrateType; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::def_id::LocalDefId; @@ -20,29 +20,6 @@ use crate::lints::{ }; use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; -#[derive(PartialEq)] -pub(crate) enum MethodLateContext { - TraitAutoImpl, - TraitImpl, - PlainImpl, -} - -pub(crate) fn method_context(cx: &LateContext<'_>, id: LocalDefId) -> MethodLateContext { - let item = cx.tcx.associated_item(id); - match item.container { - ty::AssocItemContainer::Trait => MethodLateContext::TraitAutoImpl, - ty::AssocItemContainer::Impl => match cx.tcx.impl_trait_ref(item.container_id(cx.tcx)) { - Some(_) => MethodLateContext::TraitImpl, - None => MethodLateContext::PlainImpl, - }, - } -} - -fn assoc_item_in_trait_impl(cx: &LateContext<'_>, ii: &hir::ImplItem<'_>) -> bool { - let item = cx.tcx.associated_item(ii.owner_id); - item.trait_item_def_id.is_some() -} - declare_lint! { /// The `non_camel_case_types` lint detects types, variants, traits and /// type parameters that don't have camel case names. @@ -389,8 +366,8 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { id: LocalDefId, ) { match &fk { - FnKind::Method(ident, sig, ..) => match method_context(cx, id) { - MethodLateContext::PlainImpl => { + FnKind::Method(ident, sig, ..) => match cx.tcx.associated_item(id).container { + AssocContainer::InherentImpl => { if sig.header.abi != ExternAbi::Rust && find_attr!(cx.tcx.get_all_attrs(id), AttributeKind::NoMangle(..)) { @@ -398,10 +375,10 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { } self.check_snake_case(cx, "method", ident); } - MethodLateContext::TraitAutoImpl => { + AssocContainer::Trait => { self.check_snake_case(cx, "trait method", ident); } - _ => (), + AssocContainer::TraitImpl(_) => {} }, FnKind::ItemFn(ident, _, header) => { // Skip foreign-ABI #[no_mangle] functions (Issue #31924) @@ -602,7 +579,7 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals { fn check_impl_item(&mut self, cx: &LateContext<'_>, ii: &hir::ImplItem<'_>) { if let hir::ImplItemKind::Const(..) = ii.kind - && !assoc_item_in_trait_impl(cx, ii) + && let hir::ImplItemImplKind::Inherent { .. } = ii.impl_kind { NonUpperCaseGlobals::check_upper_case(cx, "associated constant", None, &ii.ident); } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 110b26c62ef..0c8d1f32e99 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1194,10 +1194,6 @@ impl<'a> CrateMetadataRef<'a> { self.root.tables.default_fields.get(self, id).map(|d| d.decode(self)) } - fn get_trait_item_def_id(self, id: DefIndex) -> Option<DefId> { - self.root.tables.trait_item_def_id.get(self, id).map(|d| d.decode_from_cdata(self)) - } - fn get_expn_that_defined(self, id: DefIndex, sess: &Session) -> ExpnId { self.root .tables @@ -1359,14 +1355,9 @@ impl<'a> CrateMetadataRef<'a> { } _ => bug!("cannot get associated-item of `{:?}`", self.def_key(id)), }; - let container = self.root.tables.assoc_container.get(self, id).unwrap(); + let container = self.root.tables.assoc_container.get(self, id).unwrap().decode(self); - ty::AssocItem { - kind, - def_id: self.local_def_id(id), - trait_item_def_id: self.get_trait_item_def_id(id), - container, - } + ty::AssocItem { kind, def_id: self.local_def_id(id), container } } fn get_ctor(self, node_id: DefIndex) -> Option<(CtorKind, DefId)> { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index a7e7e9985f4..db66938457f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -22,7 +22,7 @@ use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::mir::interpret; use rustc_middle::query::Providers; use rustc_middle::traits::specialization_graph; -use rustc_middle::ty::AssocItemContainer; +use rustc_middle::ty::AssocContainer; use rustc_middle::ty::codec::TyEncoder; use rustc_middle::ty::fast_reject::{self, TreatParams}; use rustc_middle::{bug, span_bug}; @@ -1254,8 +1254,8 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> DefKind::AssocTy => { let assoc_item = tcx.associated_item(def_id); match assoc_item.container { - ty::AssocItemContainer::Impl => true, - ty::AssocItemContainer::Trait => assoc_item.defaultness(tcx).has_value(), + ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => true, + ty::AssocContainer::Trait => assoc_item.defaultness(tcx).has_value(), } } DefKind::TyParam => { @@ -1725,24 +1725,20 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let tcx = self.tcx; let item = tcx.associated_item(def_id); - self.tables.defaultness.set_some(def_id.index, item.defaultness(tcx)); - self.tables.assoc_container.set_some(def_id.index, item.container); - - match item.container { - AssocItemContainer::Trait => { - if item.is_type() { - self.encode_explicit_item_bounds(def_id); - self.encode_explicit_item_self_bounds(def_id); - if tcx.is_conditionally_const(def_id) { - record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id] - <- self.tcx.explicit_implied_const_bounds(def_id).skip_binder()); - } - } - } - AssocItemContainer::Impl => { - if let Some(trait_item_def_id) = item.trait_item_def_id { - self.tables.trait_item_def_id.set_some(def_id.index, trait_item_def_id.into()); - } + if matches!(item.container, AssocContainer::Trait | AssocContainer::TraitImpl(_)) { + self.tables.defaultness.set_some(def_id.index, item.defaultness(tcx)); + } + + record!(self.tables.assoc_container[def_id] <- item.container); + + if let AssocContainer::Trait = item.container + && item.is_type() + { + self.encode_explicit_item_bounds(def_id); + self.encode_explicit_item_self_bounds(def_id); + if tcx.is_conditionally_const(def_id) { + record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id] + <- self.tcx.explicit_implied_const_bounds(def_id).skip_binder()); } } if let ty::AssocKind::Type { data: ty::AssocTypeData::Rpitit(rpitit_info) } = item.kind { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 1f7d142d330..720970bbaf9 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -447,7 +447,6 @@ define_tables! { coroutine_by_move_body_def_id: Table<DefIndex, RawDefId>, eval_static_initializer: Table<DefIndex, LazyValue<mir::interpret::ConstAllocation<'static>>>, trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>, - trait_item_def_id: Table<DefIndex, RawDefId>, expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>, default_fields: Table<DefIndex, LazyValue<DefId>>, params_in_repr: Table<DefIndex, LazyValue<DenseBitSet<u32>>>, @@ -459,7 +458,7 @@ define_tables! { def_keys: Table<DefIndex, LazyValue<DefKey>>, proc_macro_quoted_spans: Table<usize, LazyValue<Span>>, variant_data: Table<DefIndex, LazyValue<VariantData>>, - assoc_container: Table<DefIndex, ty::AssocItemContainer>, + assoc_container: Table<DefIndex, LazyValue<ty::AssocContainer>>, macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>, proc_macro: Table<DefIndex, MacroKind>, deduced_param_attrs: Table<DefIndex, LazyArray<DeducedParamAttrs>>, diff --git a/compiler/rustc_metadata/src/rmeta/parameterized.rs b/compiler/rustc_metadata/src/rmeta/parameterized.rs index 34180001f80..4b2dc2c814e 100644 --- a/compiler/rustc_metadata/src/rmeta/parameterized.rs +++ b/compiler/rustc_metadata/src/rmeta/parameterized.rs @@ -102,7 +102,7 @@ trivially_parameterized_over_tcx! { rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault, rustc_middle::mir::ConstQualifs, rustc_middle::ty::AnonConstKind, - rustc_middle::ty::AssocItemContainer, + rustc_middle::ty::AssocContainer, rustc_middle::ty::AsyncDestructor, rustc_middle::ty::Asyncness, rustc_middle::ty::DeducedParamAttrs, diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 2cb07a28a8a..a882ee4f2b9 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -222,13 +222,6 @@ fixed_size_enum! { } fixed_size_enum! { - ty::AssocItemContainer { - ( Trait ) - ( Impl ) - } -} - -fixed_size_enum! { MacroKind { ( Attr ) ( Bang ) diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index bea2191c560..4c00b769237 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -318,7 +318,7 @@ trivial! { rustc_middle::traits::WellFormedLoc, rustc_middle::ty::adjustment::CoerceUnsizedInfo, rustc_middle::ty::AssocItem, - rustc_middle::ty::AssocItemContainer, + rustc_middle::ty::AssocContainer, rustc_middle::ty::Asyncness, rustc_middle::ty::AsyncDestructor, rustc_middle::ty::BoundVariableKind, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 2aa32dfa0d8..0e645a3aae4 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1881,6 +1881,7 @@ rustc_queries! { } /// Returns whether the impl or associated function has the `default` keyword. + /// Note: This will ICE on inherent impl items. Consider using `AssocItem::defaultness`. query defaultness(def_id: DefId) -> hir::Defaultness { desc { |tcx| "looking up whether `{}` has `default`", tcx.def_path_str(def_id) } separate_provide_extern diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index a902a8a61e5..768646c7630 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -5,15 +5,17 @@ use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::def_id::DefId; use rustc_hir::find_attr; use rustc_macros::{Decodable, Encodable, HashStable}; -use rustc_span::{Ident, Symbol}; +use rustc_span::{ErrorGuaranteed, Ident, Symbol}; use super::{TyCtxt, Visibility}; use crate::ty; #[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable, Hash, Encodable, Decodable)] -pub enum AssocItemContainer { +pub enum AssocContainer { Trait, - Impl, + InherentImpl, + /// The `DefId` points to the trait item being implemented. + TraitImpl(Result<DefId, ErrorGuaranteed>), } /// Information about an associated item @@ -21,11 +23,7 @@ pub enum AssocItemContainer { pub struct AssocItem { pub def_id: DefId, pub kind: AssocKind, - pub container: AssocItemContainer, - - /// If this is an item in an impl of a trait then this is the `DefId` of - /// the associated item on the trait that this implements. - pub trait_item_def_id: Option<DefId>, + pub container: AssocContainer, } impl AssocItem { @@ -55,7 +53,34 @@ impl AssocItem { /// /// [`type_of`]: crate::ty::TyCtxt::type_of pub fn defaultness(&self, tcx: TyCtxt<'_>) -> hir::Defaultness { - tcx.defaultness(self.def_id) + match self.container { + AssocContainer::InherentImpl => hir::Defaultness::Final, + AssocContainer::Trait | AssocContainer::TraitImpl(_) => tcx.defaultness(self.def_id), + } + } + + pub fn expect_trait_impl(&self) -> Result<DefId, ErrorGuaranteed> { + let AssocContainer::TraitImpl(trait_item_id) = self.container else { + bug!("expected item to be in a trait impl: {:?}", self.def_id); + }; + trait_item_id + } + + /// If this is a trait impl item, returns the `DefId` of the trait item this implements. + /// Otherwise, returns `DefId` for self. Returns an Err in case the trait item was not + /// resolved successfully. + pub fn trait_item_or_self(&self) -> Result<DefId, ErrorGuaranteed> { + match self.container { + AssocContainer::TraitImpl(id) => id, + AssocContainer::Trait | AssocContainer::InherentImpl => Ok(self.def_id), + } + } + + pub fn trait_item_def_id(&self) -> Option<DefId> { + match self.container { + AssocContainer::TraitImpl(Ok(id)) => Some(id), + _ => None, + } } #[inline] @@ -71,16 +96,18 @@ impl AssocItem { #[inline] pub fn trait_container(&self, tcx: TyCtxt<'_>) -> Option<DefId> { match self.container { - AssocItemContainer::Impl => None, - AssocItemContainer::Trait => Some(tcx.parent(self.def_id)), + AssocContainer::InherentImpl | AssocContainer::TraitImpl(_) => None, + AssocContainer::Trait => Some(tcx.parent(self.def_id)), } } #[inline] pub fn impl_container(&self, tcx: TyCtxt<'_>) -> Option<DefId> { match self.container { - AssocItemContainer::Impl => Some(tcx.parent(self.def_id)), - AssocItemContainer::Trait => None, + AssocContainer::InherentImpl | AssocContainer::TraitImpl(_) => { + Some(tcx.parent(self.def_id)) + } + AssocContainer::Trait => None, } } @@ -156,11 +183,11 @@ impl AssocItem { return false; } - let def_id = match (self.container, self.trait_item_def_id) { - (AssocItemContainer::Trait, _) => self.def_id, - (AssocItemContainer::Impl, Some(trait_item_did)) => trait_item_did, - // Inherent impl but this attr is only applied to trait assoc items. - (AssocItemContainer::Impl, None) => return true, + let def_id = match self.container { + AssocContainer::Trait => self.def_id, + AssocContainer::TraitImpl(Ok(trait_item_did)) => trait_item_did, + AssocContainer::TraitImpl(Err(_)) => return false, + AssocContainer::InherentImpl => return true, }; find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 8ea767dccd3..79700d485c4 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2276,7 +2276,16 @@ impl<'tcx> TyCtxt<'tcx> { let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) { Node::Item(..) | Node::TraitItem(..) => false, - Node::ImplItem(..) => self.is_bound_region_in_impl_item(suitable_region_binding_scope), + Node::ImplItem(impl_item) => match impl_item.impl_kind { + // For now, we do not try to target impls of traits. This is + // because this message is going to suggest that the user + // change the fn signature, but they may not be free to do so, + // since the signature must match the trait. + // + // FIXME(#42706) -- in some cases, we could do better here. + hir::ImplItemImplKind::Trait { .. } => true, + _ => false, + }, _ => false, }; @@ -2330,21 +2339,6 @@ impl<'tcx> TyCtxt<'tcx> { None } - /// Checks if the bound region is in Impl Item. - pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool { - let container_id = self.parent(suitable_region_binding_scope.to_def_id()); - if self.impl_trait_ref(container_id).is_some() { - // For now, we do not try to target impls of traits. This is - // because this message is going to suggest that the user - // change the fn signature, but they may not be free to do so, - // since the signature must match the trait. - // - // FIXME(#42706) -- in some cases, we could do better here. - return true; - } - false - } - /// Determines whether identifiers in the assembly have strict naming rules. /// Currently, only NVPTX* targets need it. pub fn has_strict_asm_symbol_naming(self) -> bool { diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index e76993e0542..34ead91b4f6 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -18,8 +18,8 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::ty::normalize_erasing_regions::NormalizationError; use crate::ty::print::{FmtPrinter, Print}; use crate::ty::{ - self, EarlyBinder, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, - TypeVisitable, TypeVisitableExt, TypeVisitor, + self, AssocContainer, EarlyBinder, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable, + TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; /// An `InstanceKind` along with the args that are needed to substitute the instance. @@ -611,26 +611,23 @@ impl<'tcx> Instance<'tcx> { debug!(" => fn pointer created for virtual call"); resolved.def = InstanceKind::ReifyShim(def_id, reason); } - // Reify `Trait::method` implementations if KCFI is enabled - // FIXME(maurer) only reify it if it is a vtable-safe function - _ if tcx.sess.is_sanitizer_kcfi_enabled() - && tcx - .opt_associated_item(def_id) - .and_then(|assoc| assoc.trait_item_def_id) - .is_some() => - { - // If this function could also go in a vtable, we need to `ReifyShim` it with - // KCFI because it can only attach one type per function. - resolved.def = InstanceKind::ReifyShim(resolved.def_id(), reason) - } - // Reify `::call`-like method implementations if KCFI is enabled - _ if tcx.sess.is_sanitizer_kcfi_enabled() - && tcx.is_closure_like(resolved.def_id()) => - { - // Reroute through a reify via the *unresolved* instance. The resolved one can't - // be directly reified because it's closure-like. The reify can handle the - // unresolved instance. - resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args } + _ if tcx.sess.is_sanitizer_kcfi_enabled() => { + // Reify `::call`-like method implementations + if tcx.is_closure_like(resolved.def_id()) { + // Reroute through a reify via the *unresolved* instance. The resolved one can't + // be directly reified because it's closure-like. The reify can handle the + // unresolved instance. + resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args } + // Reify `Trait::method` implementations + // FIXME(maurer) only reify it if it is a vtable-safe function + } else if let Some(assoc) = tcx.opt_associated_item(def_id) + && let AssocContainer::Trait | AssocContainer::TraitImpl(Ok(_)) = + assoc.container + { + // If this function could also go in a vtable, we need to `ReifyShim` it with + // KCFI because it can only attach one type per function. + resolved.def = InstanceKind::ReifyShim(resolved.def_id(), reason) + } } _ => {} } @@ -683,7 +680,7 @@ impl<'tcx> Instance<'tcx> { && !matches!( tcx.opt_associated_item(def), Some(ty::AssocItem { - container: ty::AssocItemContainer::Trait, + container: ty::AssocContainer::Trait, .. }) ); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index da17ec1f9f3..d4c001f625e 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1934,6 +1934,11 @@ impl<'tcx> TyCtxt<'tcx> { Some((parent, def_kind)) } + /// Returns the trait item that is implemented by the given item `DefId`. + pub fn trait_item_of(self, def_id: impl IntoQueryParam<DefId>) -> Option<DefId> { + self.opt_associated_item(def_id.into_query_param())?.trait_item_def_id() + } + /// If the given `DefId` is an associated item of a trait, /// returns the `DefId` of the trait; otherwise, returns `None`. pub fn trait_of_assoc(self, def_id: DefId) -> Option<DefId> { @@ -2149,17 +2154,12 @@ impl<'tcx> TyCtxt<'tcx> { let Some(item) = self.opt_associated_item(def_id) else { return false; }; - if item.container != ty::AssocItemContainer::Impl { - return false; - } - let Some(trait_item_def_id) = item.trait_item_def_id else { + let AssocContainer::TraitImpl(Ok(trait_item_def_id)) = item.container else { return false; }; - return !self - .associated_types_for_impl_traits_in_associated_fn(trait_item_def_id) - .is_empty(); + !self.associated_types_for_impl_traits_in_associated_fn(trait_item_def_id).is_empty() } } diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index ab7885905a6..75537caa894 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -75,7 +75,7 @@ passes_const_stable_not_stable = .label = attribute specified here passes_custom_mir_incompatible_dialect_and_phase = - The {$dialect} dialect is not compatible with the {$phase} phase + the {$dialect} dialect is not compatible with the {$phase} phase .dialect_span = this dialect... .phase_span = ... is not compatible with this phase diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index fc33405d455..3c2c9683a4d 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -373,31 +373,27 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { /// Automatically generated items marked with `rustc_trivial_field_reads` /// will be ignored for the purposes of dead code analysis (see PR #85200 /// for discussion). - fn should_ignore_item(&mut self, def_id: DefId) -> bool { - if let Some(impl_of) = self.tcx.trait_impl_of_assoc(def_id) { - if !self.tcx.is_automatically_derived(impl_of) { - return false; - } - - if let Some(trait_of) = self.tcx.trait_id_of_impl(impl_of) - && self.tcx.has_attr(trait_of, sym::rustc_trivial_field_reads) + fn should_ignore_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) -> bool { + if let hir::ImplItemImplKind::Trait { .. } = impl_item.impl_kind + && let impl_of = self.tcx.parent(impl_item.owner_id.to_def_id()) + && self.tcx.is_automatically_derived(impl_of) + && let trait_ref = self.tcx.impl_trait_ref(impl_of).unwrap().instantiate_identity() + && self.tcx.has_attr(trait_ref.def_id, sym::rustc_trivial_field_reads) + { + if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind() + && let Some(adt_def_id) = adt_def.did().as_local() { - let trait_ref = self.tcx.impl_trait_ref(impl_of).unwrap().instantiate_identity(); - if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind() - && let Some(adt_def_id) = adt_def.did().as_local() - { - self.ignored_derived_traits.entry(adt_def_id).or_default().insert(trait_of); - } - return true; + self.ignored_derived_traits.entry(adt_def_id).or_default().insert(trait_ref.def_id); } + return true; } false } fn visit_node(&mut self, node: Node<'tcx>) { - if let Node::ImplItem(hir::ImplItem { owner_id, .. }) = node - && self.should_ignore_item(owner_id.to_def_id()) + if let Node::ImplItem(impl_item) = node + && self.should_ignore_impl_item(impl_item) { return; } @@ -439,7 +435,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } Node::ImplItem(impl_item) => { let item = self.tcx.local_parent(impl_item.owner_id.def_id); - if self.tcx.impl_trait_ref(item).is_none() { + if let hir::ImplItemImplKind::Inherent { .. } = impl_item.impl_kind { //// If it's a type whose items are live, then it's live, too. //// This is done to handle the case where, for example, the static //// method of a private type is used, but the type itself is never @@ -484,13 +480,11 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { fn check_impl_or_impl_item_live(&mut self, local_def_id: LocalDefId) -> bool { let (impl_block_id, trait_def_id) = match self.tcx.def_kind(local_def_id) { // assoc impl items of traits are live if the corresponding trait items are live - DefKind::AssocConst | DefKind::AssocTy | DefKind::AssocFn => ( - self.tcx.local_parent(local_def_id), - self.tcx - .associated_item(local_def_id) - .trait_item_def_id - .and_then(|def_id| def_id.as_local()), - ), + DefKind::AssocConst | DefKind::AssocTy | DefKind::AssocFn => { + let trait_item_id = + self.tcx.trait_item_of(local_def_id).and_then(|def_id| def_id.as_local()); + (self.tcx.local_parent(local_def_id), trait_item_id) + } // impl items are live if the corresponding traits are live DefKind::Impl { of_trait: true } => ( local_def_id, diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 71650c6b9b9..2ee1bd0dfd1 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -21,8 +21,8 @@ use rustc_middle::middle::lib_features::{FeatureStability, LibFeatures}; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::middle::stability::{AllowUnstable, Deprecated, DeprecationEntry, EvalResult}; use rustc_middle::query::{LocalCrate, Providers}; -use rustc_middle::ty::TyCtxt; use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_middle::ty::{AssocContainer, TyCtxt}; use rustc_session::lint; use rustc_session::lint::builtin::{DEPRECATED, INEFFECTIVE_UNSTABLE_TRAIT_IMPL}; use rustc_span::{Span, Symbol, sym}; @@ -486,8 +486,7 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> { fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) { self.check_compatible_stability(ii.owner_id.def_id); - let impl_def_id = self.tcx.hir_get_parent_item(ii.hir_id()); - if self.tcx.impl_trait_ref(impl_def_id).is_none() { + if let hir::ImplItemImplKind::Inherent { .. } = ii.impl_kind { self.check_missing_stability(ii.owner_id.def_id); self.check_missing_const_stability(ii.owner_id.def_id); } @@ -711,7 +710,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { for impl_item_ref in items { let impl_item = self.tcx.associated_item(impl_item_ref.owner_id); - if let Some(def_id) = impl_item.trait_item_def_id { + if let AssocContainer::TraitImpl(Ok(def_id)) = impl_item.container { // Pass `None` to skip deprecation warnings. self.tcx.check_stability( def_id, diff --git a/compiler/rustc_public/src/ty.rs b/compiler/rustc_public/src/ty.rs index 1b5f0ed1429..bcc77ff849d 100644 --- a/compiler/rustc_public/src/ty.rs +++ b/compiler/rustc_public/src/ty.rs @@ -1612,11 +1612,7 @@ crate_def! { pub struct AssocItem { pub def_id: AssocDef, pub kind: AssocKind, - pub container: AssocItemContainer, - - /// If this is an item in an impl of a trait then this is the `DefId` of - /// the associated item on the trait that this implements. - pub trait_item_def_id: Option<AssocDef>, + pub container: AssocContainer, } #[derive(Clone, PartialEq, Debug, Eq, Serialize)] @@ -1636,9 +1632,11 @@ pub enum AssocKind { } #[derive(Clone, Debug, Eq, PartialEq, Serialize)] -pub enum AssocItemContainer { +pub enum AssocContainer { + InherentImpl, + /// The `AssocDef` points to the trait item being implemented. + TraitImpl(AssocDef), Trait, - Impl, } #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)] diff --git a/compiler/rustc_public/src/unstable/convert/stable/ty.rs b/compiler/rustc_public/src/unstable/convert/stable/ty.rs index 207038db40d..5131611eb02 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/ty.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/ty.rs @@ -1076,14 +1076,21 @@ impl<'tcx> Stable<'tcx> for ty::AssocKind { } } -impl<'tcx> Stable<'tcx> for ty::AssocItemContainer { - type T = crate::ty::AssocItemContainer; +impl<'tcx> Stable<'tcx> for ty::AssocContainer { + type T = crate::ty::AssocContainer; - fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T { - use crate::ty::AssocItemContainer; + fn stable( + &self, + tables: &mut Tables<'_, BridgeTys>, + _: &CompilerCtxt<'_, BridgeTys>, + ) -> Self::T { + use crate::ty::AssocContainer; match self { - ty::AssocItemContainer::Trait => AssocItemContainer::Trait, - ty::AssocItemContainer::Impl => AssocItemContainer::Impl, + ty::AssocContainer::Trait => AssocContainer::Trait, + ty::AssocContainer::InherentImpl => AssocContainer::InherentImpl, + ty::AssocContainer::TraitImpl(trait_item_id) => { + AssocContainer::TraitImpl(tables.assoc_def(trait_item_id.unwrap())) + } } } } @@ -1100,7 +1107,6 @@ impl<'tcx> Stable<'tcx> for ty::AssocItem { def_id: tables.assoc_def(self.def_id), kind: self.kind.stable(tables, cx), container: self.container.stable(tables, cx), - trait_item_def_id: self.trait_item_def_id.map(|did| tables.assoc_def(did)), } } } diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index d81fa062e01..577a16a0d25 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -469,8 +469,7 @@ fn implemented_method<'tcx>( let ancestor = if let Some(impl_id) = tcx.impl_of_assoc(instance.def_id()) { // Implementation in an `impl` block trait_ref = tcx.impl_trait_ref(impl_id)?; - let impl_method = tcx.associated_item(instance.def_id()); - method_id = impl_method.trait_item_def_id?; + method_id = tcx.trait_item_of(instance.def_id())?; trait_method = tcx.associated_item(method_id); trait_id = trait_ref.skip_binder().def_id; impl_id diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 9793d8091e2..297df7c2c97 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -70,6 +70,7 @@ pub const PRINT_KINDS: &[(&str, PrintKind)] = &[ ("target-libdir", PrintKind::TargetLibdir), ("target-list", PrintKind::TargetList), ("target-spec-json", PrintKind::TargetSpecJson), + ("target-spec-json-schema", PrintKind::TargetSpecJsonSchema), ("tls-models", PrintKind::TlsModels), // tidy-alphabetical-end ]; @@ -1043,6 +1044,7 @@ pub enum PrintKind { TargetLibdir, TargetList, TargetSpecJson, + TargetSpecJsonSchema, TlsModels, // tidy-alphabetical-end } @@ -2323,7 +2325,8 @@ fn is_print_request_stable(print_kind: PrintKind) -> bool { | PrintKind::CheckCfg | PrintKind::CrateRootLintLevels | PrintKind::SupportedCrateTypes - | PrintKind::TargetSpecJson => false, + | PrintKind::TargetSpecJson + | PrintKind::TargetSpecJsonSchema => false, _ => true, } } diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 19494ffc37e..633cbc3a4ae 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -46,6 +46,8 @@ use crate::symbol::{Symbol, kw, sym}; use crate::{DUMMY_SP, HashStableContext, Span, SpanDecoder, SpanEncoder, with_session_globals}; /// A `SyntaxContext` represents a chain of pairs `(ExpnId, Transparency)` named "marks". +/// +/// See <https://rustc-dev-guide.rust-lang.org/macro-expansion.html> for more explanation. #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct SyntaxContext(u32); @@ -61,7 +63,10 @@ pub type SyntaxContextKey = (SyntaxContext, ExpnId, Transparency); #[derive(Clone, Copy, Debug)] struct SyntaxContextData { + /// The last macro expansion in the chain. + /// (Here we say the most deeply nested macro expansion is the "outermost" expansion.) outer_expn: ExpnId, + /// Transparency of the last macro expansion outer_transparency: Transparency, parent: SyntaxContext, /// This context, but with all transparent and semi-opaque expansions filtered away. @@ -450,11 +455,13 @@ impl HygieneData { self.syntax_context_data[ctxt.0 as usize].opaque_and_semiopaque } + /// See [`SyntaxContextData::outer_expn`] #[inline] fn outer_expn(&self, ctxt: SyntaxContext) -> ExpnId { self.syntax_context_data[ctxt.0 as usize].outer_expn } + /// The last macro expansion and its Transparency #[inline] fn outer_mark(&self, ctxt: SyntaxContext) -> (ExpnId, Transparency) { let data = &self.syntax_context_data[ctxt.0 as usize]; @@ -900,6 +907,7 @@ impl SyntaxContext { HygieneData::with(|data| data.normalize_to_macro_rules(self)) } + /// See [`SyntaxContextData::outer_expn`] #[inline] pub fn outer_expn(self) -> ExpnId { HygieneData::with(|data| data.outer_expn(self)) @@ -912,6 +920,7 @@ impl SyntaxContext { HygieneData::with(|data| data.expn_data(data.outer_expn(self)).clone()) } + /// See [`HygieneData::outer_mark`] #[inline] fn outer_mark(self) -> (ExpnId, Transparency) { HygieneData::with(|data| data.outer_mark(self)) @@ -982,19 +991,20 @@ impl Span { #[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic)] pub struct ExpnData { // --- The part unique to each expansion. - /// The kind of this expansion - macro or compiler desugaring. pub kind: ExpnKind, - /// The expansion that produced this expansion. + /// The expansion that contains the definition of the macro for this expansion. pub parent: ExpnId, - /// The location of the actual macro invocation or syntax sugar , e.g. - /// `let x = foo!();` or `if let Some(y) = x {}` + /// The span of the macro call which produced this expansion. + /// + /// This span will typically have a different `ExpnData` and `call_site`. + /// This recursively traces back through any macro calls which expanded into further + /// macro calls, until the "source call-site" is reached at the root SyntaxContext. + /// For example, if `food!()` expands to `fruit!()` which then expands to `grape`, + /// then the call-site of `grape` is `fruit!()` and the call-site of `fruit!()` + /// is `food!()`. /// - /// This may recursively refer to other macro invocations, e.g., if - /// `foo!()` invoked `bar!()` internally, and there was an - /// expression inside `bar!`; the call_site of the expression in - /// the expansion would point to the `bar!` invocation; that - /// call_site span would have its own ExpnData, with the call_site - /// pointing to the `foo!` invocation. + /// For a desugaring expansion, this is the span of the expression or node that was + /// desugared. pub call_site: Span, /// Used to force two `ExpnData`s to have different `Fingerprint`s. /// Due to macro expansion, it's possible to end up with two `ExpnId`s diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index ae6755f0764..e95b743b1ce 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -710,8 +710,8 @@ impl Span { if !ctxt.is_root() { ctxt.outer_expn_data().call_site.source_callsite() } else { self } } - /// The `Span` for the tokens in the previous macro expansion from which `self` was generated, - /// if any. + /// Returns the call-site span of the last macro expansion which produced this `Span`. + /// (see [`ExpnData::call_site`]). Returns `None` if this is not an expansion. pub fn parent_callsite(self) -> Option<Span> { let ctxt = self.ctxt(); (!ctxt.is_root()).then(|| ctxt.outer_expn_data().call_site) diff --git a/compiler/rustc_target/Cargo.toml b/compiler/rustc_target/Cargo.toml index 7fabb227d9a..ecdb6ab5a57 100644 --- a/compiler/rustc_target/Cargo.toml +++ b/compiler/rustc_target/Cargo.toml @@ -14,6 +14,7 @@ rustc_fs_util = { path = "../rustc_fs_util" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } +schemars = "1.0.4" serde = "1.0.219" serde_derive = "1.0.219" serde_json = "1.0.59" diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index 91657fef803..b3fe1fffcce 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -72,3 +72,65 @@ fn find_relative_libdir(sysroot: &Path) -> std::borrow::Cow<'static, str> { Some(libdir) => libdir.into(), } } + +macro_rules! target_spec_enum { + ( + $( #[$attr:meta] )* + pub enum $name:ident { + $( + $( #[$variant_attr:meta] )* + $variant:ident = $string:literal, + )* + } + parse_error_type = $parse_error_type:literal; + ) => { + $( #[$attr] )* + #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)] + #[derive(schemars::JsonSchema)] + pub enum $name { + $( + $( #[$variant_attr] )* + #[serde(rename = $string)] // for JSON schema generation only + $variant, + )* + } + + impl FromStr for $name { + type Err = String; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + Ok(match s { + $( $string => Self::$variant, )* + _ => { + let all = [$( concat!("'", $string, "'") ),*].join(", "); + return Err(format!("invalid {}: '{s}'. allowed values: {all}", $parse_error_type)); + } + }) + } + } + + impl $name { + pub fn desc(&self) -> &'static str { + match self { + $( Self::$variant => $string, )* + } + } + } + + impl crate::json::ToJson for $name { + fn to_json(&self) -> crate::json::Json { + self.desc().to_json() + } + } + + crate::json::serde_deserialize_from_str!($name); + + + impl std::fmt::Display for $name { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.desc()) + } + } + }; +} +use target_spec_enum; diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs index e9ae5734d5b..f236be92b3b 100644 --- a/compiler/rustc_target/src/spec/json.rs +++ b/compiler/rustc_target/src/spec/json.rs @@ -408,12 +408,12 @@ impl ToJson for Target { } } -#[derive(serde_derive::Deserialize)] +#[derive(serde_derive::Deserialize, schemars::JsonSchema)] struct LinkSelfContainedComponentsWrapper { components: Vec<LinkSelfContainedComponents>, } -#[derive(serde_derive::Deserialize)] +#[derive(serde_derive::Deserialize, schemars::JsonSchema)] #[serde(untagged)] enum TargetFamiliesJson { Array(StaticCow<[StaticCow<str>]>), @@ -429,6 +429,18 @@ impl FromStr for EndianWrapper { } } crate::json::serde_deserialize_from_str!(EndianWrapper); +impl schemars::JsonSchema for EndianWrapper { + fn schema_name() -> std::borrow::Cow<'static, str> { + "Endian".into() + } + fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema { + schemars::json_schema! ({ + "type": "string", + "enum": ["big", "little"] + }) + .into() + } +} /// `ExternAbi` is in `rustc_abi`, which doesn't have access to the macro and serde. struct ExternAbiWrapper(rustc_abi::ExternAbi); @@ -441,8 +453,22 @@ impl FromStr for ExternAbiWrapper { } } crate::json::serde_deserialize_from_str!(ExternAbiWrapper); +impl schemars::JsonSchema for ExternAbiWrapper { + fn schema_name() -> std::borrow::Cow<'static, str> { + "ExternAbi".into() + } + fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema { + let all = + rustc_abi::ExternAbi::ALL_VARIANTS.iter().map(|abi| abi.as_str()).collect::<Vec<_>>(); + schemars::json_schema! ({ + "type": "string", + "enum": all, + }) + .into() + } +} -#[derive(serde_derive::Deserialize)] +#[derive(serde_derive::Deserialize, schemars::JsonSchema)] struct TargetSpecJsonMetadata { description: Option<StaticCow<str>>, tier: Option<u64>, @@ -450,7 +476,7 @@ struct TargetSpecJsonMetadata { std: Option<bool>, } -#[derive(serde_derive::Deserialize)] +#[derive(serde_derive::Deserialize, schemars::JsonSchema)] #[serde(rename_all = "kebab-case")] // Ensure that all unexpected fields get turned into errors. // This helps users stay up to date when the schema changes instead of silently @@ -593,3 +619,7 @@ struct TargetSpecJson { supports_xray: Option<bool>, entry_abi: Option<ExternAbiWrapper>, } + +pub fn json_schema() -> schemars::Schema { + schemars::schema_for!(TargetSpecJson) +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 4d9f06c568b..07fb1ce63f7 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -70,6 +70,7 @@ mod json; pub use abi_map::{AbiMap, AbiMapping}; pub use base::apple; pub use base::avr::ef_avr_arch; +pub use json::json_schema; /// Linker is called through a C/C++ compiler. #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] @@ -183,50 +184,15 @@ impl LinkerFlavorCli { } } -#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] -pub enum LldFlavor { - Wasm, - Ld64, - Ld, - Link, -} - -impl LldFlavor { - pub fn as_str(&self) -> &'static str { - match self { - LldFlavor::Wasm => "wasm", - LldFlavor::Ld64 => "darwin", - LldFlavor::Ld => "gnu", - LldFlavor::Link => "link", - } - } -} - -impl FromStr for LldFlavor { - type Err = String; - - fn from_str(s: &str) -> Result<Self, Self::Err> { - Ok(match s { - "darwin" => LldFlavor::Ld64, - "gnu" => LldFlavor::Ld, - "link" => LldFlavor::Link, - "wasm" => LldFlavor::Wasm, - _ => { - return Err( - "invalid value for lld flavor: '{s}', expected one of 'darwin', 'gnu', 'link', 'wasm'" - .into(), - ); - } - }) +crate::target_spec_enum! { + pub enum LldFlavor { + Wasm = "wasm", + Ld64 = "darwin", + Ld = "gnu", + Link = "link", } -} -crate::json::serde_deserialize_from_str!(LldFlavor); - -impl ToJson for LldFlavor { - fn to_json(&self) -> Json { - self.as_str().to_json() - } + parse_error_type = "LLD flavor"; } impl LinkerFlavor { @@ -558,6 +524,20 @@ linker_flavor_cli_impls! { } crate::json::serde_deserialize_from_str!(LinkerFlavorCli); +impl schemars::JsonSchema for LinkerFlavorCli { + fn schema_name() -> std::borrow::Cow<'static, str> { + "LinkerFlavor".into() + } + fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema { + let all: Vec<&'static str> = + Self::all().iter().map(|flavor| flavor.desc()).collect::<Vec<_>>(); + schemars::json_schema! ({ + "type": "string", + "enum": all + }) + .into() + } +} impl ToJson for LinkerFlavorCli { fn to_json(&self) -> Json { @@ -611,6 +591,18 @@ impl FromStr for LinkSelfContainedDefault { } crate::json::serde_deserialize_from_str!(LinkSelfContainedDefault); +impl schemars::JsonSchema for LinkSelfContainedDefault { + fn schema_name() -> std::borrow::Cow<'static, str> { + "LinkSelfContainedDefault".into() + } + fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema { + schemars::json_schema! ({ + "type": "string", + "enum": ["false", "true", "wasm", "musl", "mingw"] + }) + .into() + } +} impl ToJson for LinkSelfContainedDefault { fn to_json(&self) -> Json { @@ -743,6 +735,20 @@ impl FromStr for LinkSelfContainedComponents { } crate::json::serde_deserialize_from_str!(LinkSelfContainedComponents); +impl schemars::JsonSchema for LinkSelfContainedComponents { + fn schema_name() -> std::borrow::Cow<'static, str> { + "LinkSelfContainedComponents".into() + } + fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema { + let all = + Self::all_components().iter().map(|component| component.as_str()).collect::<Vec<_>>(); + schemars::json_schema! ({ + "type": "string", + "enum": all, + }) + .into() + } +} impl ToJson for LinkSelfContainedComponents { fn to_json(&self) -> Json { @@ -823,10 +829,14 @@ impl LinkerFeatures { } } -#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable, HashStable_Generic)] -pub enum PanicStrategy { - Unwind, - Abort, +crate::target_spec_enum! { + #[derive(Encodable, Decodable, HashStable_Generic)] + pub enum PanicStrategy { + Unwind = "unwind", + Abort = "abort", + } + + parse_error_type = "panic strategy"; } #[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable, HashStable_Generic)] @@ -838,13 +848,6 @@ pub enum OnBrokenPipe { } impl PanicStrategy { - pub fn desc(&self) -> &str { - match *self { - PanicStrategy::Unwind => "unwind", - PanicStrategy::Abort => "abort", - } - } - pub const fn desc_symbol(&self) -> Symbol { match *self { PanicStrategy::Unwind => sym::unwind, @@ -857,24 +860,16 @@ impl PanicStrategy { } } -impl FromStr for PanicStrategy { - type Err = String; - fn from_str(s: &str) -> Result<Self, Self::Err> { - Ok(match s { - "unwind" => PanicStrategy::Unwind, - "abort" => PanicStrategy::Abort, - _ => { - return Err(format!( - "'{}' is not a valid value for \ - panic-strategy. Use 'unwind' or 'abort'.", - s - )); - } - }) +crate::target_spec_enum! { + pub enum RelroLevel { + Full = "full", + Partial = "partial", + Off = "off", + None = "none", } -} -crate::json::serde_deserialize_from_str!(PanicStrategy); + parse_error_type = "relro level"; +} impl IntoDiagArg for PanicStrategy { fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { @@ -882,109 +877,14 @@ impl IntoDiagArg for PanicStrategy { } } -impl ToJson for PanicStrategy { - fn to_json(&self) -> Json { - match *self { - PanicStrategy::Abort => "abort".to_json(), - PanicStrategy::Unwind => "unwind".to_json(), - } - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Hash)] -pub enum RelroLevel { - Full, - Partial, - Off, - None, -} - -impl RelroLevel { - pub fn desc(&self) -> &str { - match *self { - RelroLevel::Full => "full", - RelroLevel::Partial => "partial", - RelroLevel::Off => "off", - RelroLevel::None => "none", - } - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Hash)] -pub enum SymbolVisibility { - Hidden, - Protected, - Interposable, -} - -impl SymbolVisibility { - pub fn desc(&self) -> &str { - match *self { - SymbolVisibility::Hidden => "hidden", - SymbolVisibility::Protected => "protected", - SymbolVisibility::Interposable => "interposable", - } - } -} - -impl FromStr for SymbolVisibility { - type Err = String; - - fn from_str(s: &str) -> Result<SymbolVisibility, Self::Err> { - match s { - "hidden" => Ok(SymbolVisibility::Hidden), - "protected" => Ok(SymbolVisibility::Protected), - "interposable" => Ok(SymbolVisibility::Interposable), - _ => Err(format!( - "'{}' is not a valid value for \ - symbol-visibility. Use 'hidden', 'protected, or 'interposable'.", - s - )), - } - } -} - -crate::json::serde_deserialize_from_str!(SymbolVisibility); - -impl ToJson for SymbolVisibility { - fn to_json(&self) -> Json { - match *self { - SymbolVisibility::Hidden => "hidden".to_json(), - SymbolVisibility::Protected => "protected".to_json(), - SymbolVisibility::Interposable => "interposable".to_json(), - } - } -} - -impl FromStr for RelroLevel { - type Err = String; - - fn from_str(s: &str) -> Result<RelroLevel, Self::Err> { - match s { - "full" => Ok(RelroLevel::Full), - "partial" => Ok(RelroLevel::Partial), - "off" => Ok(RelroLevel::Off), - "none" => Ok(RelroLevel::None), - _ => Err(format!( - "'{}' is not a valid value for \ - relro-level. Use 'full', 'partial, 'off', or 'none'.", - s - )), - } +crate::target_spec_enum! { + pub enum SymbolVisibility { + Hidden = "hidden", + Protected = "protected", + Interposable = "interposable", } -} - -crate::json::serde_deserialize_from_str!(RelroLevel); -impl ToJson for RelroLevel { - fn to_json(&self) -> Json { - match *self { - RelroLevel::Full => "full".to_json(), - RelroLevel::Partial => "partial".to_json(), - RelroLevel::Off => "off".to_json(), - RelroLevel::None => "None".to_json(), - } - } + parse_error_type = "symbol visibility"; } #[derive(Clone, Debug, PartialEq, Hash)] @@ -1014,6 +914,18 @@ impl FromStr for SmallDataThresholdSupport { } crate::json::serde_deserialize_from_str!(SmallDataThresholdSupport); +impl schemars::JsonSchema for SmallDataThresholdSupport { + fn schema_name() -> std::borrow::Cow<'static, str> { + "SmallDataThresholdSupport".into() + } + fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema { + schemars::json_schema! ({ + "type": "string", + "pattern": r#"^none|default-for-arch|llvm-module-flag=.+|llvm-arg=.+$"#, + }) + .into() + } +} impl ToJson for SmallDataThresholdSupport { fn to_json(&self) -> Value { @@ -1026,76 +938,31 @@ impl ToJson for SmallDataThresholdSupport { } } -#[derive(Clone, Copy, Debug, PartialEq, Hash)] -pub enum MergeFunctions { - Disabled, - Trampolines, - Aliases, -} - -impl MergeFunctions { - pub fn desc(&self) -> &str { - match *self { - MergeFunctions::Disabled => "disabled", - MergeFunctions::Trampolines => "trampolines", - MergeFunctions::Aliases => "aliases", - } +crate::target_spec_enum! { + pub enum MergeFunctions { + Disabled = "disabled", + Trampolines = "trampolines", + Aliases = "aliases", } -} - -impl FromStr for MergeFunctions { - type Err = String; - fn from_str(s: &str) -> Result<MergeFunctions, Self::Err> { - match s { - "disabled" => Ok(MergeFunctions::Disabled), - "trampolines" => Ok(MergeFunctions::Trampolines), - "aliases" => Ok(MergeFunctions::Aliases), - _ => Err(format!( - "'{}' is not a valid value for \ - merge-functions. Use 'disabled', \ - 'trampolines', or 'aliases'.", - s - )), - } - } + parse_error_type = "value for merge-functions"; } -crate::json::serde_deserialize_from_str!(MergeFunctions); - -impl ToJson for MergeFunctions { - fn to_json(&self) -> Json { - match *self { - MergeFunctions::Disabled => "disabled".to_json(), - MergeFunctions::Trampolines => "trampolines".to_json(), - MergeFunctions::Aliases => "aliases".to_json(), - } +crate::target_spec_enum! { + pub enum RelocModel { + Static = "static", + Pic = "pic", + Pie = "pie", + DynamicNoPic = "dynamic-no-pic", + Ropi = "ropi", + Rwpi = "rwpi", + RopiRwpi = "ropi-rwpi", } -} -#[derive(Clone, Copy, PartialEq, Hash, Debug)] -pub enum RelocModel { - Static, - Pic, - Pie, - DynamicNoPic, - Ropi, - Rwpi, - RopiRwpi, + parse_error_type = "relocation model"; } impl RelocModel { - pub fn desc(&self) -> &str { - match *self { - RelocModel::Static => "static", - RelocModel::Pic => "pic", - RelocModel::Pie => "pie", - RelocModel::DynamicNoPic => "dynamic-no-pic", - RelocModel::Ropi => "ropi", - RelocModel::Rwpi => "rwpi", - RelocModel::RopiRwpi => "ropi-rwpi", - } - } pub const fn desc_symbol(&self) -> Symbol { match *self { RelocModel::Static => kw::Static, @@ -1121,236 +988,75 @@ impl RelocModel { } } -impl FromStr for RelocModel { - type Err = String; - - fn from_str(s: &str) -> Result<RelocModel, Self::Err> { - Ok(match s { - "static" => RelocModel::Static, - "pic" => RelocModel::Pic, - "pie" => RelocModel::Pie, - "dynamic-no-pic" => RelocModel::DynamicNoPic, - "ropi" => RelocModel::Ropi, - "rwpi" => RelocModel::Rwpi, - "ropi-rwpi" => RelocModel::RopiRwpi, - _ => { - return Err(format!( - "invalid relocation model '{s}'. - Run `rustc --print relocation-models` to \ - see the list of supported values.'" - )); - } - }) +crate::target_spec_enum! { + pub enum CodeModel { + Tiny = "tiny", + Small = "small", + Kernel = "kernel", + Medium = "medium", + Large = "large", } -} -crate::json::serde_deserialize_from_str!(RelocModel); - -impl ToJson for RelocModel { - fn to_json(&self) -> Json { - self.desc().to_json() - } -} - -#[derive(Clone, Copy, PartialEq, Hash, Debug)] -pub enum CodeModel { - Tiny, - Small, - Kernel, - Medium, - Large, + parse_error_type = "code model"; } -impl FromStr for CodeModel { - type Err = String; - - fn from_str(s: &str) -> Result<CodeModel, Self::Err> { - Ok(match s { - "tiny" => CodeModel::Tiny, - "small" => CodeModel::Small, - "kernel" => CodeModel::Kernel, - "medium" => CodeModel::Medium, - "large" => CodeModel::Large, - _ => { - return Err(format!( - "'{s}' is not a valid code model. \ - Run `rustc --print code-models` to \ - see the list of supported values." - )); - } - }) +crate::target_spec_enum! { + /// The float ABI setting to be configured in the LLVM target machine. + pub enum FloatAbi { + Soft = "soft", + Hard = "hard", } -} -crate::json::serde_deserialize_from_str!(CodeModel); - -impl ToJson for CodeModel { - fn to_json(&self) -> Json { - match *self { - CodeModel::Tiny => "tiny", - CodeModel::Small => "small", - CodeModel::Kernel => "kernel", - CodeModel::Medium => "medium", - CodeModel::Large => "large", - } - .to_json() - } + parse_error_type = "float abi"; } -/// The float ABI setting to be configured in the LLVM target machine. -#[derive(Clone, Copy, PartialEq, Hash, Debug)] -pub enum FloatAbi { - Soft, - Hard, -} - -impl FromStr for FloatAbi { - type Err = String; - - fn from_str(s: &str) -> Result<FloatAbi, Self::Err> { - Ok(match s { - "soft" => FloatAbi::Soft, - "hard" => FloatAbi::Hard, - _ => { - return Err(format!( - "'{}' is not a valid value for \ - llvm-floatabi. Use 'soft' or 'hard'.", - s - )); - } - }) +crate::target_spec_enum! { + /// The Rustc-specific variant of the ABI used for this target. + pub enum RustcAbi { + /// On x86-32 only: make use of SSE and SSE2 for ABI purposes. + X86Sse2 = "x86-sse2", + /// On x86-32/64 only: do not use any FPU or SIMD registers for the ABI. + X86Softfloat = "x86-softfloat", } -} - -crate::json::serde_deserialize_from_str!(FloatAbi); -impl ToJson for FloatAbi { - fn to_json(&self) -> Json { - match *self { - FloatAbi::Soft => "soft", - FloatAbi::Hard => "hard", - } - .to_json() - } -} - -/// The Rustc-specific variant of the ABI used for this target. -#[derive(Clone, Copy, PartialEq, Hash, Debug)] -pub enum RustcAbi { - /// On x86-32 only: make use of SSE and SSE2 for ABI purposes. - X86Sse2, - /// On x86-32/64 only: do not use any FPU or SIMD registers for the ABI. - X86Softfloat, + parse_error_type = "rustc abi"; } -impl FromStr for RustcAbi { - type Err = String; - - fn from_str(s: &str) -> Result<RustcAbi, Self::Err> { - Ok(match s { - "x86-sse2" => RustcAbi::X86Sse2, - "x86-softfloat" => RustcAbi::X86Softfloat, - _ => { - return Err(format!( - "'{s}' is not a valid value for rustc-abi. \ - Use 'x86-softfloat' or leave the field unset." - )); - } - }) - } -} - -crate::json::serde_deserialize_from_str!(RustcAbi); - -impl ToJson for RustcAbi { - fn to_json(&self) -> Json { - match *self { - RustcAbi::X86Sse2 => "x86-sse2", - RustcAbi::X86Softfloat => "x86-softfloat", - } - .to_json() +crate::target_spec_enum! { + pub enum TlsModel { + GeneralDynamic = "global-dynamic", + LocalDynamic = "local-dynamic", + InitialExec = "initial-exec", + LocalExec = "local-exec", + Emulated = "emulated", } -} -#[derive(Clone, Copy, PartialEq, Hash, Debug)] -pub enum TlsModel { - GeneralDynamic, - LocalDynamic, - InitialExec, - LocalExec, - Emulated, -} - -impl FromStr for TlsModel { - type Err = String; - - fn from_str(s: &str) -> Result<TlsModel, Self::Err> { - Ok(match s { - // Note the difference "general" vs "global" difference. The model name is "general", - // but the user-facing option name is "global" for consistency with other compilers. - "global-dynamic" => TlsModel::GeneralDynamic, - "local-dynamic" => TlsModel::LocalDynamic, - "initial-exec" => TlsModel::InitialExec, - "local-exec" => TlsModel::LocalExec, - "emulated" => TlsModel::Emulated, - _ => { - return Err(format!( - "'{s}' is not a valid TLS model. \ - Run `rustc --print tls-models` to \ - see the list of supported values." - )); - } - }) - } + parse_error_type = "TLS model"; } -crate::json::serde_deserialize_from_str!(TlsModel); - -impl ToJson for TlsModel { - fn to_json(&self) -> Json { - match *self { - TlsModel::GeneralDynamic => "global-dynamic", - TlsModel::LocalDynamic => "local-dynamic", - TlsModel::InitialExec => "initial-exec", - TlsModel::LocalExec => "local-exec", - TlsModel::Emulated => "emulated", - } - .to_json() +crate::target_spec_enum! { + /// Everything is flattened to a single enum to make the json encoding/decoding less annoying. + pub enum LinkOutputKind { + /// Dynamically linked non position-independent executable. + DynamicNoPicExe = "dynamic-nopic-exe", + /// Dynamically linked position-independent executable. + DynamicPicExe = "dynamic-pic-exe", + /// Statically linked non position-independent executable. + StaticNoPicExe = "static-nopic-exe", + /// Statically linked position-independent executable. + StaticPicExe = "static-pic-exe", + /// Regular dynamic library ("dynamically linked"). + DynamicDylib = "dynamic-dylib", + /// Dynamic library with bundled libc ("statically linked"). + StaticDylib = "static-dylib", + /// WASI module with a lifetime past the _initialize entry point + WasiReactorExe = "wasi-reactor-exe", } -} -/// Everything is flattened to a single enum to make the json encoding/decoding less annoying. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] -pub enum LinkOutputKind { - /// Dynamically linked non position-independent executable. - DynamicNoPicExe, - /// Dynamically linked position-independent executable. - DynamicPicExe, - /// Statically linked non position-independent executable. - StaticNoPicExe, - /// Statically linked position-independent executable. - StaticPicExe, - /// Regular dynamic library ("dynamically linked"). - DynamicDylib, - /// Dynamic library with bundled libc ("statically linked"). - StaticDylib, - /// WASI module with a lifetime past the _initialize entry point - WasiReactorExe, + parse_error_type = "CRT object kind"; } impl LinkOutputKind { - fn as_str(&self) -> &'static str { - match self { - LinkOutputKind::DynamicNoPicExe => "dynamic-nopic-exe", - LinkOutputKind::DynamicPicExe => "dynamic-pic-exe", - LinkOutputKind::StaticNoPicExe => "static-nopic-exe", - LinkOutputKind::StaticPicExe => "static-pic-exe", - LinkOutputKind::DynamicDylib => "dynamic-dylib", - LinkOutputKind::StaticDylib => "static-dylib", - LinkOutputKind::WasiReactorExe => "wasi-reactor-exe", - } - } - pub fn can_link_dylib(self) -> bool { match self { LinkOutputKind::StaticNoPicExe | LinkOutputKind::StaticPicExe => false, @@ -1363,171 +1069,64 @@ impl LinkOutputKind { } } -impl FromStr for LinkOutputKind { - type Err = String; - - fn from_str(s: &str) -> Result<LinkOutputKind, Self::Err> { - Ok(match s { - "dynamic-nopic-exe" => LinkOutputKind::DynamicNoPicExe, - "dynamic-pic-exe" => LinkOutputKind::DynamicPicExe, - "static-nopic-exe" => LinkOutputKind::StaticNoPicExe, - "static-pic-exe" => LinkOutputKind::StaticPicExe, - "dynamic-dylib" => LinkOutputKind::DynamicDylib, - "static-dylib" => LinkOutputKind::StaticDylib, - "wasi-reactor-exe" => LinkOutputKind::WasiReactorExe, - _ => { - return Err(format!( - "invalid value for CRT object kind. \ - Use '(dynamic,static)-(nopic,pic)-exe' or \ - '(dynamic,static)-dylib' or 'wasi-reactor-exe'" - )); - } - }) - } -} - -crate::json::serde_deserialize_from_str!(LinkOutputKind); - -impl fmt::Display for LinkOutputKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.as_str()) - } -} - pub type LinkArgs = BTreeMap<LinkerFlavor, Vec<StaticCow<str>>>; pub type LinkArgsCli = BTreeMap<LinkerFlavorCli, Vec<StaticCow<str>>>; -/// Which kind of debuginfo does the target use? -/// -/// Useful in determining whether a target supports Split DWARF (a target with -/// `DebuginfoKind::Dwarf` and supporting `SplitDebuginfo::Unpacked` for example). -#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)] -pub enum DebuginfoKind { - /// DWARF debuginfo (such as that used on `x86_64_unknown_linux_gnu`). - #[default] - Dwarf, - /// DWARF debuginfo in dSYM files (such as on Apple platforms). - DwarfDsym, - /// Program database files (such as on Windows). - Pdb, -} - -impl DebuginfoKind { - fn as_str(&self) -> &'static str { - match self { - DebuginfoKind::Dwarf => "dwarf", - DebuginfoKind::DwarfDsym => "dwarf-dsym", - DebuginfoKind::Pdb => "pdb", - } - } -} - -impl FromStr for DebuginfoKind { - type Err = String; - - fn from_str(s: &str) -> Result<Self, Self::Err> { - Ok(match s { - "dwarf" => DebuginfoKind::Dwarf, - "dwarf-dsym" => DebuginfoKind::DwarfDsym, - "pdb" => DebuginfoKind::Pdb, - _ => { - return Err(format!( - "'{s}' is not a valid value for debuginfo-kind. Use 'dwarf', \ - 'dwarf-dsym' or 'pdb'." - )); - } - }) - } -} - -crate::json::serde_deserialize_from_str!(DebuginfoKind); - -impl ToJson for DebuginfoKind { - fn to_json(&self) -> Json { - self.as_str().to_json() - } -} - -impl fmt::Display for DebuginfoKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.as_str()) - } -} - -#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)] -pub enum SplitDebuginfo { - /// Split debug-information is disabled, meaning that on supported platforms - /// you can find all debug information in the executable itself. This is - /// only supported for ELF effectively. - /// - /// * Windows - not supported - /// * macOS - don't run `dsymutil` - /// * ELF - `.debug_*` sections - #[default] - Off, - - /// Split debug-information can be found in a "packed" location separate - /// from the final artifact. This is supported on all platforms. +crate::target_spec_enum! { + /// Which kind of debuginfo does the target use? /// - /// * Windows - `*.pdb` - /// * macOS - `*.dSYM` (run `dsymutil`) - /// * ELF - `*.dwp` (run `thorin`) - Packed, - - /// Split debug-information can be found in individual object files on the - /// filesystem. The main executable may point to the object files. - /// - /// * Windows - not supported - /// * macOS - supported, scattered object files - /// * ELF - supported, scattered `*.dwo` or `*.o` files (see `SplitDwarfKind`) - Unpacked, -} - -impl SplitDebuginfo { - fn as_str(&self) -> &'static str { - match self { - SplitDebuginfo::Off => "off", - SplitDebuginfo::Packed => "packed", - SplitDebuginfo::Unpacked => "unpacked", - } - } -} - -impl FromStr for SplitDebuginfo { - type Err = String; - - fn from_str(s: &str) -> Result<Self, Self::Err> { - Ok(match s { - "off" => SplitDebuginfo::Off, - "unpacked" => SplitDebuginfo::Unpacked, - "packed" => SplitDebuginfo::Packed, - _ => { - return Err(format!( - "'{s}' is not a valid value for \ - split-debuginfo. Use 'off', 'unpacked', or 'packed'.", - )); - } - }) - } -} - -crate::json::serde_deserialize_from_str!(SplitDebuginfo); - -impl ToJson for SplitDebuginfo { - fn to_json(&self) -> Json { - self.as_str().to_json() - } -} - -impl fmt::Display for SplitDebuginfo { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.as_str()) - } + /// Useful in determining whether a target supports Split DWARF (a target with + /// `DebuginfoKind::Dwarf` and supporting `SplitDebuginfo::Unpacked` for example). + #[derive(Default)] + pub enum DebuginfoKind { + /// DWARF debuginfo (such as that used on `x86_64_unknown_linux_gnu`). + #[default] + Dwarf = "dwarf", + /// DWARF debuginfo in dSYM files (such as on Apple platforms). + DwarfDsym = "dwarf-dsym", + /// Program database files (such as on Windows). + Pdb = "pdb", + } + + parse_error_type = "debuginfo kind"; +} + +crate::target_spec_enum! { + #[derive(Default)] + pub enum SplitDebuginfo { + /// Split debug-information is disabled, meaning that on supported platforms + /// you can find all debug information in the executable itself. This is + /// only supported for ELF effectively. + /// + /// * Windows - not supported + /// * macOS - don't run `dsymutil` + /// * ELF - `.debug_*` sections + #[default] + Off = "off", + + /// Split debug-information can be found in a "packed" location separate + /// from the final artifact. This is supported on all platforms. + /// + /// * Windows - `*.pdb` + /// * macOS - `*.dSYM` (run `dsymutil`) + /// * ELF - `*.dwp` (run `thorin`) + Packed = "packed", + + /// Split debug-information can be found in individual object files on the + /// filesystem. The main executable may point to the object files. + /// + /// * Windows - not supported + /// * macOS - supported, scattered object files + /// * ELF - supported, scattered `*.dwo` or `*.o` files (see `SplitDwarfKind`) + Unpacked = "unpacked", + } + + parse_error_type = "split debuginfo"; } into_diag_arg_using_display!(SplitDebuginfo); -#[derive(Clone, Debug, PartialEq, Eq, serde_derive::Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, serde_derive::Deserialize, schemars::JsonSchema)] #[serde(tag = "kind")] #[serde(rename_all = "kebab-case")] pub enum StackProbeType { @@ -1688,6 +1287,19 @@ impl FromStr for SanitizerSet { } crate::json::serde_deserialize_from_str!(SanitizerSet); +impl schemars::JsonSchema for SanitizerSet { + fn schema_name() -> std::borrow::Cow<'static, str> { + "SanitizerSet".into() + } + fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema { + let all = Self::all().iter().map(|sanitizer| sanitizer.as_str()).collect::<Vec<_>>(); + schemars::json_schema! ({ + "type": "string", + "enum": all, + }) + .into() + } +} impl ToJson for SanitizerSet { fn to_json(&self) -> Json { @@ -1699,17 +1311,20 @@ impl ToJson for SanitizerSet { } } -#[derive(Clone, Copy, PartialEq, Hash, Debug)] -pub enum FramePointer { - /// Forces the machine code generator to always preserve the frame pointers. - Always, - /// Forces the machine code generator to preserve the frame pointers except for the leaf - /// functions (i.e. those that don't call other functions). - NonLeaf, - /// Allows the machine code generator to omit the frame pointers. - /// - /// This option does not guarantee that the frame pointers will be omitted. - MayOmit, +crate::target_spec_enum! { + pub enum FramePointer { + /// Forces the machine code generator to always preserve the frame pointers. + Always = "always", + /// Forces the machine code generator to preserve the frame pointers except for the leaf + /// functions (i.e. those that don't call other functions). + NonLeaf = "non-leaf", + /// Allows the machine code generator to omit the frame pointers. + /// + /// This option does not guarantee that the frame pointers will be omitted. + MayOmit = "may-omit", + } + + parse_error_type = "frame pointer"; } impl FramePointer { @@ -1726,93 +1341,43 @@ impl FramePointer { } } -impl FromStr for FramePointer { - type Err = String; - fn from_str(s: &str) -> Result<Self, Self::Err> { - Ok(match s { - "always" => Self::Always, - "non-leaf" => Self::NonLeaf, - "may-omit" => Self::MayOmit, - _ => return Err(format!("'{s}' is not a valid value for frame-pointer")), - }) - } -} - -crate::json::serde_deserialize_from_str!(FramePointer); - -impl ToJson for FramePointer { - fn to_json(&self) -> Json { - match *self { - Self::Always => "always", - Self::NonLeaf => "non-leaf", - Self::MayOmit => "may-omit", - } - .to_json() - } -} - -/// Controls use of stack canaries. -#[derive(Clone, Copy, Debug, PartialEq, Hash, Eq)] -pub enum StackProtector { - /// Disable stack canary generation. - None, - - /// On LLVM, mark all generated LLVM functions with the `ssp` attribute (see - /// llvm/docs/LangRef.rst). This triggers stack canary generation in - /// functions which contain an array of a byte-sized type with more than - /// eight elements. - Basic, +crate::target_spec_enum! { + /// Controls use of stack canaries. + pub enum StackProtector { + /// Disable stack canary generation. + None = "none", - /// On LLVM, mark all generated LLVM functions with the `sspstrong` - /// attribute (see llvm/docs/LangRef.rst). This triggers stack canary - /// generation in functions which either contain an array, or which take - /// the address of a local variable. - Strong, + /// On LLVM, mark all generated LLVM functions with the `ssp` attribute (see + /// llvm/docs/LangRef.rst). This triggers stack canary generation in + /// functions which contain an array of a byte-sized type with more than + /// eight elements. + Basic = "basic", - /// Generate stack canaries in all functions. - All, -} + /// On LLVM, mark all generated LLVM functions with the `sspstrong` + /// attribute (see llvm/docs/LangRef.rst). This triggers stack canary + /// generation in functions which either contain an array, or which take + /// the address of a local variable. + Strong = "strong", -impl StackProtector { - fn as_str(&self) -> &'static str { - match self { - StackProtector::None => "none", - StackProtector::Basic => "basic", - StackProtector::Strong => "strong", - StackProtector::All => "all", - } + /// Generate stack canaries in all functions. + All = "all", } -} -impl FromStr for StackProtector { - type Err = (); - - fn from_str(s: &str) -> Result<StackProtector, ()> { - Ok(match s { - "none" => StackProtector::None, - "basic" => StackProtector::Basic, - "strong" => StackProtector::Strong, - "all" => StackProtector::All, - _ => return Err(()), - }) - } -} - -impl fmt::Display for StackProtector { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.as_str()) - } + parse_error_type = "stack protector"; } into_diag_arg_using_display!(StackProtector); -#[derive(PartialEq, Clone, Debug)] -pub enum BinaryFormat { - Coff, - Elf, - MachO, - Wasm, - Xcoff, +crate::target_spec_enum! { + pub enum BinaryFormat { + Coff = "coff", + Elf = "elf", + MachO = "mach-o", + Wasm = "wasm", + Xcoff = "xcoff", + } + + parse_error_type = "binary format"; } impl BinaryFormat { @@ -1828,38 +1393,6 @@ impl BinaryFormat { } } -impl FromStr for BinaryFormat { - type Err = String; - fn from_str(s: &str) -> Result<Self, Self::Err> { - match s { - "coff" => Ok(Self::Coff), - "elf" => Ok(Self::Elf), - "mach-o" => Ok(Self::MachO), - "wasm" => Ok(Self::Wasm), - "xcoff" => Ok(Self::Xcoff), - _ => Err(format!( - "'{s}' is not a valid value for binary_format. \ - Use 'coff', 'elf', 'mach-o', 'wasm' or 'xcoff' " - )), - } - } -} - -crate::json::serde_deserialize_from_str!(BinaryFormat); - -impl ToJson for BinaryFormat { - fn to_json(&self) -> Json { - match self { - Self::Coff => "coff", - Self::Elf => "elf", - Self::MachO => "mach-o", - Self::Wasm => "wasm", - Self::Xcoff => "xcoff", - } - .to_json() - } -} - impl ToJson for Align { fn to_json(&self) -> Json { self.bits().to_json() diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index e042ce84955..f997842a607 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -857,11 +857,11 @@ fn foo(&self) -> Self::T { String::new() } && self.infcx.can_eq(param_env, assoc_ty, found) { let msg = match assoc_item.container { - ty::AssocItemContainer::Trait => { + ty::AssocContainer::Trait => { "associated type defaults can't be assumed inside the \ trait defining them" } - ty::AssocItemContainer::Impl => { + ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => { "associated type is `default` and may be overridden" } }; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index 7369134420c..518d4fe17e8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -571,13 +571,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // but right now it's not really very smart when it comes to implicit `Sized` // predicates and bounds on the trait itself. - let Some(impl_def_id) = self.tcx.associated_item(impl_item_def_id).impl_container(self.tcx) - else { - return; - }; - let Some(trait_ref) = self.tcx.impl_trait_ref(impl_def_id) else { + let Some(impl_def_id) = self.tcx.trait_impl_of_assoc(impl_item_def_id.to_def_id()) else { return; }; + let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap(); let trait_args = trait_ref .instantiate_identity() // Replace the explicit self type with `Self` for better suggestion rendering diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs index 8a67e4ccd45..f54ebd76cab 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs @@ -5,7 +5,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::{LangItem, lang_items}; -use rustc_middle::ty::{AssocItemContainer, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv}; +use rustc_middle::ty::{AssocContainer, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv}; use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, sym}; use tracing::debug; @@ -76,8 +76,9 @@ pub fn call_kind<'tcx>( let parent = tcx.opt_associated_item(method_did).and_then(|assoc| { let container_id = assoc.container_id(tcx); match assoc.container { - AssocItemContainer::Impl => tcx.trait_id_of_impl(container_id), - AssocItemContainer::Trait => Some(container_id), + AssocContainer::InherentImpl => None, + AssocContainer::TraitImpl(_) => tcx.trait_id_of_impl(container_id), + AssocContainer::Trait => Some(container_id), } }); 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 cb84d583e6e..f2f840581cf 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -421,7 +421,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) | hir::Node::ImplItem(hir::ImplItem { generics, - trait_item_def_id: None, + impl_kind: hir::ImplItemImplKind::Inherent { .. }, kind: hir::ImplItemKind::Fn(..), .. }) if finder.can_suggest_bound(generics) => { diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs index 19eb85506b6..4d0465777dd 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs @@ -387,7 +387,7 @@ pub(crate) fn assoc_def( if let Some(assoc_item) = ancestors.leaf_def(tcx, assoc_def_id) { // Ensure that the impl is constrained, otherwise projection may give us // bad unconstrained infer vars. - if assoc_item.item.container == ty::AssocItemContainer::Impl + if let ty::AssocContainer::TraitImpl(_) = assoc_item.item.container && let Some(impl_def_id) = assoc_item.item.container_id(tcx).as_local() { tcx.ensure_ok().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?; diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index e9629e31482..84f52e7fc9d 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -2,7 +2,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::definitions::{DefPathData, DisambiguatorState}; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{self as hir, ItemKind}; +use rustc_hir::{self as hir, ImplItemImplKind, ItemKind}; use rustc_middle::query::Providers; use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt}; use rustc_middle::{bug, span_bug}; @@ -63,7 +63,7 @@ fn associated_items(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItems { fn impl_item_implementor_ids(tcx: TyCtxt<'_>, impl_id: DefId) -> DefIdMap<DefId> { tcx.associated_items(impl_id) .in_definition_order() - .filter_map(|item| item.trait_item_def_id.map(|trait_item| (trait_item, item.def_id))) + .filter_map(|item| item.trait_item_def_id().map(|trait_item| (trait_item, item.def_id))) .collect() } @@ -97,12 +97,7 @@ fn associated_item_from_trait_item( } }; - ty::AssocItem { - kind, - def_id: owner_id.to_def_id(), - trait_item_def_id: Some(owner_id.to_def_id()), - container: ty::AssocItemContainer::Trait, - } + ty::AssocItem { kind, def_id: owner_id.to_def_id(), container: ty::AssocContainer::Trait } } fn associated_item_from_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) -> ty::AssocItem { @@ -118,12 +113,13 @@ fn associated_item_from_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_> } }; - ty::AssocItem { - kind, - def_id: owner_id.to_def_id(), - trait_item_def_id: impl_item.trait_item_def_id, - container: ty::AssocItemContainer::Impl, - } + let container = match impl_item.impl_kind { + ImplItemImplKind::Inherent { .. } => ty::AssocContainer::InherentImpl, + ImplItemImplKind::Trait { trait_item_def_id, .. } => { + ty::AssocContainer::TraitImpl(trait_item_def_id) + } + }; + ty::AssocItem { kind, def_id: owner_id.to_def_id(), container } } struct RPITVisitor<'a, 'tcx> { tcx: TyCtxt<'tcx>, @@ -190,7 +186,10 @@ fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>( } let did = item.owner_id.def_id.to_def_id(); let item = tcx.hir_impl_item(*item); - let Some(trait_item_def_id) = item.trait_item_def_id else { + let ImplItemImplKind::Trait { + trait_item_def_id: Ok(trait_item_def_id), .. + } = item.impl_kind + else { return Some((did, vec![])); }; let iter = in_trait_def[&trait_item_def_id].iter().map(|&id| { @@ -256,8 +255,7 @@ fn associated_type_for_impl_trait_in_trait( }), }, def_id, - trait_item_def_id: None, - container: ty::AssocItemContainer::Trait, + container: ty::AssocContainer::Trait, }); // Copy visility of the containing function. @@ -322,8 +320,7 @@ fn associated_type_for_impl_trait_in_impl( }), }, def_id, - trait_item_def_id: Some(trait_assoc_def_id), - container: ty::AssocItemContainer::Impl, + container: ty::AssocContainer::TraitImpl(Ok(trait_assoc_def_id)), }); // Copy visility of the containing function. diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index cdfb93c4e7d..543f6a3ccf7 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -107,7 +107,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' // the assumed wf types of the trait's RPITIT GAT. ty::ImplTraitInTraitData::Impl { .. } => { let impl_def_id = tcx.local_parent(def_id); - let rpitit_def_id = tcx.associated_item(def_id).trait_item_def_id.unwrap(); + let rpitit_def_id = tcx.trait_item_of(def_id).unwrap(); let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto( tcx, impl_def_id.to_def_id(), diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 4a7263d0ccd..eb3236d3006 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -245,7 +245,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> { for &assoc in self.tcx.associated_items(parent).in_definition_order() { trace!(?assoc); - if assoc.trait_item_def_id != Some(alias_ty.def_id) { + if assoc.expect_trait_impl() != Ok(alias_ty.def_id) { continue; } diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index b22c326b9f2..a5987757dc3 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -88,7 +88,10 @@ fn defaultness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Defaultness { }), .. }) - | hir::Node::ImplItem(hir::ImplItem { defaultness, .. }) + | hir::Node::ImplItem(hir::ImplItem { + impl_kind: hir::ImplItemImplKind::Trait { defaultness, .. }, + .. + }) | hir::Node::TraitItem(hir::TraitItem { defaultness, .. }) => *defaultness, node => { bug!("`defaultness` called on {:?}", node); @@ -165,7 +168,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { if tcx.def_kind(def_id) == DefKind::AssocFn && let assoc_item = tcx.associated_item(def_id) - && assoc_item.container == ty::AssocItemContainer::Trait + && assoc_item.container == ty::AssocContainer::Trait && assoc_item.defaultness(tcx).has_value() { let sig = tcx.fn_sig(def_id).instantiate_identity(); diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 8b6d86a2888..98f11e2ea57 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -1433,7 +1433,6 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> { /// # Examples /// /// ``` - /// #![feature(btree_extract_if)] /// use std::collections::BTreeMap; /// /// // Splitting a map into even and odd keys, reusing the original map: @@ -1450,7 +1449,7 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> { /// assert_eq!(low.keys().copied().collect::<Vec<_>>(), [0, 1, 2, 3]); /// assert_eq!(high.keys().copied().collect::<Vec<_>>(), [4, 5, 6, 7]); /// ``` - #[unstable(feature = "btree_extract_if", issue = "70530")] + #[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")] pub fn extract_if<F, R>(&mut self, range: R, pred: F) -> ExtractIf<'_, K, V, R, F, A> where K: Ord, @@ -1937,7 +1936,7 @@ impl<K, V> Default for Values<'_, K, V> { } /// An iterator produced by calling `extract_if` on BTreeMap. -#[unstable(feature = "btree_extract_if", issue = "70530")] +#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")] #[must_use = "iterators are lazy and do nothing unless consumed"] pub struct ExtractIf< 'a, @@ -1970,7 +1969,7 @@ pub(super) struct ExtractIfInner<'a, K, V, R> { range: R, } -#[unstable(feature = "btree_extract_if", issue = "70530")] +#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")] impl<K, V, R, F, A> fmt::Debug for ExtractIf<'_, K, V, R, F, A> where K: fmt::Debug, @@ -1982,7 +1981,7 @@ where } } -#[unstable(feature = "btree_extract_if", issue = "70530")] +#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")] impl<K, V, R, F, A: Allocator + Clone> Iterator for ExtractIf<'_, K, V, R, F, A> where K: PartialOrd, @@ -2056,7 +2055,7 @@ impl<'a, K, V, R> ExtractIfInner<'a, K, V, R> { } } -#[unstable(feature = "btree_extract_if", issue = "70530")] +#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")] impl<K, V, R, F> FusedIterator for ExtractIf<'_, K, V, R, F> where K: PartialOrd, diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index d50ce02bda7..e6b0a1f6323 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1202,7 +1202,6 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> { /// # Examples /// /// ``` - /// #![feature(btree_extract_if)] /// use std::collections::BTreeSet; /// /// // Splitting a set into even and odd values, reusing the original set: @@ -1219,7 +1218,7 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> { /// assert_eq!(low.into_iter().collect::<Vec<_>>(), [0, 1, 2, 3]); /// assert_eq!(high.into_iter().collect::<Vec<_>>(), [4, 5, 6, 7]); /// ``` - #[unstable(feature = "btree_extract_if", issue = "70530")] + #[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")] pub fn extract_if<F, R>(&mut self, range: R, pred: F) -> ExtractIf<'_, T, R, F, A> where T: Ord, @@ -1554,7 +1553,7 @@ impl<'a, T, A: Allocator + Clone> IntoIterator for &'a BTreeSet<T, A> { } /// An iterator produced by calling `extract_if` on BTreeSet. -#[unstable(feature = "btree_extract_if", issue = "70530")] +#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")] #[must_use = "iterators are lazy and do nothing unless consumed"] pub struct ExtractIf< 'a, @@ -1569,7 +1568,7 @@ pub struct ExtractIf< alloc: A, } -#[unstable(feature = "btree_extract_if", issue = "70530")] +#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")] impl<T, R, F, A> fmt::Debug for ExtractIf<'_, T, R, F, A> where T: fmt::Debug, @@ -1582,7 +1581,7 @@ where } } -#[unstable(feature = "btree_extract_if", issue = "70530")] +#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")] impl<T, R, F, A: Allocator + Clone> Iterator for ExtractIf<'_, T, R, F, A> where T: PartialOrd, @@ -1602,7 +1601,7 @@ where } } -#[unstable(feature = "btree_extract_if", issue = "70530")] +#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")] impl<T, R, F, A: Allocator + Clone> FusedIterator for ExtractIf<'_, T, R, F, A> where T: PartialOrd, diff --git a/library/alloctests/benches/lib.rs b/library/alloctests/benches/lib.rs index 2633154318c..721d685527f 100644 --- a/library/alloctests/benches/lib.rs +++ b/library/alloctests/benches/lib.rs @@ -1,6 +1,5 @@ // Disabling in Miri as these would take too long. #![cfg(not(miri))] -#![feature(btree_extract_if)] #![feature(iter_next_chunk)] #![feature(repr_simd)] #![feature(slice_partition_dedup)] diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index bf446ae1ba4..8c3ce156f3c 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -2,7 +2,6 @@ #![feature(alloc_layout_extra)] #![feature(iter_array_chunks)] #![feature(assert_matches)] -#![feature(btree_extract_if)] #![feature(wtf8_internals)] #![feature(char_max_len)] #![feature(cow_is_borrowed)] diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index 1c55824ab90..7ff4af8ede8 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -1257,6 +1257,108 @@ mod ref_keyword {} /// [`async`]: ../std/keyword.async.html mod return_keyword {} +#[doc(keyword = "become")] +// +/// Perform a tail-call of a function. +/// +/// <div class="warning"> +/// +/// `feature(explicit_tail_calls)` is currently incomplete and may not work properly. +/// </div> +/// +/// When tail calling a function, instead of its stack frame being added to the +/// stack, the stack frame of the caller is directly replaced with the callee's. +/// This means that as long as a loop in a call graph only uses tail calls, the +/// stack growth will be bounded. +/// +/// This is useful for writing functional-style code (since it prevents recursion +/// from exhausting resources) or for code optimization (since a tail call +/// *might* be cheaper than a normal call, tail calls can be used in a similar +/// manner to computed goto). +/// +/// Example of using `become` to implement functional-style `fold`: +/// ``` +/// #![feature(explicit_tail_calls)] +/// #![expect(incomplete_features)] +/// +/// fn fold<T: Copy, S>(slice: &[T], init: S, f: impl Fn(S, T) -> S) -> S { +/// match slice { +/// // without `become`, on big inputs this could easily overflow the +/// // stack. using a tail call guarantees that the stack will not grow unboundedly +/// [first, rest @ ..] => become fold(rest, f(init, *first), f), +/// [] => init, +/// } +/// } +/// ``` +/// +/// Compilers can already perform "tail call optimization" -- they can replace normal +/// calls with tail calls, although there are no guarantees that this will be done. +/// However, to perform TCO, the call needs to be the last thing that happens +/// in the functions and be returned from it. This requirement is often broken +/// by drop code for locals, which is run after computing the return expression: +/// +/// ``` +/// fn example() { +/// let string = "meow".to_owned(); +/// println!("{string}"); +/// return help(); // this is *not* the last thing that happens in `example`... +/// } +/// +/// // ... because it is desugared to this: +/// fn example_desugared() { +/// let string = "meow".to_owned(); +/// println!("{string}"); +/// let tmp = help(); +/// drop(string); +/// return tmp; +/// } +/// +/// fn help() {} +/// ``` +/// +/// For this reason, `become` also changes the drop order, such that locals are +/// dropped *before* evaluating the call. +/// +/// In order to guarantee that the compiler can perform a tail call, `become` +/// currently has these requirements: +/// 1. callee and caller must have the same ABI, arguments, and return type +/// 2. callee and caller must not have varargs +/// 3. caller must not be marked with `#[track_caller]` +/// - callee is allowed to be marked with `#[track_caller]` as otherwise +/// adding `#[track_caller]` would be a breaking change. if callee is +/// marked with `#[track_caller]` a tail call is not guaranteed. +/// 4. callee and caller cannot be a closure +/// (unless it's coerced to a function pointer) +/// +/// It is possible to tail-call a function pointer: +/// ``` +/// #![feature(explicit_tail_calls)] +/// #![expect(incomplete_features)] +/// +/// #[derive(Copy, Clone)] +/// enum Inst { Inc, Dec } +/// +/// fn dispatch(stream: &[Inst], state: u32) -> u32 { +/// const TABLE: &[fn(&[Inst], u32) -> u32] = &[increment, decrement]; +/// match stream { +/// [inst, rest @ ..] => become TABLE[*inst as usize](rest, state), +/// [] => state, +/// } +/// } +/// +/// fn increment(stream: &[Inst], state: u32) -> u32 { +/// become dispatch(stream, state + 1) +/// } +/// +/// fn decrement(stream: &[Inst], state: u32) -> u32 { +/// become dispatch(stream, state - 1) +/// } +/// +/// let program = &[Inst::Inc, Inst::Inc, Inst::Dec, Inst::Inc]; +/// assert_eq!(dispatch(program, 0), 2); +/// ``` +mod become_keyword {} + #[doc(keyword = "self")] // /// The receiver of a method, or the current module. diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 5725816c600..33e3bf0c085 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -284,7 +284,6 @@ #![feature(core_float_math)] #![feature(decl_macro)] #![feature(deprecated_suggestion)] -#![feature(derive_const)] #![feature(doc_cfg)] #![feature(doc_cfg_hide)] #![feature(doc_masked)] @@ -332,11 +331,7 @@ #![feature(cfg_select)] #![feature(char_internals)] #![feature(clone_to_uninit)] -#![feature(const_cmp)] #![feature(const_convert)] -#![feature(const_ops)] -#![feature(const_option_ops)] -#![feature(const_try)] #![feature(core_intrinsics)] #![feature(core_io_borrowed_buf)] #![feature(drop_guard)] diff --git a/library/std/src/sys/pal/hermit/time.rs b/library/std/src/sys/pal/hermit/time.rs index 89a427ab88b..f76a5f96c87 100644 --- a/library/std/src/sys/pal/hermit/time.rs +++ b/library/std/src/sys/pal/hermit/time.rs @@ -25,15 +25,8 @@ impl Timespec { Timespec { t: timespec { tv_sec, tv_nsec } } } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - const fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> { - // FIXME: const PartialOrd - let mut cmp = self.t.tv_sec - other.t.tv_sec; - if cmp == 0 { - cmp = self.t.tv_nsec as i64 - other.t.tv_nsec as i64; - } - - if cmp >= 0 { + fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> { + if self >= other { Ok(if self.t.tv_nsec >= other.t.tv_nsec { Duration::new( (self.t.tv_sec - other.t.tv_sec) as u64, @@ -53,22 +46,20 @@ impl Timespec { } } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - const fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> { + fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> { let mut secs = self.t.tv_sec.checked_add_unsigned(other.as_secs())?; // Nano calculations can't overflow because nanos are <1B which fit // in a u32. - let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32; - if nsec >= NSEC_PER_SEC as u32 { - nsec -= NSEC_PER_SEC as u32; + let mut nsec = other.subsec_nanos() + u32::try_from(self.t.tv_nsec).unwrap(); + if nsec >= NSEC_PER_SEC.try_into().unwrap() { + nsec -= u32::try_from(NSEC_PER_SEC).unwrap(); secs = secs.checked_add(1)?; } Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } }) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - const fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> { + fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> { let mut secs = self.t.tv_sec.checked_sub_unsigned(other.as_secs())?; // Similar to above, nanos can't overflow. @@ -222,18 +213,15 @@ impl SystemTime { SystemTime(time) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { + pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { self.0.sub_timespec(&other.0) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { Some(SystemTime(self.0.checked_add_duration(other)?)) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { Some(SystemTime(self.0.checked_sub_duration(other)?)) } } diff --git a/library/std/src/sys/pal/sgx/time.rs b/library/std/src/sys/pal/sgx/time.rs index 603dae952ab..db4cf2804bf 100644 --- a/library/std/src/sys/pal/sgx/time.rs +++ b/library/std/src/sys/pal/sgx/time.rs @@ -32,22 +32,15 @@ impl SystemTime { SystemTime(usercalls::insecure_time()) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { - // FIXME: ok_or_else with const closures - match self.0.checked_sub(other.0) { - Some(duration) => Ok(duration), - None => Err(other.0 - self.0), - } + pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { + self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { Some(SystemTime(self.0.checked_add(*other)?)) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { Some(SystemTime(self.0.checked_sub(*other)?)) } } diff --git a/library/std/src/sys/pal/solid/time.rs b/library/std/src/sys/pal/solid/time.rs index e35e60df1a0..c39d715c6a6 100644 --- a/library/std/src/sys/pal/solid/time.rs +++ b/library/std/src/sys/pal/solid/time.rs @@ -39,8 +39,7 @@ impl SystemTime { Self(t) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { + pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { if self.0 >= other.0 { Ok(Duration::from_secs((self.0 as u64).wrapping_sub(other.0 as u64))) } else { @@ -48,13 +47,11 @@ impl SystemTime { } } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { Some(SystemTime(self.0.checked_add_unsigned(other.as_secs())?)) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { Some(SystemTime(self.0.checked_sub_unsigned(other.as_secs())?)) } } diff --git a/library/std/src/sys/pal/uefi/time.rs b/library/std/src/sys/pal/uefi/time.rs index 36ce3f7ef96..c6636626fd5 100644 --- a/library/std/src/sys/pal/uefi/time.rs +++ b/library/std/src/sys/pal/uefi/time.rs @@ -80,32 +80,19 @@ impl SystemTime { .unwrap_or_else(|| panic!("time not implemented on this platform")) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { - // FIXME: ok_or_else with const closures - match self.0.checked_sub(other.0) { - Some(duration) => Ok(duration), - None => Err(other.0 - self.0), - } + pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { + self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { - let temp = self.0.checked_add(*other)?; + pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { + let temp = Self(self.0.checked_add(*other)?); // Check if can be represented in UEFI - // FIXME: const PartialOrd - let mut cmp = temp.as_secs() - MAX_UEFI_TIME.0.as_secs(); - if cmp == 0 { - cmp = temp.subsec_nanos() as u64 - MAX_UEFI_TIME.0.subsec_nanos() as u64; - } - - if cmp <= 0 { Some(SystemTime(temp)) } else { None } + if temp <= MAX_UEFI_TIME { Some(temp) } else { None } } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { - Some(SystemTime(self.0.checked_sub(*other)?)) + pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { + self.0.checked_sub(*other).map(Self) } } diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index 328fe0bc960..bd7f74fea6a 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -38,18 +38,15 @@ impl SystemTime { SystemTime { t: Timespec::now(libc::CLOCK_REALTIME) } } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { + pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { self.t.sub_timespec(&other.t) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { Some(SystemTime { t: self.t.checked_add_duration(other)? }) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { Some(SystemTime { t: self.t.checked_sub_duration(other)? }) } } @@ -136,15 +133,8 @@ impl Timespec { Timespec::new(t.tv_sec as i64, t.tv_nsec as i64).unwrap() } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> { - // FIXME: const PartialOrd - let mut cmp = self.tv_sec - other.tv_sec; - if cmp == 0 { - cmp = self.tv_nsec.as_inner() as i64 - other.tv_nsec.as_inner() as i64; - } - - if cmp >= 0 { + pub fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> { + if self >= other { // NOTE(eddyb) two aspects of this `if`-`else` are required for LLVM // to optimize it into a branchless form (see also #75545): // @@ -179,8 +169,7 @@ impl Timespec { } } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> { + pub fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> { let mut secs = self.tv_sec.checked_add_unsigned(other.as_secs())?; // Nano calculations can't overflow because nanos are <1B which fit @@ -190,11 +179,10 @@ impl Timespec { nsec -= NSEC_PER_SEC as u32; secs = secs.checked_add(1)?; } - Some(unsafe { Timespec::new_unchecked(secs, nsec as i64) }) + Some(unsafe { Timespec::new_unchecked(secs, nsec.into()) }) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> { + pub fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> { let mut secs = self.tv_sec.checked_sub_unsigned(other.as_secs())?; // Similar to above, nanos can't overflow. @@ -203,7 +191,7 @@ impl Timespec { nsec += NSEC_PER_SEC as i32; secs = secs.checked_sub(1)?; } - Some(unsafe { Timespec::new_unchecked(secs, nsec as i64) }) + Some(unsafe { Timespec::new_unchecked(secs, nsec.into()) }) } #[allow(dead_code)] diff --git a/library/std/src/sys/pal/unsupported/time.rs b/library/std/src/sys/pal/unsupported/time.rs index 0c387917044..6d67b538a96 100644 --- a/library/std/src/sys/pal/unsupported/time.rs +++ b/library/std/src/sys/pal/unsupported/time.rs @@ -31,22 +31,15 @@ impl SystemTime { panic!("time not implemented on this platform") } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { - // FIXME: ok_or_else with const closures - match self.0.checked_sub(other.0) { - Some(duration) => Ok(duration), - None => Err(other.0 - self.0), - } + pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { + self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { Some(SystemTime(self.0.checked_add(*other)?)) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { Some(SystemTime(self.0.checked_sub(*other)?)) } } diff --git a/library/std/src/sys/pal/wasip1/time.rs b/library/std/src/sys/pal/wasip1/time.rs index 892661b312b..0d8d0b59ac1 100644 --- a/library/std/src/sys/pal/wasip1/time.rs +++ b/library/std/src/sys/pal/wasip1/time.rs @@ -43,34 +43,23 @@ impl SystemTime { SystemTime(current_time(wasi::CLOCKID_REALTIME)) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime { + pub fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime { SystemTime(Duration::from_nanos(ts)) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> { - // FIXME: const TryInto - let ns = self.0.as_nanos(); - if ns <= u64::MAX as u128 { Some(ns as u64) } else { None } + pub fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> { + self.0.as_nanos().try_into().ok() } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { - // FIXME: ok_or_else with const closures - match self.0.checked_sub(other.0) { - Some(duration) => Ok(duration), - None => Err(other.0 - self.0), - } + pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { + self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { Some(SystemTime(self.0.checked_add(*other)?)) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { Some(SystemTime(self.0.checked_sub(*other)?)) } } diff --git a/library/std/src/sys/pal/wasip2/time.rs b/library/std/src/sys/pal/wasip2/time.rs index 980070e7b85..43489183994 100644 --- a/library/std/src/sys/pal/wasip2/time.rs +++ b/library/std/src/sys/pal/wasip2/time.rs @@ -36,34 +36,23 @@ impl SystemTime { SystemTime(Duration::new(now.seconds, now.nanoseconds)) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime { + pub fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime { SystemTime(Duration::from_nanos(ts)) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> { - // FIXME: const TryInto - let ns = self.0.as_nanos(); - if ns <= u64::MAX as u128 { Some(ns as u64) } else { None } + pub fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> { + self.0.as_nanos().try_into().ok() } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { - // FIXME: ok_or_else with const closures - match self.0.checked_sub(other.0) { - Some(duration) => Ok(duration), - None => Err(other.0 - self.0), - } + pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { + self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { Some(SystemTime(self.0.checked_add(*other)?)) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { Some(SystemTime(self.0.checked_sub(*other)?)) } } diff --git a/library/std/src/sys/pal/windows/time.rs b/library/std/src/sys/pal/windows/time.rs index f8f9a9fd818..0d31b80e56a 100644 --- a/library/std/src/sys/pal/windows/time.rs +++ b/library/std/src/sys/pal/windows/time.rs @@ -72,8 +72,7 @@ impl SystemTime { } } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - const fn from_intervals(intervals: i64) -> SystemTime { + fn from_intervals(intervals: i64) -> SystemTime { SystemTime { t: c::FILETIME { dwLowDateTime: intervals as u32, @@ -82,13 +81,11 @@ impl SystemTime { } } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - const fn intervals(&self) -> i64 { + fn intervals(&self) -> i64 { (self.t.dwLowDateTime as i64) | ((self.t.dwHighDateTime as i64) << 32) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { + pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { let me = self.intervals(); let other = other.intervals(); if me >= other { @@ -98,14 +95,12 @@ impl SystemTime { } } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { let intervals = self.intervals().checked_add(checked_dur2intervals(other)?)?; Some(SystemTime::from_intervals(intervals)) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { let intervals = self.intervals().checked_sub(checked_dur2intervals(other)?)?; Some(SystemTime::from_intervals(intervals)) } @@ -155,18 +150,15 @@ impl Hash for SystemTime { } } -#[rustc_const_unstable(feature = "const_system_time", issue = "144517")] -const fn checked_dur2intervals(dur: &Duration) -> Option<i64> { - // FIXME: const TryInto - let secs = dur - .as_secs() +fn checked_dur2intervals(dur: &Duration) -> Option<i64> { + dur.as_secs() .checked_mul(INTERVALS_PER_SEC)? - .checked_add(dur.subsec_nanos() as u64 / 100)?; - if secs <= i64::MAX as u64 { Some(secs.cast_signed()) } else { None } + .checked_add(dur.subsec_nanos() as u64 / 100)? + .try_into() + .ok() } -#[rustc_const_unstable(feature = "const_system_time", issue = "144517")] -const fn intervals2dur(intervals: u64) -> Duration { +fn intervals2dur(intervals: u64) -> Duration { Duration::new(intervals / INTERVALS_PER_SEC, ((intervals % INTERVALS_PER_SEC) * 100) as u32) } diff --git a/library/std/src/sys/pal/xous/time.rs b/library/std/src/sys/pal/xous/time.rs index d737416436e..ae8be81c0b7 100644 --- a/library/std/src/sys/pal/xous/time.rs +++ b/library/std/src/sys/pal/xous/time.rs @@ -43,22 +43,15 @@ impl SystemTime { SystemTime { 0: Duration::from_millis((upper as u64) << 32 | lower as u64) } } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { - // FIXME: ok_or_else with const closures - match self.0.checked_sub(other.0) { - Some(duration) => Ok(duration), - None => Err(other.0 - self.0), - } + pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { + self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { Some(SystemTime(self.0.checked_add(*other)?)) } - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { + pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { Some(SystemTime(self.0.checked_sub(*other)?)) } } diff --git a/library/std/src/time.rs b/library/std/src/time.rs index 84fbb4c2fe4..31187adb6fe 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -551,13 +551,8 @@ impl SystemTime { /// println!("{difference:?}"); /// ``` #[stable(feature = "time2", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn duration_since(&self, earlier: SystemTime) -> Result<Duration, SystemTimeError> { - // FIXME: map_err in const - match self.0.sub_time(&earlier.0) { - Ok(time) => Ok(time), - Err(err) => Err(SystemTimeError(err)), - } + pub fn duration_since(&self, earlier: SystemTime) -> Result<Duration, SystemTimeError> { + self.0.sub_time(&earlier.0).map_err(SystemTimeError) } /// Returns the difference from this system time to the @@ -594,8 +589,7 @@ impl SystemTime { /// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None` /// otherwise. #[stable(feature = "time_checked_add", since = "1.34.0")] - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_add(&self, duration: Duration) -> Option<SystemTime> { + pub fn checked_add(&self, duration: Duration) -> Option<SystemTime> { self.0.checked_add_duration(&duration).map(SystemTime) } @@ -603,15 +597,13 @@ impl SystemTime { /// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None` /// otherwise. #[stable(feature = "time_checked_add", since = "1.34.0")] - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn checked_sub(&self, duration: Duration) -> Option<SystemTime> { + pub fn checked_sub(&self, duration: Duration) -> Option<SystemTime> { self.0.checked_sub_duration(&duration).map(SystemTime) } } #[stable(feature = "time2", since = "1.8.0")] -#[rustc_const_unstable(feature = "const_ops", issue = "143802")] -impl const Add<Duration> for SystemTime { +impl Add<Duration> for SystemTime { type Output = SystemTime; /// # Panics @@ -624,16 +616,14 @@ impl const Add<Duration> for SystemTime { } #[stable(feature = "time_augmented_assignment", since = "1.9.0")] -#[rustc_const_unstable(feature = "const_ops", issue = "143802")] -impl const AddAssign<Duration> for SystemTime { +impl AddAssign<Duration> for SystemTime { fn add_assign(&mut self, other: Duration) { *self = *self + other; } } #[stable(feature = "time2", since = "1.8.0")] -#[rustc_const_unstable(feature = "const_ops", issue = "143802")] -impl const Sub<Duration> for SystemTime { +impl Sub<Duration> for SystemTime { type Output = SystemTime; fn sub(self, dur: Duration) -> SystemTime { @@ -642,8 +632,7 @@ impl const Sub<Duration> for SystemTime { } #[stable(feature = "time_augmented_assignment", since = "1.9.0")] -#[rustc_const_unstable(feature = "const_ops", issue = "143802")] -impl const SubAssign<Duration> for SystemTime { +impl SubAssign<Duration> for SystemTime { fn sub_assign(&mut self, other: Duration) { *self = *self - other; } @@ -710,8 +699,7 @@ impl SystemTimeError { /// ``` #[must_use] #[stable(feature = "time2", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_system_time", issue = "144517")] - pub const fn duration(&self) -> Duration { + pub fn duration(&self) -> Duration { self.0 } } diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index a5f0718bc01..99a1062109a 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -590,6 +590,8 @@ impl Step for Rustc { // Debugger scripts builder.ensure(DebuggerScripts { sysroot: image.to_owned(), target }); + generate_target_spec_json_schema(builder, image); + // HTML copyright files let file_list = builder.ensure(super::run::GenerateCopyright); for file in file_list { @@ -618,6 +620,28 @@ impl Step for Rustc { } } +fn generate_target_spec_json_schema(builder: &Builder<'_>, sysroot: &Path) { + // Since we run rustc in bootstrap, we need to ensure that we use the host compiler. + // We do this by using the stage 1 compiler, which is always compiled for the host, + // even in a cross build. + let stage1_host = builder.compiler(1, builder.host_target); + let mut rustc = command(builder.rustc(stage1_host)).fail_fast(); + rustc + .env("RUSTC_BOOTSTRAP", "1") + .args(["--print=target-spec-json-schema", "-Zunstable-options"]); + let schema = rustc.run_capture(builder).stdout(); + + let schema_dir = tmpdir(builder); + t!(fs::create_dir_all(&schema_dir)); + let schema_file = schema_dir.join("target-spec-json-schema.json"); + t!(std::fs::write(&schema_file, schema)); + + let dst = sysroot.join("etc"); + t!(fs::create_dir_all(&dst)); + + builder.install(&schema_file, &dst, FileType::Regular); +} + /// Copies debugger scripts for `target` into the given compiler `sysroot`. #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct DebuggerScripts { diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 4f839bdf7b8..723ba80eaf8 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2086,11 +2086,25 @@ HELP: You can add it into `bootstrap.toml` in `rust.codegen-backends = [{name:?} } // Get paths from cmd args - let paths = match &builder.config.cmd { + let mut paths = match &builder.config.cmd { Subcommand::Test { .. } => &builder.config.paths[..], _ => &[], }; + // in rustdoc-js mode, allow filters to be rs files or js files. + // use a late-initialized Vec to avoid cloning for other modes. + let mut paths_v; + if mode == "rustdoc-js" { + paths_v = paths.to_vec(); + for p in &mut paths_v { + if let Some(ext) = p.extension() + && ext == "js" + { + p.set_extension("rs"); + } + } + paths = &paths_v; + } // Get test-args by striping suite path let mut test_args: Vec<&str> = paths .iter() diff --git a/src/bootstrap/src/utils/proc_macro_deps.rs b/src/bootstrap/src/utils/proc_macro_deps.rs index 777c8601aa1..db2369097d6 100644 --- a/src/bootstrap/src/utils/proc_macro_deps.rs +++ b/src/bootstrap/src/utils/proc_macro_deps.rs @@ -43,6 +43,7 @@ pub static CRATES: &[&str] = &[ "rustc-hash", "self_cell", "serde", + "serde_derive_internals", "sha2", "smallvec", "stable_deref_trait", diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 8e378e53e51..e4bf33dd8a0 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -48,6 +48,7 @@ - [\*-apple-visionos](platform-support/apple-visionos.md) - [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md) - [aarch64-unknown-linux-musl](platform-support/aarch64-unknown-linux-musl.md) + - [aarch64-unknown-none*](platform-support/aarch64-unknown-none.md) - [aarch64_be-unknown-none-softfloat](platform-support/aarch64_be-unknown-none-softfloat.md) - [aarch64_be-unknown-linux-musl](platform-support/aarch64_be-unknown-linux-musl.md) - [amdgcn-amd-amdhsa](platform-support/amdgcn-amd-amdhsa.md) @@ -55,7 +56,9 @@ - [arm-none-eabi](platform-support/arm-none-eabi.md) - [armv4t-none-eabi](platform-support/armv4t-none-eabi.md) - [armv5te-none-eabi](platform-support/armv5te-none-eabi.md) - - [armv7r-none-eabi](platform-support/armv7r-none-eabi.md) + - [armv7a-none-eabi{,hf}](platform-support/armv7a-none-eabi.md) + - [armv7r-none-eabi{,hf}](platform-support/armv7r-none-eabi.md) + - [armebv7r-none-eabi{,hf}](platform-support/armebv7r-none-eabi.md) - [armv8r-none-eabihf](platform-support/armv8r-none-eabihf.md) - [thumbv6m-none-eabi](./platform-support/thumbv6m-none-eabi.md) - [thumbv7em-none-eabi\*](./platform-support/thumbv7em-none-eabi.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 9ad9cb5b526..e5e46f72637 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -149,22 +149,22 @@ target | std | notes [`aarch64-apple-ios-sim`](platform-support/apple-ios.md) | โ | Apple iOS Simulator on ARM64 [`aarch64-linux-android`](platform-support/android.md) | โ | ARM64 Android [`aarch64-unknown-fuchsia`](platform-support/fuchsia.md) | โ | ARM64 Fuchsia -`aarch64-unknown-none` | * | Bare ARM64, hardfloat -`aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat +[`aarch64-unknown-none`](platform-support/aarch64-unknown-none.md) | * | Bare ARM64, hardfloat +[`aarch64-unknown-none-softfloat`](platform-support/aarch64-unknown-none.md) | * | Bare ARM64, softfloat [`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | ARM64 UEFI [`arm-linux-androideabi`](platform-support/android.md) | โ | Armv6 Android `arm-unknown-linux-musleabi` | โ | Armv6 Linux with musl 1.2.3 `arm-unknown-linux-musleabihf` | โ | Armv6 Linux with musl 1.2.3, hardfloat [`arm64ec-pc-windows-msvc`](platform-support/arm64ec-pc-windows-msvc.md) | โ | Arm64EC Windows MSVC -[`armebv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian -[`armebv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian, hardfloat +[`armebv7r-none-eabi`](platform-support/armebv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian +[`armebv7r-none-eabihf`](platform-support/armebv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian, hardfloat [`armv5te-unknown-linux-gnueabi`](platform-support/armv5te-unknown-linux-gnueabi.md) | โ | Armv5TE Linux (kernel 4.4+, glibc 2.23) `armv5te-unknown-linux-musleabi` | โ | Armv5TE Linux with musl 1.2.3 [`armv7-linux-androideabi`](platform-support/android.md) | โ | Armv7-A Android `armv7-unknown-linux-gnueabi` | โ | Armv7-A Linux (kernel 4.15+, glibc 2.27) `armv7-unknown-linux-musleabi` | โ | Armv7-A Linux with musl 1.2.3 `armv7-unknown-linux-musleabihf` | โ | Armv7-A Linux with musl 1.2.3, hardfloat -[`armv7a-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare Armv7-A +[`armv7a-none-eabi`](platform-support/armv7a-none-eabi.md) | * | Bare Armv7-A [`armv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R [`armv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, hardfloat `i586-unknown-linux-gnu` | โ | 32-bit Linux (kernel 3.2+, glibc 2.17, original Pentium) [^x86_32-floats-x87] diff --git a/src/doc/rustc/src/platform-support/aarch64-unknown-none.md b/src/doc/rustc/src/platform-support/aarch64-unknown-none.md new file mode 100644 index 00000000000..7e18e8c157f --- /dev/null +++ b/src/doc/rustc/src/platform-support/aarch64-unknown-none.md @@ -0,0 +1,78 @@ +# `aarch64-unknown-none` and `aarch64-unknown-none-softfloat` + +* **Tier: 2** +* **Library Support:** core and alloc (bare-metal, `#![no_std]`) + +Bare-metal targets for CPUs in the Armv8-A architecture family, running in AArch64 mode. + +For the AArch32 mode carried over from Armv7-A, see +[`armv7a-none-eabi`](armv7a-none-eabi.md) instead. + +Processors in this family include the [Arm Cortex-A35, 53, 76, etc][aarch64-cpus]. + +[aarch64-cpus]: https://en.wikipedia.org/wiki/Comparison_of_ARM_processors#ARMv8-A + +## Target maintainers + +[Rust Embedded Devices Working Group Arm Team] + +[Rust Embedded Devices Working Group Arm Team]: https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team + +## Target CPU and Target Feature options + +All AArch64 processors include an FPU. The difference between the `-none` and +`-none-softfloat` targets is whether the FPU is used for passing function arguments. +You may prefer the `-softfloat` target when writing a kernel or interfacing with +pre-compiled binaries that use the soft-float ABI. + +When using the hardfloat targets, the minimum floating-point features assumed +are those of the `fp-armv8`, which excludes NEON SIMD support. If your +processor supports a different set of floating-point features than the default +expectations of `fp-armv8`, then these should also be enabled or disabled as +needed with `-C target-feature=(+/-)`. It is also possible to tell Rust (or +LLVM) that you have a specific model of Arm processor, using the +[`-Ctarget-cpu`][target-cpu] option. Doing so may change the default set of +target-features enabled. + +[target-cpu]: https://doc.rust-lang.org/rustc/codegen-options/index.html#target-cpu +[target-feature]: https://doc.rust-lang.org/rustc/codegen-options/index.html#target-feature + +## Requirements + +These targets are cross-compiled and use static linking. + +By default, the `lld` linker included with Rust will be used; however, you may +want to use the GNU linker instead. This can be obtained for Windows/Mac/Linux +from the [Arm Developer Website][arm-gnu-toolchain], or possibly from your OS's +package manager. To use it, add the following to your `.cargo/config.toml`: + +```toml +[target.aarch64-unknown-none] +linker = "aarch64-none-elf-ld" +``` + +The GNU linker can also be used by specifying `aarch64-none-elf-gcc` as the +linker. This is needed when using GCC's link time optimization. + +These targets don't provide a linker script, so you'll need to bring your own +according to the specific device you are using. Pass +`-Clink-arg=-Tyour_script.ld` as a rustc argument to make the linker use +`your_script.ld` during linking. + +[arm-gnu-toolchain]: https://developer.arm.com/Tools%20and%20Software/GNU%20Toolchain + +## Cross-compilation toolchains and C code + +This target supports C code compiled with the `aarch64-none-elf` target +triple and a suitable `-march` or `-mcpu` flag. + +## Start-up and Low-Level Code + +The [Rust Embedded Devices Working Group Arm Team] maintain the +[`aarch64-cpu`] crate, which may be useful for writing bare-metal code using +this target. + +The *TrustedFirmware* group also maintain [Rust crates for this +target](https://github.com/ArmFirmwareCrates). + +[`aarch64-cpu`]: https://docs.rs/aarch64-cpu diff --git a/src/doc/rustc/src/platform-support/arm-none-eabi.md b/src/doc/rustc/src/platform-support/arm-none-eabi.md index 9732df4be7f..aaa80e42971 100644 --- a/src/doc/rustc/src/platform-support/arm-none-eabi.md +++ b/src/doc/rustc/src/platform-support/arm-none-eabi.md @@ -12,10 +12,10 @@ their own document. ### Tier 2 Target List - Arm A-Profile Architectures - - `armv7a-none-eabi` + - [`armv7a-none-eabi`](armv7a-none-eabi.md) - Arm R-Profile Architectures - [`armv7r-none-eabi` and `armv7r-none-eabihf`](armv7r-none-eabi.md) - - [`armebv7r-none-eabi` and `armebv7r-none-eabihf`](armv7r-none-eabi.md) + - [`armebv7r-none-eabi` and `armebv7r-none-eabihf`](armebv7r-none-eabi.md) - Arm M-Profile Architectures - [`thumbv6m-none-eabi`](thumbv6m-none-eabi.md) - [`thumbv7m-none-eabi`](thumbv7m-none-eabi.md) @@ -28,7 +28,7 @@ their own document. ### Tier 3 Target List - Arm A-Profile Architectures - - `armv7a-none-eabihf` + - [`armv7a-none-eabihf`](armv7a-none-eabi.md) - Arm R-Profile Architectures - [`armv8r-none-eabihf`](armv8r-none-eabihf.md) - Arm M-Profile Architectures diff --git a/src/doc/rustc/src/platform-support/armebv7r-none-eabi.md b/src/doc/rustc/src/platform-support/armebv7r-none-eabi.md new file mode 100644 index 00000000000..3e90319c373 --- /dev/null +++ b/src/doc/rustc/src/platform-support/armebv7r-none-eabi.md @@ -0,0 +1,55 @@ +# `armebv7r-none-eabi` and `armebv7r-none-eabihf` + +* **Tier: 2** +* **Library Support:** core and alloc (bare-metal, `#![no_std]`) + +Bare-metal target for CPUs in the Armv7-R architecture family running in Big +Endian mode. These processors support dual ARM/Thumb mode, with ARM mode as +the default. + +**NOTE:** You should almost always prefer the [little-endian +versions](armv7r-none-eabi.md) of these target. Big Endian Arm systems are +highly unusual. + +Processors in this family include the [Arm Cortex-R4, 5, 7, and 8][cortex-r]. + +See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all +`arm-none-eabi` targets. + +[cortex-r]: https://en.wikipedia.org/wiki/ARM_Cortex-R + +## Target maintainers + +[@chrisnc](https://github.com/chrisnc) + +## Requirements + +Note that some variants of the Cortex-R have both big-endian instructions and +data. This configuration is known as BE-32, while data-only big-endianness is +known as BE-8. To build programs for BE-32 processors, the GNU linker must be +used with the `-mbe32` option. See [ARM Cortex-R Series Programmer's Guide: +Endianness][endianness] for more details about different endian modes. + +When using the hardfloat targets, the minimum floating-point features assumed +are those of the `vfpv3-d16`, which includes single- and double-precision, with +16 double-precision registers. This floating-point unit appears in Cortex-R4F +and Cortex-R5F processors. See [VFP in the Cortex-R processors][vfp] +for more details on the possible FPU variants. + +If your processor supports a different set of floating-point features than the +default expectations of `vfpv3-d16`, then these should also be enabled or +disabled as needed with `-C target-feature=(+/-)`. + +[endianness]: https://developer.arm.com/documentation/den0042/a/Coding-for-Cortex-R-Processors/Endianness + +[vfp]: https://developer.arm.com/documentation/den0042/a/Floating-Point/Floating-point-basics-and-the-IEEE-754-standard/VFP-in-the-Cortex-R-processors + +## Start-up and Low-Level Code + +The [Rust Embedded Devices Working Group Arm Team] maintain the [`cortex-ar`] +and [`cortex-r-rt`] crates, which may be useful for writing bare-metal code +using this target. Those crates include several examples which run in QEMU and +build using these targets. + +[`cortex-ar`]: https://docs.rs/cortex-ar +[`cortex-r-rt`]: https://docs.rs/cortex-r-rt diff --git a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md index 56f919e2a12..c6d88762fb1 100644 --- a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md @@ -1,6 +1,7 @@ # armv4t-none-eabi / thumbv4t-none-eabi -Tier 3 +* **Tier: 3** +* **Library Support:** core and alloc (bare-metal, `#![no_std]`) These two targets are part of the [`arm-none-eabi`](arm-none-eabi.md) target group, and all the information there applies. diff --git a/src/doc/rustc/src/platform-support/armv5te-none-eabi.md b/src/doc/rustc/src/platform-support/armv5te-none-eabi.md index 22287972b7e..e9f34d4ede8 100644 --- a/src/doc/rustc/src/platform-support/armv5te-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv5te-none-eabi.md @@ -1,6 +1,7 @@ # `armv5te-none-eabi` -**Tier: 3** +* **Tier: 3** +* **Library Support:** core and alloc (bare-metal, `#![no_std]`) Bare-metal target for any cpu in the Armv5TE architecture family, supporting ARM/Thumb code interworking (aka `A32`/`T32`), with `A32` code as the default code diff --git a/src/doc/rustc/src/platform-support/armv7a-none-eabi.md b/src/doc/rustc/src/platform-support/armv7a-none-eabi.md new file mode 100644 index 00000000000..3dadda86a5f --- /dev/null +++ b/src/doc/rustc/src/platform-support/armv7a-none-eabi.md @@ -0,0 +1,70 @@ +# `armv7a-none-eabi` and `armv7a-none-eabihf` + +* **Tier: 2** for `armv7a-none-eabi` +* **Tier: 3** for `armv7a-none-eabihf` +* **Library Support:** core and alloc (bare-metal, `#![no_std]`) + +Bare-metal target for CPUs in the Armv7-A architecture family, supporting +dual ARM/Thumb mode, with ARM mode as the default. + +Note, this is for processors running in AArch32 mode. For the AArch64 mode +added in Armv8-A, see [`aarch64-unknown-none`](aarch64-unknown-none.md) instead. + +Processors in this family include the [Arm Cortex-A5, 8, 32, etc][cortex-a]. + +See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all +`arm-none-eabi` targets. + +[cortex-a]: https://en.wikipedia.org/wiki/ARM_Cortex-A + +## Target maintainers + +[Rust Embedded Devices Working Group Arm Team] + +[Rust Embedded Devices Working Group Arm Team]: https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team + +## Requirements + +Almost all Armv7-A processors include an FPU (a VFPv3 or a VFPv4). The +difference between the `-eabi` and `-eabihf` targets is whether the FPU is +used for passing function arguments. You may prefer the `-eabi` soft-float +target when the processor does not have a floating point unit or the compiled +code should not use the floating point unit. + +When using the hardfloat targets, the minimum floating-point features assumed +are those of the VFPv3-D16, which includes single- and double-precision, with +16 double-precision registers. This floating-point unit appears in Cortex-A8 +and Cortex-A9 processors. See [VFP in the Cortex-A processors][vfp] for more +details on the possible FPU variants. + +If your processor supports a different set of floating-point features than the +default expectations of VFPv3-D16, then these should also be enabled or +disabled as needed with `-C target-feature=(+/-)`. + +In general, the following four combinations are possible: + +- VFPv3-D16, target feature `+vfp3` and `-d32` +- VFPv3-D32, target feature `+vfp3` and `+d32` +- VFPv4-D16, target feature `+vfp4` and `-d32` +- VFPv4-D32, target feature `+vfp4` and `+d32` + +An Armv7-A processor may optionally include a NEON hardware unit which +provides Single Instruction Multiple Data (SIMD) operations. The +implementation of this unit implies VFPv3-D32. The target feature `+neon` may +be added to inform the compiler about the availability of NEON. + +You can refer to the [arm-none-eabi](arm-none-eabi.md) documentation for a +generic guide on target feature and target CPU specification and how to enable +and disable them via `.cargo/config.toml` file. + +[vfp]: https://developer.arm.com/documentation/den0013/0400/Floating-Point/Floating-point-basics-and-the-IEEE-754-standard/ARM-VFP + +## Start-up and Low-Level Code + +The [Rust Embedded Devices Working Group Arm Team] maintain the [`cortex-ar`] +and [`cortex-a-rt`] crates, which may be useful for writing bare-metal code +using this target. The [`cortex-ar` repository](https://github.com/rust-embedded/cortex-ar) +includes several examples which run in QEMU and build using these targets. + +[`cortex-ar`]: https://docs.rs/cortex-ar +[`cortex-a-rt`]: https://docs.rs/cortex-a-rt diff --git a/src/doc/rustc/src/platform-support/armv7r-none-eabi.md b/src/doc/rustc/src/platform-support/armv7r-none-eabi.md index 88b2689dcf0..c1252b4a4bf 100644 --- a/src/doc/rustc/src/platform-support/armv7r-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv7r-none-eabi.md @@ -1,14 +1,13 @@ -# `arm(eb)?v7r-none-eabi(hf)?` +# `armv7r-none-eabi` and `armv7r-none-eabihf` -**Tier: 2** +* **Tier: 2** +* **Library Support:** core and alloc (bare-metal, `#![no_std]`) Bare-metal target for CPUs in the Armv7-R architecture family, supporting dual ARM/Thumb mode, with ARM mode as the default. Processors in this family include the [Arm Cortex-R4, 5, 7, and 8][cortex-r]. -The `eb` versions of this target generate code for big-endian processors. - See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all `arm-none-eabi` targets. @@ -17,15 +16,11 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all ## Target maintainers [@chrisnc](https://github.com/chrisnc) +[Rust Embedded Devices Working Group Arm Team] -## Requirements +[Rust Embedded Devices Working Group Arm Team]: https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team -When using the big-endian version of this target, note that some variants of -the Cortex-R have both big-endian instructions and data. This configuration is -known as BE-32, while data-only big-endianness is known as BE-8. To build -programs for BE-32 processors, the GNU linker must be used with the `-mbe32` -option. See [ARM Cortex-R Series Programmer's Guide: Endianness][endianness] -for more details about different endian modes. +## Requirements When using the hardfloat targets, the minimum floating-point features assumed are those of the `vfpv3-d16`, which includes single- and double-precision, with @@ -41,7 +36,12 @@ disabled as needed with `-C target-feature=(+/-)`. [vfp]: https://developer.arm.com/documentation/den0042/a/Floating-Point/Floating-point-basics-and-the-IEEE-754-standard/VFP-in-the-Cortex-R-processors -## Cross-compilation toolchains and C code +## Start-up and Low-Level Code + +The [Rust Embedded Devices Working Group Arm Team] maintain the [`cortex-ar`] +and [`cortex-r-rt`] crates, which may be useful for writing bare-metal code +using this target. Those crates include several examples which run in QEMU and +build using these targets. -This target supports C code compiled with the `arm-none-eabi` target triple and -`-march=armv7-r` or a suitable `-mcpu` flag. +[`cortex-ar`]: https://docs.rs/cortex-ar +[`cortex-r-rt`]: https://docs.rs/cortex-r-rt diff --git a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md index 569d8802ebe..0d5a36c3ee2 100644 --- a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md +++ b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md @@ -1,6 +1,7 @@ # `armv8r-none-eabihf` -**Tier: 3** +* **Tier: 3** +* **Library Support:** core and alloc (bare-metal, `#![no_std]`) Bare-metal target for CPUs in the Armv8-R architecture family, supporting dual ARM/Thumb mode, with ARM mode as the default. @@ -17,6 +18,9 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all ## Target maintainers [@chrisnc](https://github.com/chrisnc) +[Rust Embedded Devices Working Group Arm Team] + +[Rust Embedded Devices Working Group Arm Team]: https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team ## Requirements @@ -34,7 +38,14 @@ Technical Reference Manual for more details. [fpu]: https://developer.arm.com/documentation/100026/0104/Advanced-SIMD-and-floating-point-support/About-the-Advanced-SIMD-and-floating-point-support -## Cross-compilation toolchains and C code - -This target supports C code compiled with the `arm-none-eabi` target triple and -`-march=armv8-r` or a suitable `-mcpu` flag. +### Table of supported CPUs for `armv8r-none-eabihf` + +| CPU | FPU | Neon | Target CPU | Target Features | +|:----------- | --- |:---- |:---------------- |:------------------ | +| Any | SP | No | None | None | +| Cortex-R52 | SP | No | `cortex-r52` | `-fp64,-d32,-neon` | +| Cortex-R52 | DP | No | `cortex-r52` | `-neon` | +| Cortex-R52 | DP | Yes | `cortex-r52` | None | +| Cortex-R52+ | SP | No | `cortex-r52plus` | `-fp64,-d32,-neon` | +| Cortex-R52+ | DP | No | `cortex-r52plus` | `-neon` | +| Cortex-R52+ | DP | Yes | `cortex-r52plus` | None | diff --git a/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md index 746b8443547..d4bd0b0945a 100644 --- a/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md @@ -1,6 +1,7 @@ # `thumbv6m-none-eabi` -**Tier: 2** +* **Tier: 2** +* **Library Support:** core and alloc (bare-metal, `#![no_std]`) Bare-metal target for CPUs in the [Armv6-M] architecture family, supporting a subset of the [T32 ISA][t32-isa]. @@ -26,7 +27,7 @@ only option because there is no FPU support in [Armv6-M]. ## Target maintainers -* [Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team) +[Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team) ## Target CPU and Target Feature options diff --git a/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md index 12e28265678..98dcf9bd396 100644 --- a/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md @@ -1,6 +1,7 @@ # `thumbv7em-none-eabi` and `thumbv7em-none-eabihf` -**Tier: 2** +* **Tier: 2** +* **Library Support:** core and alloc (bare-metal, `#![no_std]`) Bare-metal target for CPUs in the [Armv7E-M] architecture family, supporting a subset of the [T32 ISA][t32-isa]. @@ -21,7 +22,7 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all ## Target maintainers -* [Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team) +[Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team) ## Target CPU and Target Feature options diff --git a/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md index 03324b341d0..d8f3970c8bf 100644 --- a/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md @@ -1,6 +1,7 @@ # `thumbv7m-none-eabi` -**Tier: 2** +* **Tier: 2** +* **Library Support:** core and alloc (bare-metal, `#![no_std]`) Bare-metal target for CPUs in the [Armv7-M] architecture family, supporting a subset of the [T32 ISA][t32-isa]. @@ -22,7 +23,7 @@ only option because there is no FPU support in [Armv7-M]. ## Target maintainers -* [Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team) +[Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team) ## Target CPU and Target Feature options diff --git a/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md index 4a92e856466..b16d450275d 100644 --- a/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md @@ -1,6 +1,7 @@ # `thumbv8m.base-none-eabi` -**Tier: 2** +* **Tier: 2** +* **Library Support:** core and alloc (bare-metal, `#![no_std]`) Bare-metal target for CPUs in the Baseline [Armv8-M] architecture family, supporting a subset of the [T32 ISA][t32-isa]. @@ -22,7 +23,7 @@ only option because there is no FPU support in [Armv8-M] Baseline. ## Target maintainers -* [Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team) +[Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team) ## Target CPU and Target Feature options diff --git a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md index 9f85d08fa0a..a2d515d07ea 100644 --- a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md @@ -1,6 +1,7 @@ # `thumbv8m.main-none-eabi` and `thumbv8m.main-none-eabihf` -**Tier: 2** +* **Tier: 2** +* **Library Support:** core and alloc (bare-metal, `#![no_std]`) Bare-metal target for CPUs in the Mainline [Armv8-M] architecture family, supporting a subset of the [T32 ISA][t32-isa]. @@ -25,7 +26,7 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all ## Target maintainers -* [Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team) +[Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team) ## Target CPU and Target Feature options diff --git a/src/doc/rustc/src/targets/custom.md b/src/doc/rustc/src/targets/custom.md index 6c1494186a4..e1750e27f0b 100644 --- a/src/doc/rustc/src/targets/custom.md +++ b/src/doc/rustc/src/targets/custom.md @@ -16,6 +16,21 @@ rustc +nightly -Z unstable-options --target=wasm32-unknown-unknown --print targe To use a custom target, see the (unstable) [`build-std` feature](../../cargo/reference/unstable.html#build-std) of `cargo`. +<div class="warning"> + +The target JSON properties are not stable and subject to change. +Always pin your compiler version when using custom targets! + +</div> + +## JSON Schema + +`rustc` provides a JSON schema for the custom target JSON specification. +Because the schema is subject to change, you should always use the schema from the version of rustc which you are passing the target to. + +It can be found in `etc/target-spec-json-schema.json` in the sysroot (`rustc --print sysroot`) or printed with `rustc +nightly -Zunstable-options --print target-spec-json-schema`. +The existence and name of this schema is, just like the properties of the JSON specification, not stable and subject to change. + ## Custom Target Lookup Path When `rustc` is given an option `--target=TARGET` (where `TARGET` is any string), it uses the following logic: diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 93932936a2e..5ccacafea01 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1256,7 +1256,10 @@ pub(crate) fn clean_impl_item<'tcx>( })), hir::ImplItemKind::Fn(ref sig, body) => { let m = clean_function(cx, sig, impl_.generics, ParamsSrc::Body(body)); - let defaultness = cx.tcx.defaultness(impl_.owner_id); + let defaultness = match impl_.impl_kind { + hir::ImplItemImplKind::Inherent { .. } => hir::Defaultness::Final, + hir::ImplItemImplKind::Trait { defaultness, .. } => defaultness, + }; MethodItem(m, Some(defaultness)) } hir::ImplItemKind::Type(hir_ty) => { @@ -1295,12 +1298,14 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo simplify::move_bounds_to_generic_parameters(&mut generics); match assoc_item.container { - ty::AssocItemContainer::Impl => ImplAssocConstItem(Box::new(Constant { - generics, - kind: ConstantKind::Extern { def_id: assoc_item.def_id }, - type_: ty, - })), - ty::AssocItemContainer::Trait => { + ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => { + ImplAssocConstItem(Box::new(Constant { + generics, + kind: ConstantKind::Extern { def_id: assoc_item.def_id }, + type_: ty, + })) + } + ty::AssocContainer::Trait => { if tcx.defaultness(assoc_item.def_id).has_value() { ProvidedAssocConstItem(Box::new(Constant { generics, @@ -1318,10 +1323,10 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo if has_self { let self_ty = match assoc_item.container { - ty::AssocItemContainer::Impl => { + ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => { tcx.type_of(assoc_item.container_id(tcx)).instantiate_identity() } - ty::AssocItemContainer::Trait => tcx.types.self_param, + ty::AssocContainer::Trait => tcx.types.self_param, }; let self_param_ty = tcx.fn_sig(assoc_item.def_id).instantiate_identity().input(0).skip_binder(); @@ -1338,13 +1343,13 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo } let provided = match assoc_item.container { - ty::AssocItemContainer::Impl => true, - ty::AssocItemContainer::Trait => assoc_item.defaultness(tcx).has_value(), + ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => true, + ty::AssocContainer::Trait => assoc_item.defaultness(tcx).has_value(), }; if provided { let defaultness = match assoc_item.container { - ty::AssocItemContainer::Impl => Some(assoc_item.defaultness(tcx)), - ty::AssocItemContainer::Trait => None, + ty::AssocContainer::TraitImpl(_) => Some(assoc_item.defaultness(tcx)), + ty::AssocContainer::InherentImpl | ty::AssocContainer::Trait => None, }; MethodItem(item, defaultness) } else { @@ -1375,7 +1380,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo } let mut predicates = tcx.explicit_predicates_of(assoc_item.def_id).predicates; - if let ty::AssocItemContainer::Trait = assoc_item.container { + if let ty::AssocContainer::Trait = assoc_item.container { let bounds = tcx.explicit_item_bounds(assoc_item.def_id).iter_identity_copied(); predicates = tcx.arena.alloc_from_iter(bounds.chain(predicates.iter().copied())); } @@ -1386,7 +1391,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo ); simplify::move_bounds_to_generic_parameters(&mut generics); - if let ty::AssocItemContainer::Trait = assoc_item.container { + if let ty::AssocContainer::Trait = assoc_item.container { // Move bounds that are (likely) directly attached to the associated type // from the where-clause to the associated type. // There is no guarantee that this is what the user actually wrote but we have diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index dcd67cb7ebc..bd3f4e9a6f2 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -690,16 +690,13 @@ impl Item { // rustc's `is_const_fn` returns `true` for associated functions that have an `impl const` parent // or that have a `const trait` parent. Do not display those as `const` in rustdoc because we // won't be printing correct syntax plus the syntax is unstable. - match tcx.opt_associated_item(def_id) { - Some(ty::AssocItem { - container: ty::AssocItemContainer::Impl, - trait_item_def_id: Some(_), - .. - }) - | Some(ty::AssocItem { container: ty::AssocItemContainer::Trait, .. }) => { - hir::Constness::NotConst - } - None | Some(_) => hir::Constness::Const, + if let Some(assoc) = tcx.opt_associated_item(def_id) + && let ty::AssocContainer::Trait | ty::AssocContainer::TraitImpl(_) = + assoc.container + { + hir::Constness::NotConst + } else { + hir::Constness::Const } } else { hir::Constness::NotConst @@ -779,17 +776,13 @@ impl Item { | RequiredAssocTypeItem(..) | RequiredMethodItem(..) | MethodItem(..) => { - let assoc_item = tcx.associated_item(def_id); - let is_trait_item = match assoc_item.container { - ty::AssocItemContainer::Trait => true, - ty::AssocItemContainer::Impl => { - // Trait impl items always inherit the impl's visibility -- - // we don't want to show `pub`. - tcx.impl_trait_ref(tcx.parent(assoc_item.def_id)).is_some() + match tcx.associated_item(def_id).container { + // Trait impl items always inherit the impl's visibility -- + // we don't want to show `pub`. + ty::AssocContainer::Trait | ty::AssocContainer::TraitImpl(_) => { + return None; } - }; - if is_trait_item { - return None; + ty::AssocContainer::InherentImpl => {} } } _ => {} diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 719b7c6ab89..0da42f38251 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -210,7 +210,7 @@ impl UrlFragment { &UrlFragment::Item(def_id) => { let kind = match tcx.def_kind(def_id) { DefKind::AssocFn => { - if tcx.defaultness(def_id).has_value() { + if tcx.associated_item(def_id).defaultness(tcx).has_value() { "method." } else { "tymethod." diff --git a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs index 23e7c7251cf..49cd2671dc0 100644 --- a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs +++ b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs @@ -8,7 +8,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefIdMap; use rustc_hir::{ - AmbigArg, Expr, ExprKind, ForeignItem, HirId, ImplItem, Item, ItemKind, OwnerId, Pat, Path, Stmt, TraitItem, Ty, + AmbigArg, Expr, ExprKind, ForeignItem, HirId, ImplItem, ImplItemImplKind, Item, ItemKind, OwnerId, Pat, Path, Stmt, TraitItem, Ty, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::TyCtxt; @@ -177,7 +177,9 @@ impl LateLintPass<'_> for DisallowedMacros { fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &ImplItem<'_>) { self.check(cx, item.span, None); - self.check(cx, item.vis_span, None); + if let ImplItemImplKind::Inherent { vis_span, .. } = item.impl_kind { + self.check(cx, vis_span, None); + } } fn check_trait_item(&mut self, cx: &LateContext<'_>, item: &TraitItem<'_>) { diff --git a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs index f8e8f5544b9..e25611d4881 100644 --- a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs +++ b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs @@ -1,7 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use rustc_errors::{Applicability, MultiSpan}; -use rustc_hir::def_id::{DefId, DefIdSet}; -use rustc_hir::hir_id::OwnerId; +use rustc_hir::def_id::DefIdSet; use rustc_hir::{Impl, ImplItem, ImplItemKind, ItemKind, Node, TraitRef}; use rustc_lint::LateContext; use rustc_span::Span; @@ -19,7 +18,7 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, item: &ImplItem<'_>, ignored of_trait: Some(of_trait), .. }) = &parent_item.kind - && let Some(did) = trait_item_def_id_of_impl(cx, item.owner_id) + && let Some(did) = cx.tcx.trait_item_of(item.owner_id) && !is_from_ignored_trait(&of_trait.trait_ref, ignored_traits) { let mut param_idents_iter = cx.tcx.hir_body_param_idents(body_id); @@ -87,11 +86,6 @@ impl RenamedFnArgs { } } -/// Get the [`trait_item_def_id`](ImplItemRef::trait_item_def_id) of a relevant impl item. -fn trait_item_def_id_of_impl(cx: &LateContext<'_>, target: OwnerId) -> Option<DefId> { - cx.tcx.associated_item(target).trait_item_def_id -} - fn is_from_ignored_trait(of_trait: &TraitRef<'_>, ignored_traits: &DefIdSet) -> bool { of_trait .trait_def_id() diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs index ba1ad599e11..bee3b19b597 100644 --- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs +++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs @@ -4,7 +4,7 @@ use rustc_errors::Applicability; use rustc_hir::intravisit::FnKind; use rustc_hir::{ Block, Body, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl, - FnRetTy, GenericBound, ImplItem, Item, Node, OpaqueTy, TraitRef, Ty, TyKind, + FnRetTy, GenericBound, Node, OpaqueTy, TraitRef, Ty, TyKind, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::middle::resolve_bound_vars::ResolvedArg; @@ -60,8 +60,11 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn { && let ExprKind::Block(block, _) = body.value.kind && block.stmts.is_empty() && let Some(closure_body) = desugared_async_block(cx, block) - && let Node::Item(Item {vis_span, ..}) | Node::ImplItem(ImplItem {vis_span, ..}) = - cx.tcx.hir_node_by_def_id(fn_def_id) + && let Some(vis_span_opt) = match cx.tcx.hir_node_by_def_id(fn_def_id) { + Node::Item(item) => Some(Some(item.vis_span)), + Node::ImplItem(impl_item) => Some(impl_item.vis_span()), + _ => None, + } && !span.from_expansion() { let header_span = span.with_hi(ret_ty.span.hi()); @@ -72,7 +75,8 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn { header_span, "this function can be simplified using the `async fn` syntax", |diag| { - if let Some(vis_snip) = vis_span.get_source_text(cx) + if let Some(vis_span) = vis_span_opt + && let Some(vis_snip) = vis_span.get_source_text(cx) && let Some(header_snip) = header_span.get_source_text(cx) && let Some(ret_pos) = position_before_rarrow(&header_snip) && let Some((_, ret_snip)) = suggested_ret(cx, output) diff --git a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs index dbce29a8631..6258e408217 100644 --- a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs +++ b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs @@ -5,8 +5,8 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{Visitor, walk_item, walk_trait_item}; use rustc_hir::{ - GenericParamKind, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, ItemLocalId, Node, Pat, PatKind, TraitItem, - UsePath, + GenericParamKind, HirId, Impl, ImplItem, ImplItemImplKind, ImplItemKind, Item, ItemKind, ItemLocalId, Node, Pat, + PatKind, TraitItem, UsePath, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::impl_lint_pass; @@ -256,7 +256,7 @@ fn is_not_in_trait_impl(cx: &LateContext<'_>, pat: &Pat<'_>, ident: Ident) -> bo } fn get_param_name(impl_item: &ImplItem<'_>, cx: &LateContext<'_>, ident: Ident) -> Option<Symbol> { - if let Some(trait_item_def_id) = impl_item.trait_item_def_id { + if let ImplItemImplKind::Trait { trait_item_def_id: Ok(trait_item_def_id), .. } = impl_item.impl_kind { let trait_param_names = cx.tcx.fn_arg_idents(trait_item_def_id); let ImplItemKind::Fn(_, body_id) = impl_item.kind else { diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs index a6be7581c9a..a63ad978626 100644 --- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs +++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs @@ -158,13 +158,23 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { let mir = cx.tcx.optimized_mir(def_id); if let Ok(()) = is_min_const_fn(cx, mir, self.msrv) - && let hir::Node::Item(hir::Item { vis_span, .. }) | hir::Node::ImplItem(hir::ImplItem { vis_span, .. }) = - cx.tcx.hir_node_by_def_id(def_id) + && let node = cx.tcx.hir_node_by_def_id(def_id) + && let Some((item_span, vis_span_opt)) = match node { + hir::Node::Item(item) => Some((item.span, Some(item.vis_span))), + hir::Node::ImplItem(impl_item) => Some((impl_item.span, impl_item.vis_span())), + _ => None, + } { - let suggestion = if vis_span.is_empty() { "const " } else { " const" }; + let (sugg_span, suggestion) = if let Some(vis_span) = vis_span_opt + && !vis_span.is_empty() + { + (vis_span.shrink_to_hi(), " const") + } else { + (item_span.shrink_to_lo(), "const ") + }; span_lint_and_then(cx, MISSING_CONST_FOR_FN, span, "this could be a `const fn`", |diag| { diag.span_suggestion_verbose( - vis_span.shrink_to_hi(), + sugg_span, "make the function `const`", suggestion, Applicability::MachineApplicable, diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 7772051eb5c..39b5964bd87 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -16,7 +16,7 @@ use rustc_hir::Attribute; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::ty::Visibility; +use rustc_middle::ty::{AssocContainer, Visibility}; use rustc_session::impl_lint_pass; use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::symbol::kw; @@ -246,12 +246,11 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) { // If the method is an impl for a trait, don't doc. - if let Some(cid) = cx.tcx.associated_item(impl_item.owner_id).impl_container(cx.tcx) { - if cx.tcx.impl_trait_ref(cid).is_some() { + match cx.tcx.associated_item(impl_item.owner_id).container { + AssocContainer::Trait | AssocContainer::TraitImpl(_) => { note_prev_span_then_ret!(self.prev_span, impl_item.span); - } - } else { - note_prev_span_then_ret!(self.prev_span, impl_item.span); + }, + AssocContainer::InherentImpl => {} } let (article, desc) = cx.tcx.article_and_description(impl_item.owner_id.to_def_id()); diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index 28555a61090..6323e728666 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -3,7 +3,7 @@ use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, Attribute, find_attr}; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::ty::AssocItemContainer; +use rustc_middle::ty::AssocContainer; use rustc_session::declare_lint_pass; use rustc_span::Span; @@ -166,8 +166,9 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { let assoc_item = cx.tcx.associated_item(impl_item.owner_id); let container_id = assoc_item.container_id(cx.tcx); let trait_def_id = match assoc_item.container { - AssocItemContainer::Trait => Some(container_id), - AssocItemContainer::Impl => cx.tcx.impl_trait_ref(container_id).map(|t| t.skip_binder().def_id), + AssocContainer::Trait => Some(container_id), + AssocContainer::TraitImpl(_) => cx.tcx.impl_trait_ref(container_id).map(|t| t.skip_binder().def_id), + AssocContainer::InherentImpl => None, }; if let Some(trait_def_id) = trait_def_id diff --git a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs index 9cc93bf0653..8e9400e9d58 100644 --- a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs +++ b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs @@ -70,7 +70,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingTraitMethods { .tcx .associated_items(item.owner_id) .in_definition_order() - .filter_map(|assoc_item| assoc_item.trait_item_def_id) + .filter_map(|assoc_item| assoc_item.expect_trait_impl().ok()) .collect(); for assoc in cx diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs index 809a6728e12..c4cad592e36 100644 --- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs @@ -248,7 +248,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { .tcx .impl_trait_ref(item.owner_id) .map(EarlyBinder::instantiate_identity) - && let Some(trait_item_id) = cx.tcx.associated_item(owner_id).trait_item_def_id + && let Some(trait_item_id) = cx.tcx.trait_item_of(owner_id) { ( trait_item_id, diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs index aeda864b7eb..8252e6d4869 100644 --- a/src/tools/clippy/clippy_lints/src/use_self.rs +++ b/src/tools/clippy/clippy_lints/src/use_self.rs @@ -151,8 +151,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { // trait, not in the impl of the trait. let trait_method = cx .tcx - .associated_item(impl_item.owner_id) - .trait_item_def_id + .trait_item_of(impl_item.owner_id) .expect("impl method matches a trait method"); let trait_method_sig = cx.tcx.fn_sig(trait_method).instantiate_identity(); let trait_method_sig = cx.tcx.instantiate_bound_regions_with_erased(trait_method_sig); diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs index c4a759e919b..1a25c90d735 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -19,7 +19,7 @@ use rustc_ast::token::CommentKind; use rustc_hir::intravisit::FnKind; use rustc_hir::{ Block, BlockCheckMode, Body, Closure, Destination, Expr, ExprKind, FieldDef, FnHeader, FnRetTy, HirId, Impl, - ImplItem, ImplItemKind, IsAuto, Item, ItemKind, Lit, LoopSource, MatchSource, MutTy, Node, Path, QPath, Safety, + ImplItem, ImplItemImplKind, ImplItemKind, IsAuto, Item, ItemKind, Lit, LoopSource, MatchSource, MutTy, Node, Path, QPath, Safety, TraitImplHeader, TraitItem, TraitItemKind, Ty, TyKind, UnOp, UnsafeSource, Variant, VariantData, YieldSource, }; use rustc_lint::{EarlyContext, LateContext, LintContext}; @@ -280,16 +280,17 @@ fn trait_item_search_pat(item: &TraitItem<'_>) -> (Pat, Pat) { } fn impl_item_search_pat(item: &ImplItem<'_>) -> (Pat, Pat) { - let (start_pat, end_pat) = match &item.kind { + let (mut start_pat, end_pat) = match &item.kind { ImplItemKind::Const(..) => (Pat::Str("const"), Pat::Str(";")), ImplItemKind::Type(..) => (Pat::Str("type"), Pat::Str(";")), ImplItemKind::Fn(sig, ..) => (fn_header_search_pat(sig.header), Pat::Str("")), }; - if item.vis_span.is_empty() { - (start_pat, end_pat) - } else { - (Pat::Str("pub"), end_pat) - } + if let ImplItemImplKind::Inherent { vis_span, .. } = item.impl_kind + && !vis_span.is_empty() + { + start_pat = Pat::Str("pub"); + }; + (start_pat, end_pat) } fn field_def_search_pat(def: &FieldDef<'_>) -> (Pat, Pat) { @@ -313,21 +314,20 @@ fn variant_search_pat(v: &Variant<'_>) -> (Pat, Pat) { } fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirId) -> (Pat, Pat) { - let (start_pat, end_pat) = match kind { + let (mut start_pat, end_pat) = match kind { FnKind::ItemFn(.., header) => (fn_header_search_pat(*header), Pat::Str("")), FnKind::Method(.., sig) => (fn_header_search_pat(sig.header), Pat::Str("")), FnKind::Closure => return (Pat::Str(""), expr_search_pat(tcx, body.value).1), }; - let start_pat = match tcx.hir_node(hir_id) { - Node::Item(Item { vis_span, .. }) | Node::ImplItem(ImplItem { vis_span, .. }) => { - if vis_span.is_empty() { - start_pat - } else { - Pat::Str("pub") + match tcx.hir_node(hir_id) { + Node::Item(Item { vis_span, .. }) + | Node::ImplItem(ImplItem { impl_kind: ImplItemImplKind::Inherent { vis_span, .. }, .. }) => { + if !vis_span.is_empty() { + start_pat = Pat::Str("pub") } }, - Node::TraitItem(_) => start_pat, - _ => Pat::Str(""), + Node::ImplItem(_) | Node::TraitItem(_) => {}, + _ => start_pat = Pat::Str(""), }; (start_pat, end_pat) } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index e1077bdf4b1..120ab2e717d 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -3244,8 +3244,8 @@ pub fn get_path_from_caller_to_method_type<'tcx>( let assoc_item = tcx.associated_item(method); let def_id = assoc_item.container_id(tcx); match assoc_item.container { - rustc_ty::AssocItemContainer::Trait => get_path_to_callee(tcx, from, def_id), - rustc_ty::AssocItemContainer::Impl => { + rustc_ty::AssocContainer::Trait => get_path_to_callee(tcx, from, def_id), + rustc_ty::AssocContainer::InherentImpl | rustc_ty::AssocContainer::TraitImpl(_) => { let ty = tcx.type_of(def_id).instantiate_identity(); get_path_to_ty(tcx, from, ty, args) }, diff --git a/src/tools/miri/tests/pass/btreemap.rs b/src/tools/miri/tests/pass/btreemap.rs index 1d65e69bf72..7af6d7b5551 100644 --- a/src/tools/miri/tests/pass/btreemap.rs +++ b/src/tools/miri/tests/pass/btreemap.rs @@ -1,7 +1,6 @@ //@revisions: stack tree //@[tree]compile-flags: -Zmiri-tree-borrows //@compile-flags: -Zmiri-strict-provenance -#![feature(btree_extract_if)] use std::collections::{BTreeMap, BTreeSet}; use std::mem; diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 60347b2ea64..a9804761400 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -267,6 +267,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "digest", "displaydoc", "dissimilar", + "dyn-clone", "either", "elsa", "ena", @@ -346,6 +347,8 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "rand_xorshift", // dependency for doc-tests in rustc_thread_pool "rand_xoshiro", "redox_syscall", + "ref-cast", + "ref-cast-impl", "regex", "regex-automata", "regex-syntax", @@ -357,11 +360,14 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "rustix", "ruzstd", // via object in thorin-dwp "ryu", + "schemars", + "schemars_derive", "scoped-tls", "scopeguard", "self_cell", "serde", "serde_derive", + "serde_derive_internals", "serde_json", "serde_path_to_error", "sha1", diff --git a/src/tools/tidy/src/fluent_lowercase.rs b/src/tools/tidy/src/fluent_lowercase.rs new file mode 100644 index 00000000000..13f0319909e --- /dev/null +++ b/src/tools/tidy/src/fluent_lowercase.rs @@ -0,0 +1,64 @@ +//! Checks that the error messages start with a lowercased letter (except when allowed to). + +use std::path::Path; + +use fluent_syntax::ast::{Entry, Message, PatternElement}; + +use crate::walk::{filter_dirs, walk}; + +#[rustfmt::skip] +const ALLOWED_CAPITALIZED_WORDS: &[&str] = &[ + // tidy-alphabetical-start + "ABI", + "ABIs", + "ADT", + "C", + "CGU", + "Ferris", + "MIR", + "OK", + "Rust", + "VS", // VS Code + // tidy-alphabetical-end +]; + +fn filter_fluent(path: &Path) -> bool { + if let Some(ext) = path.extension() { ext.to_str() != Some("ftl") } else { true } +} + +fn is_allowed_capitalized_word(msg: &str) -> bool { + ALLOWED_CAPITALIZED_WORDS.iter().any(|word| { + msg.strip_prefix(word) + .map(|tail| tail.chars().next().map(|c| c == '-' || c.is_whitespace()).unwrap_or(true)) + .unwrap_or_default() + }) +} + +fn check_lowercase(filename: &str, contents: &str, bad: &mut bool) { + let (Ok(parse) | Err((parse, _))) = fluent_syntax::parser::parse(contents); + + for entry in &parse.body { + if let Entry::Message(msg) = entry + && let Message { value: Some(pattern), .. } = msg + && let [first_pattern, ..] = &pattern.elements[..] + && let PatternElement::TextElement { value } = first_pattern + && value.chars().next().is_some_and(char::is_uppercase) + && !is_allowed_capitalized_word(value) + { + tidy_error!( + bad, + "{filename}: message `{value}` starts with an uppercase letter. Fix it or add it to `ALLOWED_CAPITALIZED_WORDS`" + ); + } + } +} + +pub fn check(path: &Path, bad: &mut bool) { + walk( + path, + |path, is_dir| filter_dirs(path) || (!is_dir && filter_fluent(path)), + &mut |ent, contents| { + check_lowercase(ent.path().to_str().unwrap(), contents, bad); + }, + ); +} diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 37713cbf75e..2a9c3963d2d 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -257,6 +257,7 @@ pub mod extra_checks; pub mod features; pub mod filenames; pub mod fluent_alphabetical; +pub mod fluent_lowercase; pub mod fluent_period; mod fluent_used; pub mod gcc_submodule; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index bfe30258915..f9e82341b7a 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -121,6 +121,7 @@ fn main() { check!(error_codes, &root_path, &[&compiler_path, &librustdoc_path], verbose, &ci_info); check!(fluent_alphabetical, &compiler_path, bless); check!(fluent_period, &compiler_path); + check!(fluent_lowercase, &compiler_path); check!(target_policy, &root_path); check!(gcc_submodule, &root_path, &compiler_path); diff --git a/tests/run-make/print-request-help-stable-unstable/help-diff.diff b/tests/run-make/print-request-help-stable-unstable/help-diff.diff index 07eafca3271..044302a19a0 100644 --- a/tests/run-make/print-request-help-stable-unstable/help-diff.diff +++ b/tests/run-make/print-request-help-stable-unstable/help-diff.diff @@ -2,6 +2,6 @@ error: unknown print request: `xxx` | - = help: valid print requests are: `calling-conventions`, `cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `tls-models` -+ = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models` ++ = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models` = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information diff --git a/tests/run-make/print-request-help-stable-unstable/unstable-invalid-print-request-help.err b/tests/run-make/print-request-help-stable-unstable/unstable-invalid-print-request-help.err index 50ef340e3dd..cc6c3c909b3 100644 --- a/tests/run-make/print-request-help-stable-unstable/unstable-invalid-print-request-help.err +++ b/tests/run-make/print-request-help-stable-unstable/unstable-invalid-print-request-help.err @@ -1,5 +1,5 @@ error: unknown print request: `xxx` | - = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models` + = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models` = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information diff --git a/tests/run-make/rustc-help/help-v.stdout b/tests/run-make/rustc-help/help-v.stdout index 3fc297fb08e..cd161c51ee3 100644 --- a/tests/run-make/rustc-help/help-v.stdout +++ b/tests/run-make/rustc-help/help-v.stdout @@ -43,7 +43,7 @@ Options: --print <INFO>[=<FILE>] Compiler information to print on stdout (or to a file) INFO may be one of - <all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models>. + <all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>. -g Equivalent to -C debuginfo=2 -O Equivalent to -C opt-level=3 -o <FILENAME> Write output to FILENAME diff --git a/tests/run-make/rustc-help/help.stdout b/tests/run-make/rustc-help/help.stdout index caffe28f498..74ec083bdee 100644 --- a/tests/run-make/rustc-help/help.stdout +++ b/tests/run-make/rustc-help/help.stdout @@ -43,7 +43,7 @@ Options: --print <INFO>[=<FILE>] Compiler information to print on stdout (or to a file) INFO may be one of - <all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models>. + <all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>. -g Equivalent to -C debuginfo=2 -O Equivalent to -C opt-level=3 -o <FILENAME> Write output to FILENAME diff --git a/tests/ui/issues/issue-56806.rs b/tests/ui/abi/invalid-self-parameter-type-56806.rs index b1dac26d65a..60229df3005 100644 --- a/tests/ui/issues/issue-56806.rs +++ b/tests/ui/abi/invalid-self-parameter-type-56806.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/56806 pub trait Trait { fn dyn_instead_of_self(self: Box<dyn Trait>); //~^ ERROR invalid `self` parameter type diff --git a/tests/ui/issues/issue-56806.stderr b/tests/ui/abi/invalid-self-parameter-type-56806.stderr index ec50d863758..ac249b8f108 100644 --- a/tests/ui/issues/issue-56806.stderr +++ b/tests/ui/abi/invalid-self-parameter-type-56806.stderr @@ -1,5 +1,5 @@ error[E0307]: invalid `self` parameter type: `Box<(dyn Trait + 'static)>` - --> $DIR/issue-56806.rs:2:34 + --> $DIR/invalid-self-parameter-type-56806.rs:3:34 | LL | fn dyn_instead_of_self(self: Box<dyn Trait>); | ^^^^^^^^^^^^^^ diff --git a/tests/ui/issues/issue-56870.rs b/tests/ui/associated-consts/traits-associated-consts-ice-56870.rs index fc6deedd029..0c5a2b84773 100644 --- a/tests/ui/issues/issue-56870.rs +++ b/tests/ui/associated-consts/traits-associated-consts-ice-56870.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/56870 //@ build-pass // Regression test for #56870: Internal compiler error (traits & associated consts) diff --git a/tests/ui/issues/issue-59326.rs b/tests/ui/associated-types/duplicate-associated-type-resolution-59326.rs index e9634ad9fd8..0439e229e14 100644 --- a/tests/ui/issues/issue-59326.rs +++ b/tests/ui/associated-types/duplicate-associated-type-resolution-59326.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/59326 //@ check-pass trait Service { type S; diff --git a/tests/ui/issues/issue-57399-self-return-impl-trait.rs b/tests/ui/associated-types/impl-trait-member-type-resolution-57399.rs index bcf1b18a9ff..3342dd0631a 100644 --- a/tests/ui/issues/issue-57399-self-return-impl-trait.rs +++ b/tests/ui/associated-types/impl-trait-member-type-resolution-57399.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/57399 //@ check-pass trait T { @@ -12,7 +13,6 @@ struct S<A> { a: A, } - impl From<u32> for S<<i32 as T>::T> { fn from(a: u32) -> Self { Self { a } diff --git a/tests/ui/issues/issue-59488.rs b/tests/ui/binop/function-comparison-errors-59488.rs index 384501e3e5d..8ded781ef95 100644 --- a/tests/ui/issues/issue-59488.rs +++ b/tests/ui/binop/function-comparison-errors-59488.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/59488 fn foo() -> i32 { 42 } diff --git a/tests/ui/issues/issue-59488.stderr b/tests/ui/binop/function-comparison-errors-59488.stderr index b6611ad63a8..615458bc45b 100644 --- a/tests/ui/issues/issue-59488.stderr +++ b/tests/ui/binop/function-comparison-errors-59488.stderr @@ -1,5 +1,5 @@ error[E0369]: binary operation `>` cannot be applied to type `fn() -> i32 {foo}` - --> $DIR/issue-59488.rs:14:9 + --> $DIR/function-comparison-errors-59488.rs:15:9 | LL | foo > 12; | --- ^ -- {integer} @@ -12,7 +12,7 @@ LL | foo() > 12; | ++ error[E0308]: mismatched types - --> $DIR/issue-59488.rs:14:11 + --> $DIR/function-comparison-errors-59488.rs:15:11 | LL | foo > 12; | ^^ expected fn item, found `i32` @@ -21,7 +21,7 @@ LL | foo > 12; found type `i32` error[E0369]: binary operation `>` cannot be applied to type `fn(i64) -> i64 {bar}` - --> $DIR/issue-59488.rs:18:9 + --> $DIR/function-comparison-errors-59488.rs:19:9 | LL | bar > 13; | --- ^ -- {integer} @@ -34,7 +34,7 @@ LL | bar(/* i64 */) > 13; | +++++++++++ error[E0308]: mismatched types - --> $DIR/issue-59488.rs:18:11 + --> $DIR/function-comparison-errors-59488.rs:19:11 | LL | bar > 13; | ^^ expected fn item, found `i64` @@ -43,7 +43,7 @@ LL | bar > 13; found type `i64` error[E0369]: binary operation `>` cannot be applied to type `fn() -> i32 {foo}` - --> $DIR/issue-59488.rs:22:9 + --> $DIR/function-comparison-errors-59488.rs:23:9 | LL | foo > foo; | --- ^ --- fn() -> i32 {foo} @@ -56,7 +56,7 @@ LL | foo() > foo(); | ++ ++ error[E0369]: binary operation `>` cannot be applied to type `fn() -> i32 {foo}` - --> $DIR/issue-59488.rs:25:9 + --> $DIR/function-comparison-errors-59488.rs:26:9 | LL | foo > bar; | --- ^ --- fn(i64) -> i64 {bar} @@ -64,7 +64,7 @@ LL | foo > bar; | fn() -> i32 {foo} error[E0308]: mismatched types - --> $DIR/issue-59488.rs:25:11 + --> $DIR/function-comparison-errors-59488.rs:26:11 | LL | foo > bar; | ^^^ expected fn item, found a different fn item @@ -73,7 +73,7 @@ LL | foo > bar; found fn item `fn(i64) -> i64 {bar}` error[E0369]: binary operation `==` cannot be applied to type `fn(usize) -> Foo {Foo::Bar}` - --> $DIR/issue-59488.rs:30:5 + --> $DIR/function-comparison-errors-59488.rs:31:5 | LL | assert_eq!(Foo::Bar, i); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -84,7 +84,7 @@ LL | assert_eq!(Foo::Bar, i); = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug` - --> $DIR/issue-59488.rs:30:5 + --> $DIR/function-comparison-errors-59488.rs:31:5 | LL | assert_eq!(Foo::Bar, i); | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for fn item `fn(usize) -> Foo {Foo::Bar}` @@ -92,7 +92,7 @@ LL | assert_eq!(Foo::Bar, i); = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug` - --> $DIR/issue-59488.rs:30:5 + --> $DIR/function-comparison-errors-59488.rs:31:5 | LL | assert_eq!(Foo::Bar, i); | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for fn item `fn(usize) -> Foo {Foo::Bar}` diff --git a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741-1.rs b/tests/ui/box/boxed-value-matching-57741.rs index d0aae23b2fc..7e2f089dad8 100644 --- a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741-1.rs +++ b/tests/ui/box/boxed-value-matching-57741.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/57741 #![allow(warnings)] // This tests that the `help: consider dereferencing the boxed value` suggestion isn't made diff --git a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741-1.stderr b/tests/ui/box/boxed-value-matching-57741.stderr index 76f03bab6d1..33d7a6759ad 100644 --- a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741-1.stderr +++ b/tests/ui/box/boxed-value-matching-57741.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-57741-1.rs:14:9 + --> $DIR/boxed-value-matching-57741.rs:15:9 | LL | let y = match x { | - this expression has type `Box<u32>` @@ -10,7 +10,7 @@ LL | S::A { a } | S::B { b: a } => a, found enum `S` error[E0308]: mismatched types - --> $DIR/issue-57741-1.rs:14:22 + --> $DIR/boxed-value-matching-57741.rs:15:22 | LL | let y = match x { | - this expression has type `Box<u32>` diff --git a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.fixed b/tests/ui/box/dereferencing-boxed-enum-in-match-57741.fixed index 1823f0d3d4c..ee796b56272 100644 --- a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.fixed +++ b/tests/ui/box/dereferencing-boxed-enum-in-match-57741.fixed @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/57741 //@ run-rustfix #![allow(warnings)] diff --git a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.rs b/tests/ui/box/dereferencing-boxed-enum-in-match-57741.rs index 47ab91177e0..3a45a8b56ff 100644 --- a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.rs +++ b/tests/ui/box/dereferencing-boxed-enum-in-match-57741.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/57741 //@ run-rustfix #![allow(warnings)] diff --git a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.stderr b/tests/ui/box/dereferencing-boxed-enum-in-match-57741.stderr index 62d83a54614..c07387b21bd 100644 --- a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.stderr +++ b/tests/ui/box/dereferencing-boxed-enum-in-match-57741.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-57741.rs:20:9 + --> $DIR/dereferencing-boxed-enum-in-match-57741.rs:21:9 | LL | let y = match x { | - this expression has type `Box<T>` @@ -14,7 +14,7 @@ LL | let y = match *x { | + error[E0308]: mismatched types - --> $DIR/issue-57741.rs:20:19 + --> $DIR/dereferencing-boxed-enum-in-match-57741.rs:21:19 | LL | let y = match x { | - this expression has type `Box<T>` @@ -29,7 +29,7 @@ LL | let y = match *x { | + error[E0308]: mismatched types - --> $DIR/issue-57741.rs:27:9 + --> $DIR/dereferencing-boxed-enum-in-match-57741.rs:28:9 | LL | let y = match x { | - this expression has type `Box<S>` @@ -44,7 +44,7 @@ LL | let y = match *x { | + error[E0308]: mismatched types - --> $DIR/issue-57741.rs:27:22 + --> $DIR/dereferencing-boxed-enum-in-match-57741.rs:28:22 | LL | let y = match x { | - this expression has type `Box<S>` diff --git a/tests/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs b/tests/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs index afb16cf58e8..4ae77ab6439 100644 --- a/tests/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs +++ b/tests/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs @@ -2,7 +2,6 @@ //@check-pass #![warn(unused)] #![feature(rustc_attrs)] -#![feature(btree_extract_if)] use std::collections::BTreeMap; use std::panic::{catch_unwind, AssertUnwindSafe}; diff --git a/tests/ui/issues/issue-59494.rs b/tests/ui/closures/generic-typed-nested-closures-59494.rs index b4d50bd4ce7..04d7b00ff7f 100644 --- a/tests/ui/issues/issue-59494.rs +++ b/tests/ui/closures/generic-typed-nested-closures-59494.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/59494 fn t7p<A, B, C>(f: impl Fn(B) -> C, g: impl Fn(A) -> B) -> impl Fn(A) -> C { move |a: A| -> C { f(g(a)) } } diff --git a/tests/ui/issues/issue-59494.stderr b/tests/ui/closures/generic-typed-nested-closures-59494.stderr index 33d3e48c1aa..9706fea82a3 100644 --- a/tests/ui/issues/issue-59494.stderr +++ b/tests/ui/closures/generic-typed-nested-closures-59494.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-59494.rs:20:40 + --> $DIR/generic-typed-nested-closures-59494.rs:21:40 | LL | let t7 = |env| |a| |b| t7p(f, g)(((env, a), b)); | ^^^ cyclic type of infinite size diff --git a/tests/ui/issues/issue-58375-monomorphize-default-impls.rs b/tests/ui/codegen/mono-item-collector-default-impl-58375.rs index 769a1176edd..f00e79e0dc5 100644 --- a/tests/ui/issues/issue-58375-monomorphize-default-impls.rs +++ b/tests/ui/codegen/mono-item-collector-default-impl-58375.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/58375 // Make sure that the mono-item collector does not crash when trying to // instantiate a default impl for DecodeUtf16<<u8 as A>::Item> // See https://github.com/rust-lang/rust/issues/58375 diff --git a/tests/ui/issues/issue-57162.rs b/tests/ui/coherence/trait-implementation-coherence-check-57162.rs index 5e62d0eb010..a57e827ca8b 100644 --- a/tests/ui/issues/issue-57162.rs +++ b/tests/ui/coherence/trait-implementation-coherence-check-57162.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/57162 //@ check-pass trait Foo {} diff --git a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs index 478fa3706e8..9af351ec59f 100644 --- a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs +++ b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs @@ -11,7 +11,6 @@ where { fn unimplemented(self, _: &Foo) -> Self::Output { //~^ ERROR method `unimplemented` is not a member of trait `std::ops::Add` - //~| ERROR type annotations needed loop {} } } diff --git a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr index 29bbd23a469..37eb895f9a8 100644 --- a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr +++ b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr @@ -3,7 +3,6 @@ error[E0407]: method `unimplemented` is not a member of trait `std::ops::Add` | LL | / fn unimplemented(self, _: &Foo) -> Self::Output { LL | | -LL | | LL | | loop {} LL | | } | |_____^ not a member of trait `std::ops::Add` @@ -39,21 +38,7 @@ LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -error[E0284]: type annotations needed - --> $DIR/post-analysis-user-facing-param-env.rs:12:40 - | -LL | fn unimplemented(self, _: &Foo) -> Self::Output { - | ^^^^^^^^^^^^ cannot infer the value of const parameter `NUM` - | -note: required for `Foo` to implement `Add<&'a Foo>` - --> $DIR/post-analysis-user-facing-param-env.rs:6:28 - | -LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo - | ---------------- ^^^^^^^^^^^^^^^^^^^^^^ ^^^ - | | - | unsatisfied trait bound introduced here - -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted -Some errors have detailed explanations: E0046, E0207, E0284, E0407. +Some errors have detailed explanations: E0046, E0207, E0407. For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/issues/issue-57781.rs b/tests/ui/consts/oncecell-const-init-57781.rs index 7f0d2eda9bb..27426ef2549 100644 --- a/tests/ui/issues/issue-57781.rs +++ b/tests/ui/consts/oncecell-const-init-57781.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/57781 //@ run-pass use std::cell::UnsafeCell; diff --git a/tests/ui/issues/issue-58463.rs b/tests/ui/debuginfo/impl-copy-function-debuginfo-58463.rs index 6e4b909bc38..72388c36ce4 100644 --- a/tests/ui/issues/issue-58463.rs +++ b/tests/ui/debuginfo/impl-copy-function-debuginfo-58463.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/58463 //@ run-pass //@ compile-flags:-C debuginfo=2 diff --git a/tests/ui/issues/issue-58734.rs b/tests/ui/dyn-compatibility/spurious-dyn-compat-errors-58734.rs index e5b371f5530..3e9ebb497a2 100644 --- a/tests/ui/issues/issue-58734.rs +++ b/tests/ui/dyn-compatibility/spurious-dyn-compat-errors-58734.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/58734 trait Trait { fn exists(self) -> (); diff --git a/tests/ui/issues/issue-58734.stderr b/tests/ui/dyn-compatibility/spurious-dyn-compat-errors-58734.stderr index 2336a94f150..140461283f3 100644 --- a/tests/ui/issues/issue-58734.stderr +++ b/tests/ui/dyn-compatibility/spurious-dyn-compat-errors-58734.stderr @@ -1,5 +1,5 @@ warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/issue-58734.rs:20:5 + --> $DIR/spurious-dyn-compat-errors-58734.rs:21:5 | LL | Trait::nonexistent(()); | ^^^^^ @@ -13,14 +13,14 @@ LL | <dyn Trait>::nonexistent(()); | ++++ + error[E0038]: the trait `Trait` is not dyn compatible - --> $DIR/issue-58734.rs:20:5 + --> $DIR/spurious-dyn-compat-errors-58734.rs:21:5 | LL | Trait::nonexistent(()); | ^^^^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> - --> $DIR/issue-58734.rs:4:8 + --> $DIR/spurious-dyn-compat-errors-58734.rs:5:8 | LL | trait Trait { | ----- this trait is not dyn compatible... diff --git a/tests/ui/issues/issue-56237.rs b/tests/ui/generics/generic-associated-type-deref-target-56237.rs index 3c0a235f3ec..2050ca377e8 100644 --- a/tests/ui/issues/issue-56237.rs +++ b/tests/ui/generics/generic-associated-type-deref-target-56237.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/56237 //@ run-pass use std::ops::Deref; diff --git a/tests/ui/issues/issue-55731.rs b/tests/ui/higher-ranked/hrtb-associated-type-leak-check-55731.rs index 7b4f4e2cd3b..978abd9fcf5 100644 --- a/tests/ui/issues/issue-55731.rs +++ b/tests/ui/higher-ranked/hrtb-associated-type-leak-check-55731.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/55731 use std::marker::PhantomData; trait DistributedIterator { diff --git a/tests/ui/issues/issue-55731.stderr b/tests/ui/higher-ranked/hrtb-associated-type-leak-check-55731.stderr index 2c38041642d..40ac1d9d041 100644 --- a/tests/ui/issues/issue-55731.stderr +++ b/tests/ui/higher-ranked/hrtb-associated-type-leak-check-55731.stderr @@ -1,5 +1,5 @@ error: implementation of `DistributedIteratorMulti` is not general enough - --> $DIR/issue-55731.rs:48:5 + --> $DIR/hrtb-associated-type-leak-check-55731.rs:49:5 | LL | / multi(Map { LL | | i: Cloned(PhantomData), diff --git a/tests/ui/imports/auxiliary/reexported-trait-56175.rs b/tests/ui/imports/auxiliary/reexported-trait-56175.rs new file mode 100644 index 00000000000..51a991bef59 --- /dev/null +++ b/tests/ui/imports/auxiliary/reexported-trait-56175.rs @@ -0,0 +1,17 @@ +mod private { + pub trait Trait { + fn trait_method(&self) { + } + } + pub trait TraitB { + fn trait_method_b(&self) { + } + } +} + +pub struct FooStruct; +pub use crate::private::Trait; +impl crate::private::Trait for FooStruct {} + +pub use crate::private::TraitB as TraitBRename; +impl crate::private::TraitB for FooStruct {} diff --git a/tests/ui/issues/issue-56175.rs b/tests/ui/imports/private-types-suggested-without-extern-crate-56175.rs index daffe806a90..ce001edad1b 100644 --- a/tests/ui/issues/issue-56175.rs +++ b/tests/ui/imports/private-types-suggested-without-extern-crate-56175.rs @@ -1,5 +1,6 @@ +// https://github.com/rust-lang/rust/issues/56175 //@ edition:2018 -//@ aux-crate:reexported_trait=reexported-trait.rs +//@ aux-crate:reexported_trait=reexported-trait-56175.rs fn main() { reexported_trait::FooStruct.trait_method(); diff --git a/tests/ui/issues/issue-56175.stderr b/tests/ui/imports/private-types-suggested-without-extern-crate-56175.stderr index df4cd6ce8a7..1e8285c80ac 100644 --- a/tests/ui/issues/issue-56175.stderr +++ b/tests/ui/imports/private-types-suggested-without-extern-crate-56175.stderr @@ -1,10 +1,10 @@ error[E0599]: no method named `trait_method` found for struct `FooStruct` in the current scope - --> $DIR/issue-56175.rs:5:33 + --> $DIR/private-types-suggested-without-extern-crate-56175.rs:6:33 | LL | reexported_trait::FooStruct.trait_method(); | ^^^^^^^^^^^^ | - ::: $DIR/auxiliary/reexported-trait.rs:3:12 + ::: $DIR/auxiliary/reexported-trait-56175.rs:3:12 | LL | fn trait_method(&self) { | ------------ the method is available for `FooStruct` here @@ -12,7 +12,7 @@ LL | fn trait_method(&self) { = help: items from traits can only be used if the trait is in scope help: trait `Trait` which provides `trait_method` is implemented but not in scope; perhaps you want to import it | -LL + use reexported_trait::Trait; +LL + use reexported_trait_56175::Trait; | help: there is a method `trait_method_b` with a similar name | @@ -20,12 +20,12 @@ LL | reexported_trait::FooStruct.trait_method_b(); | ++ error[E0599]: no method named `trait_method_b` found for struct `FooStruct` in the current scope - --> $DIR/issue-56175.rs:7:33 + --> $DIR/private-types-suggested-without-extern-crate-56175.rs:8:33 | LL | reexported_trait::FooStruct.trait_method_b(); | ^^^^^^^^^^^^^^ | - ::: $DIR/auxiliary/reexported-trait.rs:7:12 + ::: $DIR/auxiliary/reexported-trait-56175.rs:7:12 | LL | fn trait_method_b(&self) { | -------------- the method is available for `FooStruct` here @@ -33,7 +33,7 @@ LL | fn trait_method_b(&self) { = help: items from traits can only be used if the trait is in scope help: trait `TraitB` which provides `trait_method_b` is implemented but not in scope; perhaps you want to import it | -LL + use reexported_trait::TraitBRename; +LL + use reexported_trait_56175::TraitBRename; | help: there is a method `trait_method` with a similar name | diff --git a/tests/ui/issues/auxiliary/issue-57271-lib.rs b/tests/ui/infinite/auxiliary/aux-57271-lib.rs index ff625668a9d..ff625668a9d 100644 --- a/tests/ui/issues/auxiliary/issue-57271-lib.rs +++ b/tests/ui/infinite/auxiliary/aux-57271-lib.rs diff --git a/tests/ui/issues/issue-57271.rs b/tests/ui/infinite/mutually-recursive-infinite-types-57271.rs index 20d081ecb3c..cb20770b486 100644 --- a/tests/ui/issues/issue-57271.rs +++ b/tests/ui/infinite/mutually-recursive-infinite-types-57271.rs @@ -1,8 +1,9 @@ -//@ aux-build:issue-57271-lib.rs +// https://github.com/rust-lang/rust/issues/57271 +//@ aux-build:aux-57271-lib.rs -extern crate issue_57271_lib; +extern crate aux_57271_lib; -use issue_57271_lib::BaseType; +use aux_57271_lib::BaseType; pub enum ObjectType { //~ ERROR recursive types `ObjectType` and `TypeSignature` have infinite size Class(ClassTypeSignature), diff --git a/tests/ui/issues/issue-57271.stderr b/tests/ui/infinite/mutually-recursive-infinite-types-57271.stderr index a61419c61d7..8bf1b470062 100644 --- a/tests/ui/issues/issue-57271.stderr +++ b/tests/ui/infinite/mutually-recursive-infinite-types-57271.stderr @@ -1,5 +1,5 @@ error[E0072]: recursive types `ObjectType` and `TypeSignature` have infinite size - --> $DIR/issue-57271.rs:7:1 + --> $DIR/mutually-recursive-infinite-types-57271.rs:8:1 | LL | pub enum ObjectType { | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/invalid-compile-flags/print-without-arg.stderr b/tests/ui/invalid-compile-flags/print-without-arg.stderr index 3048a59d0d0..4163d4e0602 100644 --- a/tests/ui/invalid-compile-flags/print-without-arg.stderr +++ b/tests/ui/invalid-compile-flags/print-without-arg.stderr @@ -3,5 +3,5 @@ error: Argument to option 'print' missing --print <INFO>[=<FILE>] Compiler information to print on stdout (or to a file) INFO may be one of - <all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models>. + <all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>. diff --git a/tests/ui/invalid-compile-flags/print.stderr b/tests/ui/invalid-compile-flags/print.stderr index e3374eb1e6e..e8adbfd87d7 100644 --- a/tests/ui/invalid-compile-flags/print.stderr +++ b/tests/ui/invalid-compile-flags/print.stderr @@ -1,5 +1,5 @@ error: unknown print request: `yyyy` | - = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models` + = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models` = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information diff --git a/tests/ui/issues/issue-56943.rs b/tests/ui/issues/issue-56943.rs deleted file mode 100644 index 9664567ec9e..00000000000 --- a/tests/ui/issues/issue-56943.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ aux-build:issue-56943.rs - -extern crate issue_56943; - -fn main() { - let _: issue_56943::S = issue_56943::S2; - //~^ ERROR mismatched types [E0308] -} diff --git a/tests/ui/issues/issue-57198-pass.rs b/tests/ui/keyword/raw-identifier-for-function-57198.rs index 06f30603c31..41a0cbf4619 100644 --- a/tests/ui/issues/issue-57198-pass.rs +++ b/tests/ui/keyword/raw-identifier-for-function-57198.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/57198 //@ run-pass mod m { diff --git a/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.rs b/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.rs index 92cb60bb16d..dac878c1cd9 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.rs @@ -20,4 +20,4 @@ pub fn lib_main() { unsafe { f(42); } } -//~? ERROR Dlltool could not create import library with +//~? ERROR dlltool could not create import library with diff --git a/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.stderr b/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.stderr index 90cca83d1c1..5f3c29c3a21 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.stderr @@ -1,4 +1,4 @@ -error: Dlltool could not create import library with $DLLTOOL -d $DEF_FILE -D foo.dll -l $LIB_FILE $TARGET_MACHINE $ASM_FLAGS --no-leading-underscore $TEMP_PREFIX: +error: dlltool could not create import library with $DLLTOOL -d $DEF_FILE -D foo.dll -l $LIB_FILE $TARGET_MACHINE $ASM_FLAGS --no-leading-underscore $TEMP_PREFIX: $DLLTOOL: Syntax error in def file $DEF_FILE:1โ diff --git a/tests/ui/issues/auxiliary/issue-56943.rs b/tests/ui/mismatched_types/auxiliary/aux-56943.rs index 65b9beb91f9..65b9beb91f9 100644 --- a/tests/ui/issues/auxiliary/issue-56943.rs +++ b/tests/ui/mismatched_types/auxiliary/aux-56943.rs diff --git a/tests/ui/mismatched_types/type-mismatch-in-extern-crate-56943.rs b/tests/ui/mismatched_types/type-mismatch-in-extern-crate-56943.rs new file mode 100644 index 00000000000..9970b27c847 --- /dev/null +++ b/tests/ui/mismatched_types/type-mismatch-in-extern-crate-56943.rs @@ -0,0 +1,9 @@ +// https://github.com/rust-lang/rust/issues/56943 +//@ aux-build:aux-56943.rs + +extern crate aux_56943; + +fn main() { + let _: aux_56943::S = aux_56943::S2; + //~^ ERROR mismatched types [E0308] +} diff --git a/tests/ui/issues/issue-56943.stderr b/tests/ui/mismatched_types/type-mismatch-in-extern-crate-56943.stderr index 60a2e92dc71..2315267701d 100644 --- a/tests/ui/issues/issue-56943.stderr +++ b/tests/ui/mismatched_types/type-mismatch-in-extern-crate-56943.stderr @@ -1,8 +1,8 @@ error[E0308]: mismatched types - --> $DIR/issue-56943.rs:6:29 + --> $DIR/type-mismatch-in-extern-crate-56943.rs:7:27 | -LL | let _: issue_56943::S = issue_56943::S2; - | -------------- ^^^^^^^^^^^^^^^ expected `S`, found `S2` +LL | let _: aux_56943::S = aux_56943::S2; + | ------------ ^^^^^^^^^^^^^ expected `S`, found `S2` | | | expected due to this diff --git a/tests/ui/issues/issue-56128.rs b/tests/ui/modules/pub-use-handling-in-modules-56128.rs index cc170f60250..cc170f60250 100644 --- a/tests/ui/issues/issue-56128.rs +++ b/tests/ui/modules/pub-use-handling-in-modules-56128.rs diff --git a/tests/ui/issues/issue-55587.rs b/tests/ui/parser/invalid-variable-definition-55587.rs index d9100cf555b..f2c7c0a8e6c 100644 --- a/tests/ui/issues/issue-55587.rs +++ b/tests/ui/parser/invalid-variable-definition-55587.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/55587 use std::path::Path; fn main() { diff --git a/tests/ui/issues/issue-55587.stderr b/tests/ui/parser/invalid-variable-definition-55587.stderr index 7a5d0e28100..08c951582e3 100644 --- a/tests/ui/issues/issue-55587.stderr +++ b/tests/ui/parser/invalid-variable-definition-55587.stderr @@ -1,5 +1,5 @@ error[E0164]: expected tuple struct or tuple variant, found associated function `Path::new` - --> $DIR/issue-55587.rs:4:9 + --> $DIR/invalid-variable-definition-55587.rs:5:9 | LL | let Path::new(); | ^^^^^^^^^^^ `fn` calls are not allowed in patterns diff --git a/tests/ui/print-request/print-lints-help.stderr b/tests/ui/print-request/print-lints-help.stderr index bc48b2fa73c..297a3aa79e1 100644 --- a/tests/ui/print-request/print-lints-help.stderr +++ b/tests/ui/print-request/print-lints-help.stderr @@ -1,6 +1,6 @@ error: unknown print request: `lints` | - = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models` + = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models` = help: use `-Whelp` to print a list of lints = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information diff --git a/tests/ui/issues/issue-58712.rs b/tests/ui/resolve/missing-type-in-scope-58712.rs index 930bec6889b..b9ff74e426d 100644 --- a/tests/ui/issues/issue-58712.rs +++ b/tests/ui/resolve/missing-type-in-scope-58712.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/58712 struct AddrVec<H, A> { h: H, a: A, diff --git a/tests/ui/issues/issue-58712.stderr b/tests/ui/resolve/missing-type-in-scope-58712.stderr index f4bd4d1e826..d7e06eee856 100644 --- a/tests/ui/issues/issue-58712.stderr +++ b/tests/ui/resolve/missing-type-in-scope-58712.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `DeviceId` in this scope - --> $DIR/issue-58712.rs:6:20 + --> $DIR/missing-type-in-scope-58712.rs:7:20 | LL | impl<H> AddrVec<H, DeviceId> { | ^^^^^^^^ not found in this scope @@ -10,7 +10,7 @@ LL | impl<H, DeviceId> AddrVec<H, DeviceId> { | ++++++++++ error[E0412]: cannot find type `DeviceId` in this scope - --> $DIR/issue-58712.rs:8:29 + --> $DIR/missing-type-in-scope-58712.rs:9:29 | LL | pub fn device(&self) -> DeviceId { | ^^^^^^^^ not found in this scope diff --git a/tests/ui/issues/issue-59020.rs b/tests/ui/std/park-timeout-wakeup-59020.rs index 2a34ba52b88..af530bb586c 100644 --- a/tests/ui/issues/issue-59020.rs +++ b/tests/ui/std/park-timeout-wakeup-59020.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/59020 //@ edition:2018 //@ run-pass //@ needs-threads diff --git a/tests/ui/issues/issue-56835.rs b/tests/ui/structs/invalid-self-constructor-56835.rs index 7132d15ee5f..fd8763443f0 100644 --- a/tests/ui/issues/issue-56835.rs +++ b/tests/ui/structs/invalid-self-constructor-56835.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/56835 pub struct Foo {} impl Foo { diff --git a/tests/ui/issues/issue-56835.stderr b/tests/ui/structs/invalid-self-constructor-56835.stderr index e949ae7b324..045781ec42b 100644 --- a/tests/ui/issues/issue-56835.stderr +++ b/tests/ui/structs/invalid-self-constructor-56835.stderr @@ -1,11 +1,11 @@ error: the `Self` constructor can only be used with tuple or unit structs - --> $DIR/issue-56835.rs:4:12 + --> $DIR/invalid-self-constructor-56835.rs:5:12 | LL | fn bar(Self(foo): Self) {} | ^^^^^^^^^ help: use curly brackets: `Self { /* fields */ }` error[E0164]: expected tuple struct or tuple variant, found self constructor `Self` - --> $DIR/issue-56835.rs:4:12 + --> $DIR/invalid-self-constructor-56835.rs:5:12 | LL | fn bar(Self(foo): Self) {} | ^^^^^^^^^ not a tuple struct or tuple variant diff --git a/tests/ui/issues/issue-59756.fixed b/tests/ui/suggestions/incompatible-types-in-try-expression-59756.fixed index 954ba917626..954ba917626 100644 --- a/tests/ui/issues/issue-59756.fixed +++ b/tests/ui/suggestions/incompatible-types-in-try-expression-59756.fixed diff --git a/tests/ui/issues/issue-59756.rs b/tests/ui/suggestions/incompatible-types-in-try-expression-59756.rs index de349f43f46..570aa7d373b 100644 --- a/tests/ui/issues/issue-59756.rs +++ b/tests/ui/suggestions/incompatible-types-in-try-expression-59756.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/59756 //@ run-rustfix //@ ignore-test (rustfix needs multiple suggestions) // diff --git a/tests/ui/issues/issue-59756.stderr b/tests/ui/suggestions/incompatible-types-in-try-expression-59756.stderr index 27c07fecd5b..7182109b5a0 100644 --- a/tests/ui/issues/issue-59756.stderr +++ b/tests/ui/suggestions/incompatible-types-in-try-expression-59756.stderr @@ -1,5 +1,5 @@ error[E0308]: try expression alternatives have incompatible types - --> $DIR/issue-59756.rs:13:5 + --> $DIR/incompatible-types-in-try-expression-59756.rs:13:5 | LL | foo()? | ^^^^^^ expected enum `std::result::Result`, found struct `A` diff --git a/tests/ui/suggestions/missing-format-specifiers-issue-68293.rs b/tests/ui/suggestions/missing-format-specifiers-issue-68293.rs index 29799624d78..fbede7c41cb 100644 --- a/tests/ui/suggestions/missing-format-specifiers-issue-68293.rs +++ b/tests/ui/suggestions/missing-format-specifiers-issue-68293.rs @@ -32,4 +32,33 @@ fn missing_format_specifiers_multiple_unused_args() { //~| NOTE consider adding 2 format specifiers } +fn unicode_unused_args() { + panic!("๐", "๐", 1); + //~^ ERROR multiple unused formatting arguments + //~| NOTE multiple missing formatting specifiers + //~| NOTE argument never used + //~| NOTE argument never used + //~| HELP format specifiers use curly braces, consider adding 2 format specifiers +} + +fn raw_str_unused_arg() { + format_args!(r##"lJ๐ฟร๏ฟฝ.๐ฟ๏ฟฝ"##, r#"r}J๐ฟร" {}"#, 1); + //~^ ERROR multiple unused formatting arguments + //~| NOTE multiple missing formatting specifiers + //~| NOTE argument never used + //~| NOTE argument never used + //~| HELP format specifiers use curly braces, consider adding 2 format specifiers +} + +fn valid_new_lines_unused_args() { + panic!("Expect 2 newlines + +", "๐", 1); + //~^ ERROR multiple unused formatting arguments + //~| NOTE argument never used + //~| NOTE argument never used + //~^^^^^^ NOTE multiple missing formatting specifiers + //~| HELP format specifiers use curly braces, consider adding 2 format specifiers +} + fn main() { } diff --git a/tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr b/tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr index 081409789f5..7e997241698 100644 --- a/tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr +++ b/tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr @@ -45,5 +45,52 @@ LL | println!("list: {}", 1, 2, 3); | = note: consider adding 2 format specifiers -error: aborting due to 4 previous errors +error: multiple unused formatting arguments + --> $DIR/missing-format-specifiers-issue-68293.rs:36:17 + | +LL | panic!("๐", "๐", 1); + | ---- ^^^^ ^ argument never used + | | | + | | argument never used + | multiple missing formatting specifiers + | +help: format specifiers use curly braces, consider adding 2 format specifiers + | +LL | panic!("๐{}{}", "๐", 1); + | ++++ + +error: multiple unused formatting arguments + --> $DIR/missing-format-specifiers-issue-68293.rs:45:35 + | +LL | format_args!(r##"lJ๐ฟร๏ฟฝ.๐ฟ๏ฟฝ"##, r#"r}J๐ฟร" {}"#, 1); + | --------------- ^^^^^^^^^^^^^^ ^ argument never used + | | | + | | argument never used + | multiple missing formatting specifiers + | +help: format specifiers use curly braces, consider adding 2 format specifiers + | +LL | format_args!(r##"lJ๐ฟร๏ฟฝ.๐ฟ๏ฟฝ{}{}"##, r#"r}J๐ฟร" {}"#, 1); + | ++++ + +error: multiple unused formatting arguments + --> $DIR/missing-format-specifiers-issue-68293.rs:56:4 + | +LL | panic!("Expect 2 newlines + | ____________- +LL | | +LL | | ", "๐", 1); + | | - ^^^^ ^ argument never used + | | | | + | |_| argument never used + | multiple missing formatting specifiers + | +help: format specifiers use curly braces, consider adding 2 format specifiers + | +LL | panic!("Expect 2 newlines +LL | +LL ~ {}{}", "๐", 1); + | + +error: aborting due to 7 previous errors diff --git a/tests/ui/issues/issue-58857.rs b/tests/ui/trait-bounds/negative-bound-not-supported-58857.rs index 4350d7e5b40..0a0b70a216b 100644 --- a/tests/ui/issues/issue-58857.rs +++ b/tests/ui/trait-bounds/negative-bound-not-supported-58857.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/58857 struct Conj<A> {a : A} trait Valid {} diff --git a/tests/ui/issues/issue-58857.stderr b/tests/ui/trait-bounds/negative-bound-not-supported-58857.stderr index ac70bc725e2..05347a891b4 100644 --- a/tests/ui/issues/issue-58857.stderr +++ b/tests/ui/trait-bounds/negative-bound-not-supported-58857.stderr @@ -1,5 +1,5 @@ error: negative bounds are not supported - --> $DIR/issue-58857.rs:4:9 + --> $DIR/negative-bound-not-supported-58857.rs:5:9 | LL | impl<A: !Valid> Conj<A>{} | ^ diff --git a/tests/ui/issues/issue-58212.rs b/tests/ui/traits/generic-trait-impl-aliased-array-58212.rs index f266db603bf..a71194ba806 100644 --- a/tests/ui/issues/issue-58212.rs +++ b/tests/ui/traits/generic-trait-impl-aliased-array-58212.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/58212 //@ check-pass trait FromUnchecked { diff --git a/tests/ui/issues/issue-57156.rs b/tests/ui/traits/trait-object-lifetime-bounds-57156.rs index 12251509abd..8f5bef7fe13 100644 --- a/tests/ui/issues/issue-57156.rs +++ b/tests/ui/traits/trait-object-lifetime-bounds-57156.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/57156 //@ check-pass trait Foo<Args> { diff --git a/tests/ui/issues/issue-56229.rs b/tests/ui/traits/trait-objects-with-supertraits-56229.rs index 1c6dd72ed2d..27cae968a6a 100644 --- a/tests/ui/issues/issue-56229.rs +++ b/tests/ui/traits/trait-objects-with-supertraits-56229.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/56229 //@ check-pass trait Mirror { diff --git a/tests/ui/issues/issue-57924.rs b/tests/ui/typeck/self-constructor-type-args-not-allowed-57924.rs index 8846912a8ff..2b3b11c3f38 100644 --- a/tests/ui/issues/issue-57924.rs +++ b/tests/ui/typeck/self-constructor-type-args-not-allowed-57924.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/57924 pub struct Gcm<E>(E); impl<E> Gcm<E> { diff --git a/tests/ui/issues/issue-57924.stderr b/tests/ui/typeck/self-constructor-type-args-not-allowed-57924.stderr index 40435fd0f0a..b5be5b39eb8 100644 --- a/tests/ui/issues/issue-57924.stderr +++ b/tests/ui/typeck/self-constructor-type-args-not-allowed-57924.stderr @@ -1,5 +1,5 @@ error[E0109]: type arguments are not allowed on self constructor - --> $DIR/issue-57924.rs:5:16 + --> $DIR/self-constructor-type-args-not-allowed-57924.rs:6:16 | LL | Self::<E>(e) | ---- ^ type argument not allowed diff --git a/tests/ui/issues/issue-56199.rs b/tests/ui/typeck/self-constructor-type-error-56199.rs index ba11582a9d5..b08d6918980 100644 --- a/tests/ui/issues/issue-56199.rs +++ b/tests/ui/typeck/self-constructor-type-error-56199.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/56199 enum Foo {} struct Bar {} diff --git a/tests/ui/issues/issue-56199.stderr b/tests/ui/typeck/self-constructor-type-error-56199.stderr index eb6d7005979..6e9d0fcd90c 100644 --- a/tests/ui/issues/issue-56199.stderr +++ b/tests/ui/typeck/self-constructor-type-error-56199.stderr @@ -1,5 +1,5 @@ error: the `Self` constructor can only be used with tuple or unit structs - --> $DIR/issue-56199.rs:6:17 + --> $DIR/self-constructor-type-error-56199.rs:7:17 | LL | let _ = Self; | ^^^^ @@ -7,7 +7,7 @@ LL | let _ = Self; = help: did you mean to use one of the enum's variants? error: the `Self` constructor can only be used with tuple or unit structs - --> $DIR/issue-56199.rs:8:17 + --> $DIR/self-constructor-type-error-56199.rs:9:17 | LL | let _ = Self(); | ^^^^^^ @@ -15,13 +15,13 @@ LL | let _ = Self(); = help: did you mean to use one of the enum's variants? error: the `Self` constructor can only be used with tuple or unit structs - --> $DIR/issue-56199.rs:15:17 + --> $DIR/self-constructor-type-error-56199.rs:16:17 | LL | let _ = Self; | ^^^^ help: use curly brackets: `Self { /* fields */ }` error: the `Self` constructor can only be used with tuple or unit structs - --> $DIR/issue-56199.rs:17:17 + --> $DIR/self-constructor-type-error-56199.rs:18:17 | LL | let _ = Self(); | ^^^^^^ help: use curly brackets: `Self { /* fields */ }` |
