Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
39628ff
remove untrue/contentious statement
tshepang Sep 8, 2025
1eb80f1
restore helpful explanation
tshepang Oct 4, 2025
491554d
add tests for unsizing coercions (both ICE)
jdonszelmann Oct 2, 2025
14a2770
Rename nit
compiler-errors Jun 2, 2025
5689477
Rework unsizing coercions in new solver
compiler-errors Jun 2, 2025
5765a82
Prepare for merging from rust-lang/rust
invalid-email-address Oct 20, 2025
0152aa8
Merge ref '4068bafedd8b' from rust-lang/rust
invalid-email-address Oct 20, 2025
f036a30
Merge pull request #2614 from rust-lang/rustc-pull
tshepang Oct 20, 2025
b0545d6
how-to-build-and-run.md: remove stray instructions
tshepang Oct 20, 2025
5976015
compiletest: show output in debug logging
jyn514 Oct 23, 2025
8badb14
Add the gpu version of the kernel which was missing in the docs
ZuseZ4 Oct 24, 2025
bfbe728
Merge pull request #2616 from rust-lang/gpu-example-update
ZuseZ4 Oct 24, 2025
38a1790
tests/ui/sanitizer/hwaddress.rs: Run on aarch64 and remove cgu hack
Enselic Oct 18, 2025
f28ed4c
1.91.0 release notes
Mark-Simulacrum Oct 23, 2025
ee978d2
Merge pull request #2615 from rust-lang/tshepang-patch-2
jieyouxu Oct 26, 2025
9503981
add a mailmap entry
WaffleLapkin Oct 15, 2025
87c66c9
ci: loongarch64: use medium code model to avoid relocation overflows
heiher Oct 26, 2025
b12f711
Prepare for merging from rust-lang/rust
invalid-email-address Oct 27, 2025
e88afc0
Merge ref 'b1b464d6f61e' from rust-lang/rust
invalid-email-address Oct 27, 2025
a918702
Re-enable macro-stepping test for AArch64
Jamesbarford Oct 27, 2025
349dbec
move old solver coercion code to separate function
jdonszelmann Oct 20, 2025
3d9cb04
prove both newly added tests are fixed by the changes
jdonszelmann Oct 2, 2025
1756622
find the right error source when we can't unsize
jdonszelmann Oct 3, 2025
94c893e
Add `coverage` scope for controlling paths in code coverage
Urgau Oct 26, 2025
943074f
improve and strengthen wording
tshepang Oct 27, 2025
58d2f03
Merge pull request #2583 from rust-lang/tshepang-patch-4
tshepang Oct 27, 2025
044bc7a
Merge pull request #2617 from rust-lang/rustc-pull
tshepang Oct 27, 2025
bf6f303
Fix typos: duplicate words in comments
osamakader Oct 27, 2025
83cb889
Link to `i32` for `strict_div`/`rem` methods
cuviper Oct 27, 2025
b9b29c4
repr(transparent): do not consider repr(C) types to be 1-ZST
RalfJung Oct 17, 2025
20d3d57
CFI: Rewrite `FnPtrShim` when generalizing
rcvalle Aug 5, 2025
610b82e
Update target maintainers android.md
pirama-arumuga-nainar Oct 20, 2025
7a26eff
Rollup merge of #144936 - rcvalle:rust-cfi-fix-144641, r=lcnr
Zalathar Oct 28, 2025
0a0d1a3
Rollup merge of #147185 - RalfJung:repr-c-not-zst, r=petrochenkov
Zalathar Oct 28, 2025
07be389
Rollup merge of #147840 - jdonszelmann:unsizing-coercions, r=lcnr
Zalathar Oct 28, 2025
f38cf62
Rollup merge of #147915 - pirama-arumuga-nainar:patch-1, r=lqd
Zalathar Oct 28, 2025
c3669dd
Rollup merge of #148013 - Mark-Simulacrum:relnotes, r=Mark-Simulacrum
Zalathar Oct 28, 2025
2691fd6
Rollup merge of #148044 - jyn514:compiletest-logging, r=Zalathar
Zalathar Oct 28, 2025
df98447
Rollup merge of #148057 - Enselic:hwasan-fix-v2, r=nagisa
Zalathar Oct 28, 2025
b4546b2
Rollup merge of #148139 - Urgau:add-coverage-scope, r=Zalathar
Zalathar Oct 28, 2025
e65f9bc
Rollup merge of #148154 - WaffleLapkin:mail-and-ename, r=WaffleLapkin
Zalathar Oct 28, 2025
806e49f
Rollup merge of #148158 - heiher:loong64-medium, r=jieyouxu
Zalathar Oct 28, 2025
bbdd8f8
Rollup merge of #148166 - Jamesbarford:fix/aarch64-reenable-macro-ste…
Zalathar Oct 28, 2025
b0ee95c
Rollup merge of #148172 - tshepang:rdg-sync, r=tshepang
Zalathar Oct 28, 2025
a4230a0
Rollup merge of #148175 - osamakader:fix-typos-duplicate-words, r=lcnr
Zalathar Oct 28, 2025
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
1 change: 1 addition & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,7 @@ Valerii Lashmanov <vflashm@gmail.com>
Vitali Haravy <HumaneProgrammer@gmail.com> Vitali Haravy <humaneprogrammer@gmail.com>
Vitaly Shukela <vi0oss@gmail.com>
Waffle Lapkin <waffle.lapkin@gmail.com>
Waffle Lapkin <waffle.lapkin@gmail.com> <Waffle Lapkin>
Waffle Lapkin <waffle.lapkin@gmail.com> <waffle.lapkin@tasking.com>
Weihang Lo <me@weihanglo.tw>
Weihang Lo <me@weihanglo.tw> <weihanglo@users.noreply.github.com>
Expand Down
211 changes: 211 additions & 0 deletions RELEASES.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions compiler/rustc_ast_pretty/src/pp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ impl Printer {
}
}

