Auto merge of #155141 - jhpratt:rollup-pjDewx9, r=jhpratt

Rollup of 3 pull requests

Successful merges:

 - rust-lang/rust#154661 (Semantic checks of `impl` restrictions)
 - rust-lang/rust#155132 (Suggest similar target names on unrecognized `--target`)
 - rust-lang/rust#155136 (Tweak comment about intrinsics in cross-crate-inlinable)
This commit is contained in:
bors
2026-04-11 05:49:32 +00:00
35 changed files with 513 additions and 59 deletions
+46 -5
View File
@@ -24,8 +24,8 @@
use super::errors::{InvalidAbi, InvalidAbiSuggestion, TupleStructWithDefault, UnionWithDefault};
use super::stability::{enabled_names, gate_unstable_abi};
use super::{
AstOwner, FnDeclKind, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode,
RelaxedBoundForbiddenReason, RelaxedBoundPolicy, ResolverAstLoweringExt,
AstOwner, FnDeclKind, GenericArgsMode, ImplTraitContext, ImplTraitPosition, LoweringContext,
ParamMode, RelaxedBoundForbiddenReason, RelaxedBoundPolicy, ResolverAstLoweringExt,
};
/// Wraps either IndexVec (during `hir_crate`), which acts like a primary
@@ -540,14 +540,14 @@ fn lower_item_kind(
constness,
is_auto,
safety,
// FIXME(impl_restrictions): lower to HIR
impl_restriction: _,
impl_restriction,
ident,
generics,
bounds,
items,
}) => {
let constness = self.lower_constness(*constness);
let impl_restriction = self.lower_impl_restriction(impl_restriction);
let ident = self.lower_ident(*ident);
let (generics, (safety, items, bounds)) = self.lower_generics(
generics,
@@ -566,7 +566,16 @@ fn lower_item_kind(
(safety, items, bounds)
},
);
hir::ItemKind::Trait(constness, *is_auto, safety, ident, generics, bounds, items)
hir::ItemKind::Trait(
constness,
*is_auto,
safety,
impl_restriction,
ident,
generics,
bounds,
items,
)
}
ItemKind::TraitAlias(box TraitAlias { constness, ident, generics, bounds }) => {
let constness = self.lower_constness(*constness);
@@ -1831,6 +1840,38 @@ pub(super) fn lower_safety(&self, s: Safety, default: hir::Safety) -> hir::Safet
}
}
pub(super) fn lower_impl_restriction(
&mut self,
r: &ImplRestriction,
) -> &'hir hir::ImplRestriction<'hir> {
let kind = match &r.kind {
RestrictionKind::Unrestricted => hir::RestrictionKind::Unrestricted,
RestrictionKind::Restricted { path, id, shorthand: _ } => {
let res = self.resolver.get_partial_res(*id);
if let Some(did) = res.and_then(|res| res.expect_full_res().opt_def_id()) {
hir::RestrictionKind::Restricted(self.arena.alloc(hir::Path {
res: did,
segments: self.arena.alloc_from_iter(path.segments.iter().map(|segment| {
self.lower_path_segment(
path.span,
segment,
ParamMode::Explicit,
GenericArgsMode::Err,
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
)
})),
span: self.lower_span(path.span),
}))
} else {
self.dcx().span_delayed_bug(path.span, "should have errored in resolve");
hir::RestrictionKind::Unrestricted
}
}
};
self.arena.alloc(hir::ImplRestriction { kind, span: self.lower_span(r.span) })
}
/// Return the pair of the lowered `generics` as `hir::Generics` and the evaluation of `f` with
/// the carried impl trait definitions and bounds.
#[instrument(level = "debug", skip(self, f))]
+20 -4
View File
@@ -4341,13 +4341,14 @@ pub fn is_struct_or_union(&self) -> bool {
Constness,
IsAuto,
Safety,
&'hir ImplRestriction<'hir>,
Ident,
&'hir Generics<'hir>,
GenericBounds<'hir>,
&'hir [TraitItemId]
),
ItemKind::Trait(constness, is_auto, safety, ident, generics, bounds, items),
(*constness, *is_auto, *safety, *ident, generics, bounds, items);
ItemKind::Trait(constness, is_auto, safety, impl_restriction, ident, generics, bounds, items),
(*constness, *is_auto, *safety, impl_restriction, *ident, generics, bounds, items);
expect_trait_alias, (Constness, Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
ItemKind::TraitAlias(constness, ident, generics, bounds), (*constness, *ident, generics, bounds);
@@ -4416,6 +4417,20 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct ImplRestriction<'hir> {
pub kind: RestrictionKind<'hir>,
pub span: Span,
}
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum RestrictionKind<'hir> {
/// The restriction does not affect the item.
Unrestricted,
/// The restriction only applies outside of this path.
Restricted(&'hir Path<'hir, DefId>),
}
/// The actual safety specified in syntax. We may treat
/// its safety different within the type system to create a
/// "sound by default" system that needs checking this enum
@@ -4528,6 +4543,7 @@ pub enum ItemKind<'hir> {
Constness,
IsAuto,
Safety,
&'hir ImplRestriction<'hir>,
Ident,
&'hir Generics<'hir>,
GenericBounds<'hir>,
@@ -4578,7 +4594,7 @@ pub fn ident(&self) -> Option<Ident> {
| ItemKind::Enum(ident, ..)
| ItemKind::Struct(ident, ..)
| ItemKind::Union(ident, ..)
| ItemKind::Trait(_, _, _, ident, ..)
| ItemKind::Trait(_, _, _, _, ident, ..)
| ItemKind::TraitAlias(_, ident, ..) => Some(ident),
ItemKind::Use(_, UseKind::Glob | UseKind::ListStem)
@@ -4596,7 +4612,7 @@ pub fn generics(&self) -> Option<&Generics<'_>> {
| ItemKind::Enum(_, generics, _)
| ItemKind::Struct(_, generics, _)
| ItemKind::Union(_, generics, _)
| ItemKind::Trait(_, _, _, _, generics, _, _)
| ItemKind::Trait(_, _, _, _, _, generics, _, _)
| ItemKind::TraitAlias(_, _, generics, _)
| ItemKind::Impl(Impl { generics, .. }) => generics,
_ => return None,
+4
View File
@@ -632,11 +632,15 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
_constness,
_is_auto,
_safety,
ref impl_restriction,
ident,
ref generics,
bounds,
trait_item_refs,
) => {
if let RestrictionKind::Restricted(path) = &impl_restriction.kind {
walk_list!(visitor, visit_path_segment, path.segments);
}
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds);
@@ -100,6 +100,14 @@ fn enforce_trait_manually_implementable(
return Err(tcx.dcx().emit_err(errors::SpecializationTrait { span: impl_header_span }));
}
}
if !trait_def.impl_restriction.is_allowed_in(impl_def_id.to_def_id(), tcx) {
return Err(tcx.dcx().emit_err(errors::ImplOfRestrictedTrait {
impl_span: impl_header_span,
restriction_span: trait_def.impl_restriction.expect_span(),
restriction_path: trait_def.impl_restriction.restriction_path(tcx),
}));
}
Ok(())
}
+20 -5
View File
@@ -893,11 +893,25 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
let item = tcx.hir_expect_item(def_id);
let (constness, is_alias, is_auto, safety) = match item.kind {
hir::ItemKind::Trait(constness, is_auto, safety, ..) => {
(constness, false, is_auto == hir::IsAuto::Yes, safety)
}
hir::ItemKind::TraitAlias(constness, ..) => (constness, true, false, hir::Safety::Safe),
let (constness, is_alias, is_auto, safety, impl_restriction) = match item.kind {
hir::ItemKind::Trait(constness, is_auto, safety, impl_restriction, ..) => (
constness,
false,
is_auto == hir::IsAuto::Yes,
safety,
if let hir::RestrictionKind::Restricted(path) = impl_restriction.kind {
ty::trait_def::ImplRestrictionKind::Restricted(path.res, impl_restriction.span)
} else {
ty::trait_def::ImplRestrictionKind::Unrestricted
},
),
hir::ItemKind::TraitAlias(constness, ..) => (
constness,
true,
false,
hir::Safety::Safe,
ty::trait_def::ImplRestrictionKind::Unrestricted,
),
_ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
};
@@ -946,6 +960,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
def_id: def_id.to_def_id(),
safety,
constness,
impl_restriction,
paren_sugar,
has_auto_impl: is_auto,
is_marker,
@@ -165,7 +165,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
Some(ty::Binder::dummy(tcx.impl_trait_ref(def_id).instantiate_identity()));
}
}
ItemKind::Trait(_, _, _, _, _, self_bounds, ..)
ItemKind::Trait(_, _, _, _, _, _, self_bounds, ..)
| ItemKind::TraitAlias(_, _, _, self_bounds) => {
is_trait = Some((self_bounds, item.span));
}
@@ -1038,7 +1038,7 @@ pub(super) fn const_conditions<'tcx>(
Node::Item(item) => match item.kind {
hir::ItemKind::Impl(impl_) => (impl_.generics, None, false),
hir::ItemKind::Fn { generics, .. } => (generics, None, false),
hir::ItemKind::Trait(_, _, _, _, generics, supertraits, _) => {
hir::ItemKind::Trait(_, _, _, _, _, generics, supertraits, _) => {
(generics, Some((Some(item.owner_id.def_id), supertraits)), false)
}
hir::ItemKind::TraitAlias(_, _, generics, supertraits) => {
@@ -645,7 +645,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
| hir::ItemKind::Enum(_, generics, _)
| hir::ItemKind::Struct(_, generics, _)
| hir::ItemKind::Union(_, generics, _)
| hir::ItemKind::Trait(_, _, _, _, generics, ..)
| hir::ItemKind::Trait(_, _, _, _, _, generics, ..)
| hir::ItemKind::TraitAlias(_, _, generics, ..)
| hir::ItemKind::Impl(hir::Impl { generics, .. }) => {
// These kinds of items have only early-bound lifetime parameters.
+10
View File
@@ -1035,6 +1035,16 @@ pub(crate) struct SpecializationTrait {
pub span: Span,
}
#[derive(Diagnostic)]
#[diag("trait cannot be implemented outside `{$restriction_path}`")]
pub(crate) struct ImplOfRestrictedTrait {
#[primary_span]
pub impl_span: Span,
#[note("trait restricted here")]
pub restriction_span: Span,
pub restriction_path: String,
}
#[derive(Diagnostic)]
#[diag("implicit types in closure signatures are forbidden when `for<...>` is present")]
pub(crate) struct ClosureImplicitHrtb {
+14
View File
@@ -761,6 +761,7 @@ fn print_item(&mut self, item: &hir::Item<'_>) {
constness,
is_auto,
safety,
impl_restriction,
ident,
generics,
bounds,
@@ -770,6 +771,7 @@ fn print_item(&mut self, item: &hir::Item<'_>) {
self.print_constness(constness);
self.print_is_auto(is_auto);
self.print_safety(safety);
self.print_impl_restriction(impl_restriction);
self.word_nbsp("trait");
self.print_ident(ident);
self.print_generic_params(generics.params);
@@ -2645,6 +2647,18 @@ fn print_is_auto(&mut self, s: hir::IsAuto) {
hir::IsAuto::No => {}
}
}
fn print_impl_restriction(&mut self, r: &hir::ImplRestriction<'_>) {
match r.kind {
hir::RestrictionKind::Unrestricted => {}
hir::RestrictionKind::Restricted(path) => {
self.word("impl(");
self.word_nbsp("in");
self.print_path(path, false);
self.word(")");
}
}
}
}
/// Does this expression require a semicolon to be treated
@@ -1898,7 +1898,7 @@ fn handle_unsatisfied_predicates(
Some(
Node::Item(hir::Item {
kind:
hir::ItemKind::Trait(_, _, _, ident, ..)
hir::ItemKind::Trait(_, _, _, _, ident, ..)
| hir::ItemKind::TraitAlias(_, ident, ..),
..
})
@@ -4545,7 +4545,7 @@ enum Introducer {
return;
}
Node::Item(hir::Item {
kind: hir::ItemKind::Trait(_, _, _, ident, _, bounds, _),
kind: hir::ItemKind::Trait(_, _, _, _, ident, _, bounds, _),
..
}) => {
let (sp, sep, article) = if bounds.is_empty() {
@@ -39,7 +39,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
let def_id = item.owner_id.to_def_id();
// NOTE(nbdd0121): use `dyn_compatibility_violations` instead of `is_dyn_compatible` because
// the latter will report `where_clause_object_safety` lint.
if let hir::ItemKind::Trait(_, _, _, ident, ..) = item.kind
if let hir::ItemKind::Trait(_, _, _, _, ident, ..) = item.kind
&& cx.tcx.is_dyn_compatible(def_id)
{
let direct_super_traits_iter = cx
+1 -1
View File
@@ -946,7 +946,7 @@ fn named_span(item_span: Span, ident: Ident, generics: Option<&Generics<'_>>) ->
}) => until_within(*outer_span, ty.span),
// With generics and bounds.
Node::Item(Item {
kind: ItemKind::Trait(_, _, _, _, generics, bounds, _),
kind: ItemKind::Trait(_, _, _, _, _, generics, bounds, _),
span: outer_span,
..
})
+50
View File
@@ -12,6 +12,7 @@
use crate::query::LocalCrate;
use crate::traits::specialization_graph;
use crate::ty::fast_reject::{self, SimplifiedType, TreatParams};
use crate::ty::print::{with_crate_prefix, with_no_trimmed_paths};
use crate::ty::{Ident, Ty, TyCtxt};
/// A trait's definition with type information.
@@ -24,6 +25,9 @@ pub struct TraitDef {
/// Whether this trait is `const`.
pub constness: hir::Constness,
/// Restrictions on trait implementations.
pub impl_restriction: ImplRestrictionKind,
/// If `true`, then this trait had the `#[rustc_paren_sugar]`
/// attribute, indicating that it should be used with `Foo()`
/// sugar. This is a temporary thing -- eventually any trait will
@@ -97,6 +101,52 @@ pub enum TraitSpecializationKind {
AlwaysApplicable,
}
/// Whether the trait implementation is unrestricted or restricted within a specific module.
#[derive(HashStable, PartialEq, Clone, Copy, Encodable, Decodable)]
pub enum ImplRestrictionKind {
/// The restriction does not affect this trait, and it can be implemented anywhere.
Unrestricted,
/// This trait can only be implemented within the specified module.
Restricted(DefId, Span),
}
impl ImplRestrictionKind {
/// Returns `true` if the behavior is allowed/unrestricted in the given module.
/// A value of `false` indicates that the behavior is prohibited.
pub fn is_allowed_in(self, module: DefId, tcx: TyCtxt<'_>) -> bool {
match self {
ImplRestrictionKind::Unrestricted => true,
ImplRestrictionKind::Restricted(restricted_to, _) => {
tcx.is_descendant_of(module, restricted_to)
}
}
}
/// Obtain the [`Span`] of the restriction. Panics if the restriction is unrestricted.
pub fn expect_span(self) -> Span {
match self {
ImplRestrictionKind::Unrestricted => {
bug!("called `expect_span` on an unrestricted item")
}
ImplRestrictionKind::Restricted(_, span) => span,
}
}
/// Obtain the path of the restriction. If unrestricted, an empty string is returned.
pub fn restriction_path(self, tcx: TyCtxt<'_>) -> String {
match self {
ImplRestrictionKind::Unrestricted => String::new(),
ImplRestrictionKind::Restricted(restricted_to, _) => {
if restricted_to.krate == rustc_hir::def_id::LOCAL_CRATE {
with_crate_prefix!(with_no_trimmed_paths!(tcx.def_path_str(restricted_to)))
} else {
tcx.def_path_str(restricted_to.krate.as_mod_def_id())
}
}
}
}
}
#[derive(Default, Debug, HashStable)]
pub struct TraitImpls {
blanket_impls: Vec<DefId>,
@@ -146,8 +146,9 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, _: Location) {
TerminatorKind::Call { func, unwind, .. } => {
// We track calls because they make our function not a leaf (and in theory, the
// number of calls indicates how likely this function is to perturb other CGUs).
// But intrinsics don't have a body that gets assigned to a CGU, so they are
// ignored.
// But there are a handful of intrinsics such as raw_eq that should not block
// cross-crate-inlining. Adding a broad exception for all intrinsics benchmarks well
// and seems more sustainable than an ever-growing list of intrinsics to ignore.
if let Some((fn_def_id, _)) = func.const_fn_def()
&& find_attr!(tcx, fn_def_id, RustcIntrinsic)
{
+2 -2
View File
@@ -616,7 +616,7 @@ fn check_diagnostic_on_unimplemented(
if let Some(directive) = directive {
if let Node::Item(Item {
kind: ItemKind::Trait(_, _, _, trait_name, generics, _, _),
kind: ItemKind::Trait(_, _, _, _, trait_name, generics, _, _),
..
}) = self.tcx.hir_node(hir_id)
{
@@ -1069,7 +1069,7 @@ fn check_doc_search_unbox(&self, span: Span, hir_id: HirId) {
match item.kind {
ItemKind::Enum(_, generics, _) | ItemKind::Struct(_, generics, _)
if generics.params.len() != 0 => {}
ItemKind::Trait(_, _, _, _, generics, _, items)
ItemKind::Trait(_, _, _, _, _, generics, _, items)
if generics.params.len() != 0
|| items.iter().any(|item| {
matches!(self.tcx.def_kind(item.owner_id), DefKind::AssocTy)
+13
View File
@@ -1615,6 +1615,19 @@ pub fn build_target_config(
let mut err =
early_dcx.early_struct_fatal(format!("error loading target specification: {e}"));
err.help("run `rustc --print target-list` for a list of built-in targets");
let typed = target.tuple();
let limit = typed.len() / 3 + 1;
if let Some(suggestion) = rustc_target::spec::TARGETS
.iter()
.filter_map(|&t| {
rustc_span::edit_distance::edit_distance_with_substrings(typed, t, limit)
.map(|d| (d, t))
})
.min_by_key(|(d, _)| *d)
.map(|(_, t)| t)
{
err.help(format!("did you mean `{suggestion}`?"));
}
err.emit()
}
}
@@ -577,7 +577,7 @@ pub fn report_dyn_incompatibility<'tcx>(
let trait_str = tcx.def_path_str(trait_def_id);
let trait_span = tcx.hir_get_if_local(trait_def_id).and_then(|node| match node {
hir::Node::Item(item) => match item.kind {
hir::ItemKind::Trait(_, _, _, ident, ..)
hir::ItemKind::Trait(_, _, _, _, ident, ..)
| hir::ItemKind::TraitAlias(_, ident, _, _) => Some(ident.span),
_ => unreachable!(),
},
@@ -484,7 +484,7 @@ pub fn suggest_restricting_param_bound(
let node = self.tcx.hir_node_by_def_id(body_id);
match node {
hir::Node::Item(hir::Item {
kind: hir::ItemKind::Trait(_, _, _, ident, generics, bounds, _),
kind: hir::ItemKind::Trait(_, _, _, _, ident, generics, bounds, _),
..
}) if self_ty == self.tcx.types.self_param => {
assert!(param_ty);
@@ -547,7 +547,7 @@ pub fn suggest_restricting_param_bound(
}
hir::Node::Item(hir::Item {
kind:
hir::ItemKind::Trait(_, _, _, _, generics, ..)
hir::ItemKind::Trait(_, _, _, _, _, generics, ..)
| hir::ItemKind::Impl(hir::Impl { generics, .. }),
..
}) if projection.is_some() => {
@@ -571,7 +571,7 @@ pub fn suggest_restricting_param_bound(
hir::ItemKind::Struct(_, generics, _)
| hir::ItemKind::Enum(_, generics, _)
| hir::ItemKind::Union(_, generics, _)
| hir::ItemKind::Trait(_, _, _, _, generics, ..)
| hir::ItemKind::Trait(_, _, _, _, _, generics, ..)
| hir::ItemKind::Impl(hir::Impl { generics, .. })
| hir::ItemKind::Fn { generics, .. }
| hir::ItemKind::TyAlias(_, generics, _)
@@ -651,7 +651,7 @@ pub fn suggest_restricting_param_bound(
hir::ItemKind::Struct(_, generics, _)
| hir::ItemKind::Enum(_, generics, _)
| hir::ItemKind::Union(_, generics, _)
| hir::ItemKind::Trait(_, _, _, _, generics, ..)
| hir::ItemKind::Trait(_, _, _, _, _, generics, ..)
| hir::ItemKind::Impl(hir::Impl { generics, .. })
| hir::ItemKind::Fn { generics, .. }
| hir::ItemKind::TyAlias(_, generics, _)
@@ -3831,7 +3831,7 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
let mut is_auto_trait = false;
match tcx.hir_get_if_local(data.impl_or_alias_def_id) {
Some(Node::Item(hir::Item {
kind: hir::ItemKind::Trait(_, is_auto, _, ident, ..),
kind: hir::ItemKind::Trait(_, is_auto, _, _, ident, _, _, _),
..
})) => {
// FIXME: we should do something else so that it works even on crate foreign
+1 -1
View File
@@ -609,7 +609,7 @@ fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
match self.tcx.parent_hir_node(self.tcx.local_def_id_to_hir_id(anon_reg.scope))
{
hir::Node::Item(hir::Item {
kind: hir::ItemKind::Trait(_, _, _, _, generics, ..),
kind: hir::ItemKind::Trait(_, _, _, _, _, generics, ..),
..
})
| hir::Node::Item(hir::Item {
+2 -1
View File
@@ -2914,7 +2914,8 @@ fn get_name(tcx: TyCtxt<'_>, item: &hir::Item<'_>, renamed: Option<Symbol>) -> O
ItemKind::Fn { ref sig, generics, body: body_id, .. } => {
clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
}
ItemKind::Trait(_, _, _, _, generics, bounds, item_ids) => {
// FIXME: rustdoc will need to handle `impl` restrictions at some point
ItemKind::Trait(_, _, _, _impl_restriction, _, generics, bounds, item_ids) => {
let items = item_ids
.iter()
.map(|&ti| clean_trait_item(cx.tcx.hir_trait_item(ti), cx))
@@ -306,7 +306,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
cur_f = Some(field);
}
},
ItemKind::Trait(_constness, is_auto, _safety, _ident, _generics, _generic_bounds, item_ref)
ItemKind::Trait(_constness, is_auto, _safety, _impl_restriction, _ident, _generics, _generic_bounds, item_ref)
if self.enable_ordering_for_trait && *is_auto == IsAuto::No =>
{
let mut cur_t: Option<(TraitItemId, Ident)> = None;
@@ -528,7 +528,7 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
| ItemKind::Fn { ident, .. }
| ItemKind::Macro(ident, ..)
| ItemKind::Static(_, ident, ..)
| ItemKind::Trait(_, _, _, ident, ..)
| ItemKind::Trait(_, _, _, _, ident, ..)
| ItemKind::TraitAlias(_, ident, ..)
| ItemKind::TyAlias(ident, ..)
| ItemKind::Union(ident, ..)
@@ -44,7 +44,7 @@
impl<'tcx> LateLintPass<'tcx> for LenWithoutIsEmpty {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
if let ItemKind::Trait(_, _, _, ident, _, _, trait_items) = item.kind
if let ItemKind::Trait(_, _, _, _, ident, _, _, trait_items) = item.kind
&& !item.span.from_expansion()
{
check_trait_items(cx, item, ident, trait_items);
@@ -159,7 +159,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
| ItemKind::Macro(ident, ..)
| ItemKind::Static(_, ident, ..)
| ItemKind::Struct(ident, ..)
| ItemKind::Trait(_, _, _, ident, ..)
| ItemKind::Trait(_, _, _, _, ident, ..)
| ItemKind::TraitAlias(_, ident, ..)
| ItemKind::TyAlias(ident, ..)
| ItemKind::Union(ident, ..) => ident.span,
@@ -115,7 +115,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
// special handling for self trait bounds as these are not considered generics
// i.e. trait Foo: Display {}
if let Item {
kind: ItemKind::Trait(_, _, _, _, _, bounds, ..),
kind: ItemKind::Trait(_, _, _, _, _, _, bounds, ..),
..
} = item
{
@@ -136,7 +136,7 @@ fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'tc
..
}) = segments.first()
&& let Some(Node::Item(Item {
kind: ItemKind::Trait(_, _, _, _, _, self_bounds, _),
kind: ItemKind::Trait(_, _, _, _, _, _, self_bounds, _),
..
})) = cx.tcx.hir_get_if_local(*def_id)
{
@@ -131,7 +131,7 @@ fn check_item(&mut self, cx: &LateContext<'_>, it: &Item<'_>) {
return;
}
match it.kind {
ItemKind::TyAlias(ident, ..) | ItemKind::Struct(ident, ..) | ItemKind::Trait(_, _, _, ident, ..) => {
ItemKind::TyAlias(ident, ..) | ItemKind::Struct(ident, ..) | ItemKind::Trait(_, _, _, _, ident, ..) => {
check_ident(cx, &ident, it.hir_id(), self.upper_case_acronyms_aggressive);
},
ItemKind::Enum(ident, _, ref enumdef) => {
@@ -0,0 +1,11 @@
// Checks that an unknown --target also suggests a similar known target.
// See https://github.com/rust-lang/rust/issues/155085
// ignore-tidy-target-specific-tests
//@ compile-flags: --target x86_64-linux-gnu
fn main() {}
//~? ERROR error loading target specification: could not find specification for target "x86_64-linux-gnu"
//~? HELP run `rustc --print target-list` for a list of built-in targets
//~? HELP did you mean `x86_64-unknown-linux-gnu`
@@ -0,0 +1,5 @@
error: error loading target specification: could not find specification for target "x86_64-linux-gnu"
|
= help: run `rustc --print target-list` for a list of built-in targets
= help: did you mean `x86_64-unknown-linux-gnu`?
+1
View File
@@ -1,4 +1,5 @@
error: error loading target specification: could not find specification for target "x86_64_unknown-linux-musl"
|
= help: run `rustc --print target-list` for a list of built-in targets
= help: did you mean `x86_64-unknown-linux-musl`?
@@ -0,0 +1,8 @@
#![feature(impl_restriction)]
#![expect(incomplete_features)]
pub impl(crate) trait TopLevel {}
pub mod inner {
pub impl(self) trait Inner {}
}
@@ -0,0 +1,98 @@
error: trait cannot be implemented outside `external`
--> $DIR/impl-restriction-check.rs:12:1
|
LL | impl external::TopLevel for LocalType {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: trait restricted here
--> $DIR/auxiliary/external-impl-restriction.rs:4:5
|
LL | pub impl(crate) trait TopLevel {}
| ^^^^^^^^^^^
error: trait cannot be implemented outside `external`
--> $DIR/impl-restriction-check.rs:13:1
|
LL | impl external::inner::Inner for LocalType {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: trait restricted here
--> $DIR/auxiliary/external-impl-restriction.rs:7:9
|
LL | pub impl(self) trait Inner {}
| ^^^^^^^^^^
error: trait cannot be implemented outside `foo::bar`
--> $DIR/impl-restriction-check.rs:30:5
|
LL | impl bar::Foo for i8 {}
| ^^^^^^^^^^^^^^^^^^^^
|
note: trait restricted here
--> $DIR/impl-restriction-check.rs:17:20
|
LL | pub(crate) impl(self) trait Foo {}
| ^^^^^^^^^^
error: trait cannot be implemented outside `foo::bar`
--> $DIR/impl-restriction-check.rs:39:1
|
LL | impl foo::bar::Foo for u8 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: trait restricted here
--> $DIR/impl-restriction-check.rs:17:20
|
LL | pub(crate) impl(self) trait Foo {}
| ^^^^^^^^^^
error: trait cannot be implemented outside `foo`
--> $DIR/impl-restriction-check.rs:41:1
|
LL | impl foo::bar::Bar for u8 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: trait restricted here
--> $DIR/impl-restriction-check.rs:18:20
|
LL | pub(crate) impl(super) trait Bar {}
| ^^^^^^^^^^^
error: trait cannot be implemented outside `foo::bar`
--> $DIR/impl-restriction-check.rs:34:5
|
LL | impl bar::Qux for i8 {}
| ^^^^^^^^^^^^^^^^^^^^
|
note: trait restricted here
--> $DIR/impl-restriction-check.rs:20:20
|
LL | pub(crate) impl(in crate::foo::bar) trait Qux {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: trait cannot be implemented outside `foo::bar`
--> $DIR/impl-restriction-check.rs:44:1
|
LL | impl foo::bar::Qux for u8 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: trait restricted here
--> $DIR/impl-restriction-check.rs:20:20
|
LL | pub(crate) impl(in crate::foo::bar) trait Qux {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: trait cannot be implemented outside `foo`
--> $DIR/impl-restriction-check.rs:46:1
|
LL | impl foo::bar::FooBar for u8 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: trait restricted here
--> $DIR/impl-restriction-check.rs:21:20
|
LL | pub(crate) impl(in crate::foo) trait FooBar {}
| ^^^^^^^^^^^^^^^^^^^
error: aborting due to 8 previous errors
@@ -0,0 +1,98 @@
error: trait cannot be implemented outside `external`
--> $DIR/impl-restriction-check.rs:12:1
|
LL | impl external::TopLevel for LocalType {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: trait restricted here
--> $DIR/auxiliary/external-impl-restriction.rs:4:5
|
LL | pub impl(crate) trait TopLevel {}
| ^^^^^^^^^^^
error: trait cannot be implemented outside `external`
--> $DIR/impl-restriction-check.rs:13:1
|
LL | impl external::inner::Inner for LocalType {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: trait restricted here
--> $DIR/auxiliary/external-impl-restriction.rs:7:9
|
LL | pub impl(self) trait Inner {}
| ^^^^^^^^^^
error: trait cannot be implemented outside `crate::foo::bar`
--> $DIR/impl-restriction-check.rs:30:5
|
LL | impl bar::Foo for i8 {}
| ^^^^^^^^^^^^^^^^^^^^
|
note: trait restricted here
--> $DIR/impl-restriction-check.rs:17:20
|
LL | pub(crate) impl(self) trait Foo {}
| ^^^^^^^^^^
error: trait cannot be implemented outside `crate::foo::bar`
--> $DIR/impl-restriction-check.rs:39:1
|
LL | impl foo::bar::Foo for u8 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: trait restricted here
--> $DIR/impl-restriction-check.rs:17:20
|
LL | pub(crate) impl(self) trait Foo {}
| ^^^^^^^^^^
error: trait cannot be implemented outside `crate::foo`
--> $DIR/impl-restriction-check.rs:41:1
|
LL | impl foo::bar::Bar for u8 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: trait restricted here
--> $DIR/impl-restriction-check.rs:18:20
|
LL | pub(crate) impl(super) trait Bar {}
| ^^^^^^^^^^^
error: trait cannot be implemented outside `crate::foo::bar`
--> $DIR/impl-restriction-check.rs:34:5
|
LL | impl bar::Qux for i8 {}
| ^^^^^^^^^^^^^^^^^^^^
|
note: trait restricted here
--> $DIR/impl-restriction-check.rs:20:20
|
LL | pub(crate) impl(in crate::foo::bar) trait Qux {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: trait cannot be implemented outside `crate::foo::bar`
--> $DIR/impl-restriction-check.rs:44:1
|
LL | impl foo::bar::Qux for u8 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: trait restricted here
--> $DIR/impl-restriction-check.rs:20:20
|
LL | pub(crate) impl(in crate::foo::bar) trait Qux {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: trait cannot be implemented outside `crate::foo`
--> $DIR/impl-restriction-check.rs:46:1
|
LL | impl foo::bar::FooBar for u8 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: trait restricted here
--> $DIR/impl-restriction-check.rs:21:20
|
LL | pub(crate) impl(in crate::foo) trait FooBar {}
| ^^^^^^^^^^^^^^^^^^^
error: aborting due to 8 previous errors
@@ -0,0 +1,49 @@
//@ aux-build: external-impl-restriction.rs
//@ revisions: e2015 e2018
//@ [e2015] edition: 2015
//@ [e2018] edition: 2018..
#![feature(impl_restriction)]
#![expect(incomplete_features)]
extern crate external_impl_restriction as external;
struct LocalType; // needed to avoid orphan rule errors
impl external::TopLevel for LocalType {} //~ ERROR trait cannot be implemented outside `external`
impl external::inner::Inner for LocalType {} //~ ERROR trait cannot be implemented outside `external`
pub mod foo {
pub mod bar {
pub(crate) impl(self) trait Foo {}
pub(crate) impl(super) trait Bar {}
pub impl(crate) trait Baz {}
pub(crate) impl(in crate::foo::bar) trait Qux {}
pub(crate) impl(in crate::foo) trait FooBar {}
impl Foo for i16 {} // OK
impl Bar for i16 {} // OK
impl Baz for i16 {} // OK
impl Qux for i16 {} // OK
impl FooBar for i16 {} // OK
}
impl bar::Foo for i8 {} //[e2015]~ ERROR trait cannot be implemented outside `foo::bar`
//[e2018]~^ ERROR trait cannot be implemented outside `crate::foo::bar`
impl bar::Bar for i8 {} // OK
impl bar::Baz for i8 {} // OK
impl bar::Qux for i8 {} //[e2015]~ ERROR trait cannot be implemented outside `foo::bar`
//[e2018]~^ ERROR trait cannot be implemented outside `crate::foo::bar`
impl bar::FooBar for i8 {} // OK
}
impl foo::bar::Foo for u8 {} //[e2015]~ ERROR trait cannot be implemented outside `foo::bar`
//[e2018]~^ ERROR trait cannot be implemented outside `crate::foo::bar`
impl foo::bar::Bar for u8 {} //[e2015]~ ERROR trait cannot be implemented outside `foo`
//[e2018]~^ ERROR trait cannot be implemented outside `crate::foo`
impl foo::bar::Baz for u8 {} // OK
impl foo::bar::Qux for u8 {} //[e2015]~ ERROR trait cannot be implemented outside `foo::bar`
//[e2018]~^ ERROR trait cannot be implemented outside `crate::foo::bar`
impl foo::bar::FooBar for u8 {} //[e2015]~ ERROR trait cannot be implemented outside `foo`
//[e2018]~^ ERROR trait cannot be implemented outside `crate::foo`
fn main() {}
@@ -1,6 +1,9 @@
//@ aux-build: external-impl-restriction.rs
#![feature(impl_restriction)]
#![expect(incomplete_features)]
extern crate external_impl_restriction as external;
pub mod a {
pub enum E {}
pub mod d {}
@@ -53,6 +56,8 @@ pub mod h {}
pub impl(super) trait T17 {} //~ ERROR too many leading `super` keywords [E0433]
pub impl(in external) trait T18 {} //~ ERROR trait implementation can only be restricted to ancestor modules
// Check if we can resolve paths referring to modules declared later.
pub impl(in crate::j) trait L4 {} //~ ERROR trait implementation can only be restricted to ancestor modules
@@ -1,71 +1,77 @@
error: trait implementation can only be restricted to ancestor modules
--> $DIR/restriction_resolution_errors.rs:14:21
--> $DIR/restriction_resolution_errors.rs:17:21
|
LL | pub impl(in ::std) trait T2 {}
| ^^^^^
error: trait implementation can only be restricted to ancestor modules
--> $DIR/restriction_resolution_errors.rs:16:21
--> $DIR/restriction_resolution_errors.rs:19:21
|
LL | pub impl(in self::c) trait T3 {}
| ^^^^^^^
error: trait implementation can only be restricted to ancestor modules
--> $DIR/restriction_resolution_errors.rs:18:21
--> $DIR/restriction_resolution_errors.rs:21:21
|
LL | pub impl(in super::d) trait T4 {}
| ^^^^^^^^
error[E0433]: too many leading `super` keywords
--> $DIR/restriction_resolution_errors.rs:24:35
--> $DIR/restriction_resolution_errors.rs:27:35
|
LL | pub impl(in super::super::super) trait T7 {}
| ^^^^^ there are too many leading `super` keywords
error: trait implementation can only be restricted to ancestor modules
--> $DIR/restriction_resolution_errors.rs:34:21
--> $DIR/restriction_resolution_errors.rs:37:21
|
LL | pub impl(in self::f) trait L1 {}
| ^^^^^^^
error: trait implementation can only be restricted to ancestor modules
--> $DIR/restriction_resolution_errors.rs:38:21
--> $DIR/restriction_resolution_errors.rs:41:21
|
LL | pub impl(in super::h) trait L3 {}
| ^^^^^^^^
error: trait implementation can only be restricted to ancestor modules
--> $DIR/restriction_resolution_errors.rs:47:13
--> $DIR/restriction_resolution_errors.rs:50:13
|
LL | pub impl(in crate::a) trait T13 {}
| ^^^^^^^^
error[E0433]: too many leading `super` keywords
--> $DIR/restriction_resolution_errors.rs:54:10
--> $DIR/restriction_resolution_errors.rs:57:10
|
LL | pub impl(super) trait T17 {}
| ^^^^^ there are too many leading `super` keywords
error: trait implementation can only be restricted to ancestor modules
--> $DIR/restriction_resolution_errors.rs:57:13
--> $DIR/restriction_resolution_errors.rs:59:13
|
LL | pub impl(in external) trait T18 {}
| ^^^^^^^^
error: trait implementation can only be restricted to ancestor modules
--> $DIR/restriction_resolution_errors.rs:62:13
|
LL | pub impl(in crate::j) trait L4 {}
| ^^^^^^^^
error: trait implementation can only be restricted to ancestor modules
--> $DIR/restriction_resolution_errors.rs:73:21
--> $DIR/restriction_resolution_errors.rs:78:21
|
LL | pub impl(in crate::m2) trait U2 {}
| ^^^^^^^^^
error: trait implementation can only be restricted to ancestor modules
--> $DIR/restriction_resolution_errors.rs:75:21
--> $DIR/restriction_resolution_errors.rs:80:21
|
LL | pub impl(in m6::m5) trait U4 {}
| ^^^^^^
error[E0433]: cannot find module or crate `a` in this scope
--> $DIR/restriction_resolution_errors.rs:12:21
--> $DIR/restriction_resolution_errors.rs:15:21
|
LL | pub impl(in a::b) trait T1 {}
| ^ use of unresolved module or unlinked crate `a`
@@ -81,25 +87,25 @@ LL + use a;
|
error[E0433]: cannot find module `c` in the crate root
--> $DIR/restriction_resolution_errors.rs:20:28
--> $DIR/restriction_resolution_errors.rs:23:28
|
LL | pub impl(in crate::c) trait T5 {}
| ^ not found in the crate root
error[E0577]: expected module, found enum `super::E`
--> $DIR/restriction_resolution_errors.rs:22:21
--> $DIR/restriction_resolution_errors.rs:25:21
|
LL | pub impl(in super::E) trait T6 {}
| ^^^^^^^^ not a module
error[E0577]: expected module, found enum `super::G`
--> $DIR/restriction_resolution_errors.rs:36:21
--> $DIR/restriction_resolution_errors.rs:39:21
|
LL | pub impl(in super::G) trait L2 {}
| ^^^^^^^^ not a module
error[E0577]: expected module, found enum `crate::a::E`
--> $DIR/restriction_resolution_errors.rs:49:13
--> $DIR/restriction_resolution_errors.rs:52:13
|
LL | pub mod b {
| --------- similarly named module `b` defined here
@@ -114,7 +120,7 @@ LL + pub impl(in crate::a::b) trait T14 {}
|
error[E0577]: expected module, found enum `crate::I`
--> $DIR/restriction_resolution_errors.rs:59:13
--> $DIR/restriction_resolution_errors.rs:64:13
|
LL | pub mod a {
| --------- similarly named module `a` defined here
@@ -129,12 +135,12 @@ LL + pub impl(in crate::a) trait L5 {}
|
error[E0577]: expected module, found enum `m7`
--> $DIR/restriction_resolution_errors.rs:76:21
--> $DIR/restriction_resolution_errors.rs:81:21
|
LL | pub impl(in m7) trait U5 {}
| ^^ not a module
error: aborting due to 18 previous errors
error: aborting due to 19 previous errors
Some errors have detailed explanations: E0433, E0577.
For more information about an error, try `rustc --explain E0433`.