Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d5c756a
Lower `impl` restriction to HIR
CoCo-Japan-pan Mar 22, 2026
01793db
Intravisit `hir::ImplRestriction`
CoCo-Japan-pan Mar 22, 2026
bda0fce
Lower `impl` restriction information to `TraitDef`
CoCo-Japan-pan Mar 25, 2026
cdbccf7
Emit error in implementation of restricted trait
CoCo-Japan-pan Mar 25, 2026
222292a
Add UI tests for semantic checks of `impl` restrictions
CoCo-Japan-pan Mar 27, 2026
159f1f2
Call `visit_path_segment` directly
CoCo-Japan-pan Apr 4, 2026
5863660
Remove `shorthand` from HIR
CoCo-Japan-pan Apr 4, 2026
4f12609
Remove the type alias for `Path<'hir, DefId>`
CoCo-Japan-pan Apr 4, 2026
65effbf
Add a FIXME for rustdoc handling `impl` restrictions
CoCo-Japan-pan Apr 4, 2026
2f400de
Modify `restriction_path`
CoCo-Japan-pan Apr 5, 2026
6f97273
Add non-ancestor errors involving restrictions to other crates
CoCo-Japan-pan Apr 5, 2026
72c1d65
Inline `krate`
CoCo-Japan-pan Apr 5, 2026
de2408a
Implement `-Z allow-partial-mitigations` (RFC 3855)
Nov 24, 2025
daedc77
address review comments
Nov 26, 2025
51b2b93
allow denying mitigations in earlier editions
Nov 27, 2025
eb89ca9
enforced => enforcable mitigation
Dec 7, 2025
3600f4c
EnforcableMitigation => DeniedPartialMitigation
Dec 10, 2025
cc2d560
use -Z deny-partial-mitigations instead of -Z allow-partial-mitigatio…
Dec 10, 2025
c55bfc6
enforcable -> enforceable
Dec 10, 2025
b4bfd7f
address review comments
Dec 16, 2025
a0ff19d
reset mitigation status on a mitigation option as per the RFC
Feb 19, 2026
1b96797
address review comments
Apr 6, 2026
46befd8
Display only crate name for external trait `impl` restrictions
CoCo-Japan-pan Apr 10, 2026
1137762
Suggest similar target names on unrecognized `--target`
jakedrew Apr 10, 2026
270ebfc
Tweak comment about intrinsics in cross-crate-inlinable
saethlin Apr 11, 2026
19a35e4
Rollup merge of #149357 - arielb1:enforce-partial-mitigations, r=rcvalle
jhpratt Apr 11, 2026
2c0dae2
Rollup merge of #154661 - CoCo-Japan-pan:impl-restriction-check, r=jh…
jhpratt Apr 11, 2026
5756977
Rollup merge of #155132 - jakedrew:fix/suggest-similar-target-on-unre…
jhpratt Apr 11, 2026
4064b25
Rollup merge of #155136 - saethlin:intrinsic-cci-comment, r=wesleywiser
jhpratt Apr 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 46 additions & 5 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use tracing::instrument;
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
Expand Down Expand Up @@ -540,14 +540,14 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
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,
Expand All @@ -566,7 +566,16 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
(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);
Expand Down Expand Up @@ -1831,6 +1840,38 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
}
}

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))]
Expand Down
24 changes: 20 additions & 4 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4341,13 +4341,14 @@ impl<'hir> Item<'hir> {
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);
Expand Down Expand Up @@ -4416,6 +4417,20 @@ impl fmt::Display for Constness {
}
}

#[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
Expand Down Expand Up @@ -4528,6 +4543,7 @@ pub enum ItemKind<'hir> {
Constness,
IsAuto,
Safety,
&'hir ImplRestriction<'hir>,
Ident,
&'hir Generics<'hir>,
GenericBounds<'hir>,
Expand Down Expand Up @@ -4578,7 +4594,7 @@ impl ItemKind<'_> {
| 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)
Expand All @@ -4596,7 +4612,7 @@ impl ItemKind<'_> {
| 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,
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_hir_analysis/src/coherence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}

Expand Down
25 changes: 20 additions & 5 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
};

Expand Down Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down Expand Up @@ -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) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, '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.
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,7 @@ impl<'a> State<'a> {
constness,
is_auto,
safety,
impl_restriction,
ident,
generics,
bounds,
Expand All @@ -770,6 +771,7 @@ impl<'a> State<'a> {
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);
Expand Down Expand Up @@ -2645,6 +2647,18 @@ impl<'a> State<'a> {
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
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1898,7 +1898,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Some(
Node::Item(hir::Item {
kind:
hir::ItemKind::Trait(_, _, _, ident, ..)
hir::ItemKind::Trait(_, _, _, _, ident, ..)
| hir::ItemKind::TraitAlias(_, ident, ..),
..
})
Expand Down Expand Up @@ -4545,7 +4545,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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() {
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,7 @@ fn configure_and_expand(

resolver.resolve_crate(&krate);

CStore::from_tcx(tcx).report_incompatible_target_modifiers(tcx, &krate);
CStore::from_tcx(tcx).report_incompatible_async_drop_feature(tcx, &krate);
CStore::from_tcx(tcx).report_session_incompatibilities(tcx, &krate);
krate
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/multiple_supertrait_upcastable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable {
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
Expand Down
Loading
Loading