Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
ab617ae
interpret: improve assignment type validity check and error messages
RalfJung Apr 19, 2026
60604b4
Use `impl` restrictions in `std`
jhpratt May 30, 2026
478acf6
Use `impl` restrictions in `core`
jhpratt May 30, 2026
0e69e90
Update UI tests
jhpratt May 31, 2026
f898e61
Correct description of panic.rs
felix91gr Jun 1, 2026
5a302ff
rustdoc: Preserve sizedness bounds on type params belonging to the pa…
fmease Jun 1, 2026
fc18f42
[tiny] remove unecessary `.into()` calls
estebank May 31, 2026
8dd7b1b
interpret: fix mir::UnOp layout computation
RalfJung Jun 2, 2026
1c2fe35
Track trait map per-owner
oli-obk Jun 2, 2026
2a52dc4
Avoid leaking the query-job collection warning into panic output
xmakro Jun 3, 2026
03895a0
powerpc: warn against incorrect values for ABI-relevant target features
RalfJung May 28, 2026
3fbaefd
Track import map per-owner
oli-obk Jun 2, 2026
1ec9b30
librustdoc: fix CSS border issue to support Firefox high contrast mod…
robbycbennett Jun 3, 2026
591d5da
explicitly track SPE ABI for PowerPC
RalfJung May 30, 2026
b6a2d84
Re-enable the proc-macro repr(packed) ICE test under the parallel fro…
xmakro Jun 3, 2026
130b501
Rewrite target checking for `#[sanitize]`
JonathanBrouwer Jun 2, 2026
f721e6c
Add `attr-on-mac-call` test
JonathanBrouwer Jun 3, 2026
97dc1b1
Add "functions with a body" target group
JonathanBrouwer Jun 3, 2026
8e9173f
librustdoc: update test to fix CSS border issue to support Firefox hi…
robbycbennett Jun 3, 2026
37a30dc
Add clarfonthey to libs review rotation
clarfonthey Jun 3, 2026
ca881ba
Rollup merge of #157085 - RalfJung:powerpc-abi-features, r=petrochenkov
jhpratt Jun 3, 2026
feb69d6
Rollup merge of #157170 - jhpratt:dogfood-restrictions, r=Urgau
jhpratt Jun 3, 2026
ed3306f
Rollup merge of #157217 - estebank:useless-into-rust, r=petrochenkov
jhpratt Jun 3, 2026
5478269
Rollup merge of #157262 - fmease:rustdoc-preserve-sizedness-bounds-on…
jhpratt Jun 3, 2026
fc36bf2
Rollup merge of #157379 - oli-obk:more-per-owner, r=petrochenkov
jhpratt Jun 3, 2026
9e9fd1b
Rollup merge of #157381 - robbycbennett:librustdoc-fix-borders, r=not…
jhpratt Jun 3, 2026
1b77f84
Rollup merge of #155512 - RalfJung:interpret-assignment-validity, r=o…
jhpratt Jun 3, 2026
ce0ff3c
Rollup merge of #157254 - felix91gr:patch-1, r=jhpratt
jhpratt Jun 3, 2026
80c5ad6
Rollup merge of #157290 - RalfJung:unop-layout, r=oli-obk
jhpratt Jun 3, 2026
c832971
Rollup merge of #157332 - JonathanBrouwer:target-sanitize, r=mejrs
jhpratt Jun 3, 2026
5660f7f
Rollup merge of #157351 - xmakro:fix/parallel-collect-jobs-warn, r=pe…
jhpratt Jun 3, 2026
c4f09d5
Rollup merge of #157389 - clarfonthey:triagebot, r=clarfonthey
jhpratt Jun 3, 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
15 changes: 5 additions & 10 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ struct LoweringContext<'a, 'hir> {
is_in_dyn_type: bool,

current_hir_id_owner: hir::OwnerId,
owner: &'a PerOwnerResolverData,
owner: &'a PerOwnerResolverData<'hir>,
item_local_id_counter: hir::ItemLocalId,
trait_map: ItemLocalMap<&'hir [TraitCandidate<'hir>]>,

Expand Down Expand Up @@ -288,11 +288,6 @@ impl<'tcx> ResolverAstLowering<'tcx> {
.map(|fn_indexes| fn_indexes.iter().map(|(num, _)| *num).collect())
}

/// Obtains per-namespace resolutions for `use` statement with the given `NodeId`.
fn get_import_res(&self, id: NodeId) -> PerNS<Option<Res<NodeId>>> {
self.import_res_map.get(&id).copied().unwrap_or_default()
}