// This is is where `BoxMarker`s are produced.
// This is where `BoxMarker`s are produced.
fn scan_begin(&mut self, token: BeginToken) -> BoxMarker {
if self.scan_stack.is_empty() {
self.left_total = 1;
Expand All @@ -310,7 +310,7 @@ impl Printer {
BoxMarker
}

// This is is where `BoxMarker`s are consumed.
// This is where `BoxMarker`s are consumed.
fn scan_end(&mut self, b: BoxMarker) {
if self.scan_stack.is_empty() {
self.print_end();
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl GlobalFileTable {
for file in all_files {
raw_file_table.entry(file.stable_id).or_insert_with(|| {
file.name
.for_scope(tcx.sess, RemapPathScopeComponents::MACRO)
.for_scope(tcx.sess, RemapPathScopeComponents::COVERAGE)
.to_string_lossy()
.into_owned()
});
Expand All @@ -147,7 +147,7 @@ impl GlobalFileTable {
.sess
.opts
.working_dir
.for_scope(tcx.sess, RemapPathScopeComponents::MACRO)
.for_scope(tcx.sess, RemapPathScopeComponents::COVERAGE)
.to_string_lossy();
table.push(base_dir.as_ref());

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ impl EnteredTraceSpan for tracing::span::EnteredSpan {
/// ### `tracing_separate_thread` parameter
///
/// This macro was introduced to obtain better traces of Miri without impacting release performance.
/// Miri saves traces using the the `tracing_chrome` `tracing::Layer` so that they can be visualized
/// Miri saves traces using the `tracing_chrome` `tracing::Layer` so that they can be visualized
/// in <https://ui.perfetto.dev>. To instruct `tracing_chrome` to put some spans on a separate trace
/// thread/line than other spans when viewed in <https://ui.perfetto.dev>, you can pass
/// `tracing_separate_thread = tracing::field::Empty` to the tracing macros. This is useful to
Expand Down
111 changes: 68 additions & 43 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::{LangItem, Node, attrs, find_attr, intravisit};
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
use rustc_infer::traits::{Obligation, ObligationCauseCode, WellFormedLoc};
use rustc_lint_defs::builtin::{
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, UNSUPPORTED_CALLING_CONVENTIONS,
};
use rustc_lint_defs::builtin::{REPR_TRANSPARENT_NON_ZST_FIELDS, UNSUPPORTED_CALLING_CONVENTIONS};
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
use rustc_middle::middle::stability::EvalResult;
Expand Down Expand Up @@ -1509,31 +1507,46 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
}

let typing_env = ty::TypingEnv::non_body_analysis(tcx, adt.did());
// For each field, figure out if it's known to have "trivial" layout (i.e., is a 1-ZST), with
// "known" respecting #[non_exhaustive] attributes.
// For each field, figure out if it has "trivial" layout (i.e., is a 1-ZST).
// Even some 1-ZST fields are not allowed though, if they have `non_exhaustive` or private
// fields or `repr(C)`. We call those fields "unsuited".
struct FieldInfo<'tcx> {
span: Span,
trivial: bool,
unsuited: Option<UnsuitedInfo<'tcx>>,
}
struct UnsuitedInfo<'tcx> {
/// The source of the problem, a type that is found somewhere within the field type.
ty: Ty<'tcx>,
reason: UnsuitedReason,
}
enum UnsuitedReason {
NonExhaustive,
PrivateField,
ReprC,
}

let field_infos = adt.all_fields().map(|field| {
let ty = field.ty(tcx, GenericArgs::identity_for_item(tcx, field.did));
let layout = tcx.layout_of(typing_env.as_query_input(ty));
// We are currently checking the type this field came from, so it must be local
let span = tcx.hir_span_if_local(field.did).unwrap();
let trivial = layout.is_ok_and(|layout| layout.is_1zst());
if !trivial {
return (span, trivial, None);
// No need to even compute `unsuited`.
return FieldInfo { span, trivial, unsuited: None };
}
// Even some 1-ZST fields are not allowed though, if they have `non_exhaustive`.

fn check_non_exhaustive<'tcx>(
fn check_unsuited<'tcx>(
tcx: TyCtxt<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
t: Ty<'tcx>,
) -> ControlFlow<(&'static str, DefId, GenericArgsRef<'tcx>, bool)> {
ty: Ty<'tcx>,
) -> ControlFlow<UnsuitedInfo<'tcx>> {
// We can encounter projections during traversal, so ensure the type is normalized.
let t = tcx.try_normalize_erasing_regions(typing_env, t).unwrap_or(t);
match t.kind() {
ty::Tuple(list) => {
list.iter().try_for_each(|t| check_non_exhaustive(tcx, typing_env, t))
}
ty::Array(ty, _) => check_non_exhaustive(tcx, typing_env, *ty),
let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);
match ty.kind() {
ty::Tuple(list) => list.iter().try_for_each(|t| check_unsuited(tcx, typing_env, t)),
ty::Array(ty, _) => check_unsuited(tcx, typing_env, *ty),
ty::Adt(def, args) => {
if !def.did().is_local()
&& !find_attr!(
Expand All @@ -1548,28 +1561,36 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
.any(ty::VariantDef::is_field_list_non_exhaustive);
let has_priv = def.all_fields().any(|f| !f.vis.is_public());
if non_exhaustive || has_priv {
return ControlFlow::Break((
def.descr(),
def.did(),
args,
non_exhaustive,
));
return ControlFlow::Break(UnsuitedInfo {
ty,
reason: if non_exhaustive {
UnsuitedReason::NonExhaustive
} else {
UnsuitedReason::PrivateField
},
});
}
}
if def.repr().c() {
return ControlFlow::Break(UnsuitedInfo {
ty,
reason: UnsuitedReason::ReprC,
});
}
def.all_fields()
.map(|field| field.ty(tcx, args))
.try_for_each(|t| check_non_exhaustive(tcx, typing_env, t))
.try_for_each(|t| check_unsuited(tcx, typing_env, t))
}
_ => ControlFlow::Continue(()),
}
}

(span, trivial, check_non_exhaustive(tcx, typing_env, ty).break_value())
FieldInfo { span, trivial, unsuited: check_unsuited(tcx, typing_env, ty).break_value() }
});

let non_trivial_fields = field_infos
.clone()
.filter_map(|(span, trivial, _non_exhaustive)| if !trivial { Some(span) } else { None });
.filter_map(|field| if !field.trivial { Some(field.span) } else { None });
let non_trivial_count = non_trivial_fields.clone().count();
if non_trivial_count >= 2 {
bad_non_zero_sized_fields(
Expand All @@ -1581,36 +1602,40 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
);
return;
}
let mut prev_non_exhaustive_1zst = false;
for (span, _trivial, non_exhaustive_1zst) in field_infos {
if let Some((descr, def_id, args, non_exhaustive)) = non_exhaustive_1zst {

let mut prev_unsuited_1zst = false;
for field in field_infos {
if let Some(unsuited) = field.unsuited {
assert!(field.trivial);
// If there are any non-trivial fields, then there can be no non-exhaustive 1-zsts.
// Otherwise, it's only an issue if there's >1 non-exhaustive 1-zst.
if non_trivial_count > 0 || prev_non_exhaustive_1zst {
if non_trivial_count > 0 || prev_unsuited_1zst {
tcx.node_span_lint(
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
REPR_TRANSPARENT_NON_ZST_FIELDS,
tcx.local_def_id_to_hir_id(adt.did().expect_local()),
span,
field.span,
|lint| {
let title = match unsuited.reason {
UnsuitedReason::NonExhaustive => "external non-exhaustive types",
UnsuitedReason::PrivateField => "external types with private fields",
UnsuitedReason::ReprC => "`repr(C)` types",
};
lint.primary_message(
"zero-sized fields in `repr(transparent)` cannot \
contain external non-exhaustive types",
format!("zero-sized fields in `repr(transparent)` cannot contain {title}"),
);
let note = if non_exhaustive {
"is marked with `#[non_exhaustive]`"
} else {
"contains private fields"
let note = match unsuited.reason {
UnsuitedReason::NonExhaustive => "is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.",
UnsuitedReason::PrivateField => "contains private fields, so it could become non-zero-sized in the future.",
UnsuitedReason::ReprC => "is a `#[repr(C)]` type, so it is not guaranteed to be zero-sized on all targets.",
};
let field_ty = tcx.def_path_str_with_args(def_id, args);
lint.note(format!(
"this {descr} contains `{field_ty}`, which {note}, \
and makes it not a breaking change to become \
non-zero-sized in the future."
"this field contains `{field_ty}`, which {note}",
field_ty = unsuited.ty,
));
},
)
);
} else {
prev_non_exhaustive_1zst = true;
prev_unsuited_1zst = true;
}
}
}
Expand Down
Loading
Loading