/// Obtain the list of lifetimes parameters to add to an item.
///
/// Extra lifetime parameters should only be added in places that can appear
Expand Down Expand Up @@ -810,8 +805,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
}

if let Some(traits) = self.resolver.trait_map.get(&ast_node_id) {
self.trait_map.insert(hir_id.local_id, &traits[..]);
if let Some(traits) = self.owner.trait_map.get(&ast_node_id) {
self.trait_map.insert(hir_id.local_id, *traits);
}

// Check whether the same `NodeId` is lowered more than once.
Expand Down Expand Up @@ -856,8 +851,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
}

fn lower_import_res(&mut self, id: NodeId, span: Span) -> PerNS<Option<Res>> {
let per_ns = self.resolver.get_import_res(id);
let per_ns = per_ns.map(|res| res.map(|res| self.lower_res(res)));
debug_assert_eq!(id, self.owner.id);
let per_ns = self.owner.import_res.map(|res| res.map(|res| self.lower_res(res)));
if per_ns.is_empty() {
// Propagate the error to all namespaces, just to be sure.
self.dcx().span_delayed_bug(span, "no resolution for an import");
Expand Down
27 changes: 25 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::attributes::AttributeSafety;
use crate::session_diagnostics::{
EmptyExportName, NakedFunctionIncompatibleAttribute, NullOnExport, NullOnObjcClass,
NullOnObjcSelector, ObjcClassExpectedStringLiteral, ObjcSelectorExpectedStringLiteral,
SanitizeInvalidStatic,
};
use crate::target_checking::Policy::AllowSilent;

Expand Down Expand Up @@ -566,8 +567,18 @@ pub(crate) struct SanitizeParser;

impl SingleAttributeParser for SanitizeParser {
const PATH: &[Symbol] = &[sym::sanitize];
// FIXME: still checked in check_attrs.rs
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Closure),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::Method(MethodKind::TraitImpl)),
Allow(Target::Impl { of_trait: false }),
Allow(Target::Impl { of_trait: true }),
Allow(Target::Mod),
Allow(Target::Crate),
Allow(Target::Static),
]);
const TEMPLATE: AttributeTemplate = template!(List: &[
r#"address = "on|off""#,
r#"kernel_address = "on|off""#,
Expand Down Expand Up @@ -668,6 +679,18 @@ impl SingleAttributeParser for SanitizeParser {
}
}

// The sanitizer attribute is only allowed on statics, if only address bits are set
let all_set_except_address =
(on_set | off_set) & !(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS);
if cx.target == Target::Static
&& let Some(set) = all_set_except_address.iter().next()
{
cx.emit_err(SanitizeInvalidStatic {
span: cx.attr_span,
field: set.as_str().expect("Since this `SanitizerSet` is returned from an iterator, exactly one field is set")
});
}

Some(AttributeKind::Sanitize { on_set, off_set, rtsan, span: cx.attr_span })
}
}
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1023,3 +1023,12 @@ pub(crate) enum InvalidMachoSectionReason {
#[note("section name `{$section}` is longer than 16 bytes")]
SectionTooLong { section: String },
}

#[derive(Diagnostic)]
#[diag("`#[sanitize({$field} = ...)]` attribute cannot be used on statics")]
#[help("`#[sanitize]` can be used on statics if only the address is sanitized")]
pub(crate) struct SanitizeInvalidStatic {
#[primary_span]
pub span: Span,
pub field: &'static str,
}
14 changes: 14 additions & 0 deletions compiler/rustc_attr_parsing/src/target_checking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,13 @@ pub(crate) fn allowed_targets_applied(
Target::Method(MethodKind::Trait { body: true }),
Target::Method(MethodKind::TraitImpl),
];
const FUNCTION_WITH_BODY_LIKE: &[Target] = &[
Target::Fn,
Target::Closure,
Target::Method(MethodKind::Inherent),
Target::Method(MethodKind::Trait { body: true }),
Target::Method(MethodKind::TraitImpl),
];
const METHOD_LIKE: &[Target] = &[
Target::Method(MethodKind::Inherent),
Target::Method(MethodKind::Trait { body: false }),
Expand All @@ -379,6 +386,13 @@ pub(crate) fn allowed_targets_applied(
target,
&mut added_fake_targets,
);
filter_targets(
&mut allowed_targets,
FUNCTION_WITH_BODY_LIKE,
"functions with a body",
target,
&mut added_fake_targets,
);
filter_targets(&mut allowed_targets, METHOD_LIKE, "methods", target, &mut added_fake_targets);
filter_targets(&mut allowed_targets, IMPL_LIKE, "impl blocks", target, &mut added_fake_targets);
filter_targets(&mut allowed_targets, ADT_LIKE, "data types", target, &mut added_fake_targets);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ fn test_escape() {
fn test_parse() {
macro_rules! assert_pns_eq_sub {
($in_:expr, $kind:ident($arg:expr, $pos:expr)) => {
assert_eq!(pns(concat!($in_, "!")), Some((S::$kind($arg.into(), $pos), "!")))
assert_eq!(pns(concat!($in_, "!")), Some((S::$kind($arg, $pos), "!")))
};
}

Expand Down
27 changes: 16 additions & 11 deletions compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,25 +165,30 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}

/// Test if it is valid for a MIR assignment to assign `src`-typed place to `dest`-typed value.
/// This test should be symmetric, as it is primarily about layout compatibility.
pub(super) fn mir_assign_valid_types<'tcx>(
tcx: TyCtxt<'tcx>,
typing_env: TypingEnv<'tcx>,
src: TyAndLayout<'tcx>,
dest: TyAndLayout<'tcx>,
) -> bool {
// Type-changing assignments can happen when subtyping is used. While
// all normal lifetimes are erased, higher-ranked types with their
// late-bound lifetimes are still around and can lead to type
// differences.
// We *could* check `Invariant` here since all subtyping must be explicit post-borrowck.
// However, this check is also used by the interpreter to figure out if a transmute can be
// turned into a regular assignment (which has a more efficient codepath), so we want the check
// to consider as many assignments as possible to be valid. Therefore we are happy to accept
// one-way subtyping.
if util::relate_types(tcx, typing_env, Variance::Covariant, src.ty, dest.ty) {
// Make sure the layout is equal, too -- just to be safe. Miri really
// needs layout equality. For performance reason we skip this check when
// the types are equal. Equal types *can* have different layouts when
// enum downcast is involved (as enum variants carry the type of the
// enum), but those should never occur in assignments.
// Make sure the layout is equal, too -- just to be safe. Miri really needs layout equality.
// For performance reason we skip this check when the types are equal. Equal types *can*
// have different layouts when enum downcast is involved (as enum variants carry the type of
// the enum), but those should never occur in assignments.
if cfg!(debug_assertions) || src.ty != dest.ty {
assert_eq!(src.layout, dest.layout);
assert_eq!(
src.layout,
dest.layout,
"{src} is a subtype of {dest} but they have different layout",
src = src.ty,
dest = dest.ty,
);
}
true
} else {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}

UnaryOp(un_op, ref operand) => {
// The operand always has the same type as the result.
let val = self.read_immediate(&self.eval_operand(operand, Some(dest.layout))?)?;
let layout = util::unop_homogeneous(un_op).then_some(dest.layout);
let val = self.read_immediate(&self.eval_operand(operand, layout)?)?;
let result = self.unary_op(un_op, &val)?;
assert_eq!(result.layout, dest.layout, "layout mismatch for result of {un_op:?}");
self.write_immediate(*result, &dest)?;
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_const_eval/src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,13 @@ pub fn binop_right_homogeneous(op: mir::BinOp) -> bool {
Offset | Shl | ShlUnchecked | Shr | ShrUnchecked => false,
}
}

/// Classify whether an operator is "homogeneous", i.e., the operand has the
/// same type as the result.
#[inline]
pub fn unop_homogeneous(op: mir::UnOp) -> bool {
match op {
mir::UnOp::Not | mir::UnOp::Neg => true,
mir::UnOp::PtrMetadata => false,
}
}
3 changes: 2 additions & 1 deletion compiler/rustc_hir/src/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,8 @@ impl IntoDiagArg for Namespace {
}

/// Just a helper ‒ separate structure for each namespace.
#[derive(Copy, Clone, Default, Debug, StableHash)]
#[derive(Copy, Clone, Debug, StableHash)]
#[derive_const(Default)]
pub struct PerNS<T> {
pub value_ns: T,
pub type_ns: T,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ impl<'tcx> InferCtxt<'tcx> {
(GenericArgKind::Lifetime(v_o), GenericArgKind::Lifetime(v_r)) => {
if v_o != v_r {
output_query_region_constraints.constraints.push((
ty::RegionEqPredicate(v_o.into(), v_r).into(),
ty::RegionEqPredicate(v_o, v_r).into(),
constraint_category,
ty::VisibleForLeakCheck::Yes,
));
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_middle/src/mir/interpret/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,12 @@ impl<'tcx> TyCtxt<'tcx> {
Ok(Some(instance)) => GlobalId { instance, promoted: None },
// For errors during resolution, we deliberately do not point at the usage site of the constant,
// since for these errors the place the constant is used shouldn't matter.
Ok(None) => return Err(ErrorHandled::TooGeneric(DUMMY_SP).into()),
Ok(None) => return Err(ErrorHandled::TooGeneric(DUMMY_SP)),
Err(err) => {
return Err(ErrorHandled::Reported(
ReportedErrorInfo::non_const_eval_error(err),
DUMMY_SP,
)
.into());
));
}
};

Expand Down
21 changes: 11 additions & 10 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ pub use intrinsic::IntrinsicDef;
use rustc_abi::{
Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, ScalableElt, VariantIdx,
};
use rustc_ast as ast;
use rustc_ast::expand::typetree::{FncTree, Kind, Type, TypeTree};
use rustc_ast::node_id::NodeMap;
use rustc_ast::{self as ast};
pub use rustc_ast_ir::{Movability, Mutability, try_visit};
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::intern::Interned;
Expand Down Expand Up @@ -204,7 +204,7 @@ pub struct ResolverGlobalCtxt {
}

#[derive(Debug)]
pub struct PerOwnerResolverData {
pub struct PerOwnerResolverData<'tcx> {
pub node_id_to_def_id: NodeMap<LocalDefId> = Default::default(),
/// Whether lifetime elision was successful.
pub lifetime_elision_allowed: bool = false,
Expand All @@ -214,14 +214,19 @@ pub struct PerOwnerResolverData {
/// Resolutions for lifetimes.
pub lifetimes_res_map: NodeMap<LifetimeRes> = Default::default(),

pub trait_map: NodeMap<&'tcx [hir::TraitCandidate<'tcx>]> = Default::default(),

/// Resolution for import nodes, which have multiple resolutions in different namespaces.
pub import_res: hir::def::PerNS<Option<Res<ast::NodeId>>> = Default::default(),

/// The id of the owner
pub id: ast::NodeId,
/// The `DefId` of the owner, can't be found in `node_id_to_def_id`.
pub def_id: LocalDefId,
}

impl PerOwnerResolverData {
pub fn new(id: ast::NodeId, def_id: LocalDefId) -> PerOwnerResolverData {
impl<'tcx> PerOwnerResolverData<'tcx> {
pub fn new(id: ast::NodeId, def_id: LocalDefId) -> PerOwnerResolverData<'tcx> {
PerOwnerResolverData { id, def_id, .. }
}

Expand All @@ -242,16 +247,12 @@ impl PerOwnerResolverData {
pub struct ResolverAstLowering<'tcx> {
/// Resolutions for nodes that have a single resolution.
pub partial_res_map: NodeMap<hir::def::PartialRes>,
/// Resolutions for import nodes, which have multiple resolutions in different namespaces.
pub import_res_map: NodeMap<hir::def::PerNS<Option<Res<ast::NodeId>>>>,
/// Lifetime parameters that lowering will have to introduce.
pub extra_lifetime_params_map: NodeMap<Vec<(Ident, ast::NodeId, MissingLifetimeKind)>>,

pub next_node_id: ast::NodeId,

pub owners: NodeMap<PerOwnerResolverData>,

pub trait_map: NodeMap<&'tcx [hir::TraitCandidate<'tcx>]>,
pub owners: NodeMap<PerOwnerResolverData<'tcx>>,

/// Lints that were emitted by the resolver and early lints.
pub lint_buffer: Steal<LintBuffer>,
Expand Down Expand Up @@ -1098,7 +1099,7 @@ impl<'tcx> TypingEnv<'tcx> {
def_id: impl IntoQueryKey<DefId>,
) -> TypingEnv<'tcx> {
let def_id = def_id.into_query_key();
Self::new(tcx.param_env(def_id), TypingMode::non_body_analysis().into())
Self::new(tcx.param_env(def_id), TypingMode::non_body_analysis())
}

pub fn post_analysis(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryKey<DefId>) -> TypingEnv<'tcx> {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/builder/expr/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
source_info,
destination,
Rvalue::Reborrow(target, mutability, place.into()),
Rvalue::Reborrow(target, mutability, place),
);
block.unit()
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/check_null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ fn insert_null_check<'tcx>(
source_info,
StatementKind::Assign(Box::new((pointee_should_be_checked, rvalue))),
));
Operand::Copy(pointee_should_be_checked.into())
Operand::Copy(pointee_should_be_checked)
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ where
impl_def_id,
impl_args,
impl_trait_ref,
target_container_def_id.into(),
target_container_def_id,
)?;

if !cx.check_args_compatible(target_item_def_id.into(), target_args) {
Expand Down
Loading
Loading