Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
91850e9
Avoid `unsafe fn` in aarch64, powerpc and s390x tests
eduardosm Jan 28, 2026
e164dca
Don't expect specific instructions for _mm256_set_pd/_mm_set_ps
nikic Jan 29, 2026
293b61e
Ignore non-yml files in generator
nikic Jan 29, 2026
f5d594a
Change lanes vcopy_lane tests to avoid zip2
nikic Jan 29, 2026
b500dd3
Adjust expected output for vrfin
nikic Jan 29, 2026
20da410
Merge pull request #2007 from nikic/ci-test
folkertdev Jan 29, 2026
9eaf7fa
Merge pull request #2006 from eduardosm/unsafe-tests
folkertdev Jan 29, 2026
9ea3034
powerpc: implement `vnmsubfp` using `intrinsics::simd`
folkertdev Jan 31, 2026
ebc618a
wasm: use `intrinsics::simd` for the narrow functions
folkertdev Jan 31, 2026
5b8b7f5
Merge pull request #2011 from folkertdev/wasm-narrow-llvm-22
Amanieu Jan 31, 2026
c1196d4
Merge pull request #2010 from folkertdev/powerpc-vnmsub-llvm-22
Amanieu Jan 31, 2026
e40ae4f
x86: use `intrinsics::simd` for `hadds`/`hsubs`
folkertdev Jan 31, 2026
4a1094c
Merge pull request #2012 from folkertdev/llvm-22-hadds-hsubs
sayantn Feb 1, 2026
24a2833
test the `vld1*` functions
folkertdev Jan 30, 2026
a208e6c
maybe fix aarch64be unsigned vector tuple loads
folkertdev Jan 30, 2026
0306275
use macro for wide store/load roundtrip tests
folkertdev Feb 1, 2026
794810f
use more capable macro for wide store/load roundtrip tests
folkertdev Feb 1, 2026
141a867
Revert "Use LLVM intrinsics for `madd` intrinsics"
folkertdev Feb 1, 2026
f5540ad
add test for multiply by one pattern
folkertdev Feb 1, 2026
7b62d97
Mention implicit bounds from `#[derive(Clone)]` on moved value
estebank Jan 17, 2026
679f38c
On E0277 pointing at bound in derive, suggest manual impl
estebank Jan 18, 2026
54fe73f
Tweak span labels caused by trait bound coming from derive expansion
estebank Jan 18, 2026
b88fb8a
Mention that the trait could be manually impld in E0599
estebank Jan 18, 2026
085da0c
On E0308 caused by cloning a reference due to missing bounds, account…
estebank Jan 18, 2026
aebf1fd
Keep span of type in builtin derive macros expansions
estebank Jan 18, 2026
b9e5cf7
Fix incorrect suggestion caused by change in derive expansion Span
estebank Jan 18, 2026
dd81483
Tweak span labels
estebank Jan 18, 2026
20000ca
Point at destructor when denying deriving `Copy`
estebank Jan 18, 2026
23b766c
fix typo
estebank Jan 18, 2026
b534229
remove commented out code
estebank Jan 19, 2026
6c8eee8
reword span label
estebank Jan 19, 2026
879633f
Change note to help
estebank Jan 19, 2026
8543404
Tweak span in E0599
estebank Jan 19, 2026
dffec20
Tweak help to unify formatting and wording
estebank Jan 19, 2026
c95210f
Do not suggest manual `impl Copy`
estebank Feb 1, 2026
6756561
fix test after rebase
estebank Feb 1, 2026
0ec83f4
Merge pull request #2014 from folkertdev/llvm-22-madd
sayantn Feb 2, 2026
b5d9b7f
escape symbol names in global asm
usamoi Feb 1, 2026
821f139
Revert "Revert "Use LLVM intrinsics for `madd` intrinsics""
folkertdev Feb 2, 2026
f4ce247
Merge pull request #2009 from folkertdev/aarch64-vld1-tests
folkertdev Feb 2, 2026
54641ef
add `vpmaddwd` tests back in
folkertdev Feb 2, 2026
8c404a7
Prepare for merging from rust-lang/rust
invalid-email-address Feb 5, 2026
32b93d1
Merge ref 'db3e99bbab28' from rust-lang/rust
invalid-email-address Feb 5, 2026
b4e2a84
Merge pull request #2021 from rust-lang/rustc-pull
folkertdev Feb 5, 2026
cfcf20f
Merge pull request #2018 from rust-lang/revert-2014-llvm-22-madd
folkertdev Feb 5, 2026
edeb02f
disable s390x vector intrinsics if softfloat is enabled
fneddy Feb 5, 2026
3cf999f
Merge pull request #2022 from fneddy/s390x_softfloat_abi
folkertdev Feb 5, 2026
bce8c00
Remove the 4 failing tests from rustdoc-gui
JonathanBrouwer Feb 6, 2026
de68f27
Rollup merge of #152174 - folkertdev:stdarch-sync-2026-02-05, r=folke…
jieyouxu Feb 6, 2026
7b821d1
Rollup merge of #151278 - estebank:issue-108894, r=davidtwco
jieyouxu Feb 6, 2026
4a1e87c
Rollup merge of #151955 - usamoi:escape, r=davidtwco
jieyouxu Feb 6, 2026
7afff45
Rollup merge of #152194 - JonathanBrouwer:fix-rustdoc-gui, r=jieyouxu
jieyouxu Feb 6, 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
50 changes: 44 additions & 6 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1256,7 +1256,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
self.suggest_cloning_inner(err, ty, expr);
}
} else if let ty::Adt(def, args) = ty.kind()
&& def.did().as_local().is_some()
&& let Some(local_did) = def.did().as_local()
&& def.variants().iter().all(|variant| {
variant
.fields
Expand All @@ -1266,12 +1266,50 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
{
let ty_span = self.infcx.tcx.def_span(def.did());
let mut span: MultiSpan = ty_span.into();
span.push_span_label(ty_span, "consider implementing `Clone` for this type");
span.push_span_label(expr.span, "you could clone this value");
err.span_note(
span,
format!("if `{ty}` implemented `Clone`, you could clone the value"),
let mut derive_clone = false;
self.infcx.tcx.for_each_relevant_impl(
self.infcx.tcx.lang_items().clone_trait().unwrap(),
ty,
|def_id| {
if self.infcx.tcx.is_automatically_derived(def_id) {
derive_clone = true;
span.push_span_label(
self.infcx.tcx.def_span(def_id),
"derived `Clone` adds implicit bounds on type parameters",
);
if let Some(generics) = self.infcx.tcx.hir_get_generics(local_did) {
for param in generics.params {
if let hir::GenericParamKind::Type { .. } = param.kind {
span.push_span_label(
param.span,
format!(
"introduces an implicit `{}: Clone` bound",
param.name.ident()
),
);
}
}
}
}
},
);
let msg = if !derive_clone {
span.push_span_label(
ty_span,
format!(
"consider {}implementing `Clone` for this type",
if derive_clone { "manually " } else { "" }
),
);
format!("if `{ty}` implemented `Clone`, you could clone the value")
} else {
format!("if all bounds were met, you could clone the value")
};
span.push_span_label(expr.span, "you could clone this value");
err.span_note(span, msg);
if derive_clone {
err.help("consider manually implementing `Clone` to avoid undesired bounds");
}
} else if let ty::Param(param) = ty.kind()
&& let Some(_clone_trait_def) = self.infcx.tcx.lang_items().clone_trait()
&& let generics = self.infcx.tcx.generics_of(self.mir_def_id())
Expand Down
21 changes: 11 additions & 10 deletions compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -638,27 +638,27 @@ impl<'a> TraitDef<'a> {
GenericParamKind::Type { .. } => {
// Extra restrictions on the generics parameters to the
// type being derived upon.
let span = param.ident.span.with_ctxt(ctxt);
let bounds: Vec<_> = self
.additional_bounds
.iter()
.map(|p| {
cx.trait_bound(
p.to_path(cx, self.span, type_ident, generics),
self.is_const,
)
cx.trait_bound(p.to_path(cx, span, type_ident, generics), self.is_const)
})
.chain(
// Add a bound for the current trait.
self.skip_path_as_bound
.not()
.then(|| cx.trait_bound(trait_path.clone(), self.is_const)),
self.skip_path_as_bound.not().then(|| {
let mut trait_path = trait_path.clone();
trait_path.span = span;
cx.trait_bound(trait_path, self.is_const)
}),
)
.chain({
// Add a `Copy` bound if required.
if is_packed && self.needs_copy_as_bound_if_packed {
let p = deriving::path_std!(marker::Copy);
Some(cx.trait_bound(
p.to_path(cx, self.span, type_ident, generics),
p.to_path(cx, span, type_ident, generics),
self.is_const,
))
} else {
Expand All @@ -671,7 +671,7 @@ impl<'a> TraitDef<'a> {
)
.collect();

cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, bounds, None)
cx.typaram(span, param.ident, bounds, None)
}
GenericParamKind::Const { ty, span, .. } => {
let const_nodefault_kind = GenericParamKind::Const {
Expand Down Expand Up @@ -791,7 +791,8 @@ impl<'a> TraitDef<'a> {
.collect();

// Create the type of `self`.
let path = cx.path_all(self.span, false, vec![type_ident], self_params);
let path =
cx.path_all(type_ident.span.with_ctxt(ctxt), false, vec![type_ident], self_params);
let self_type = cx.ty_path(path);
let rustc_const_unstable =
cx.path_ident(self.span, Ident::new(sym::rustc_const_unstable, self.span));
Expand Down
45 changes: 42 additions & 3 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
for piece in template {
match *piece {
InlineAsmTemplatePiece::String(ref s) => template_str.push_str(s),
InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span: _ } => {
InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span } => {
match operands[operand_idx] {
GlobalAsmOperandRef::Const { ref string } => {
// Const operands get injected directly into the
Expand All @@ -414,7 +414,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
llvm::LLVMRustGetMangledName(llval, s);
})
.expect("symbol is not valid UTF-8");
template_str.push_str(&symbol);
template_str.push_str(&escape_symbol_name(self, symbol, span));
}
GlobalAsmOperandRef::SymStatic { def_id } => {
let llval = self
Expand All @@ -428,7 +428,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
llvm::LLVMRustGetMangledName(llval, s);
})
.expect("symbol is not valid UTF-8");
template_str.push_str(&symbol);
template_str.push_str(&escape_symbol_name(self, symbol, span));
}
}
}
Expand Down Expand Up @@ -1390,3 +1390,42 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
_ => layout.llvm_type(cx),
}
}

fn escape_symbol_name<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, symbol: String, span: Span) -> String {
use rustc_target::spec::{Arch, BinaryFormat};
if !symbol.is_empty()
&& symbol.chars().all(|c| matches!(c, '0'..='9' | 'A'..='Z' | 'a'..='z' | '_' | '$' | '.'))
{
return symbol;
}
if cx.tcx.sess.target.binary_format == BinaryFormat::Xcoff {
cx.tcx.sess.dcx().span_fatal(
span,
format!(
"symbol escaping is not supported for the binary format {}",
cx.tcx.sess.target.binary_format
),
);
}
if cx.tcx.sess.target.arch == Arch::Nvptx64 {
cx.tcx.sess.dcx().span_fatal(
span,
format!(
"symbol escaping is not supported for the architecture {}",
cx.tcx.sess.target.arch
),
);
}
let mut escaped_symbol = String::new();
escaped_symbol.push('\"');
for c in symbol.chars() {
match c {
'\n' => escaped_symbol.push_str("\\\n"),
'"' => escaped_symbol.push_str("\\\""),
'\\' => escaped_symbol.push_str("\\\\"),
c => escaped_symbol.push(c),
}
}
escaped_symbol.push('\"');
escaped_symbol
}
11 changes: 8 additions & 3 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// ignore-tidy-filelength
use std::borrow::Cow;
use std::fmt;
use std::ops::Not;

use rustc_abi::ExternAbi;
use rustc_ast::attr::AttributeExt;
Expand Down Expand Up @@ -1012,10 +1013,14 @@ impl<'hir> Generics<'hir> {

span_for_parentheses.map_or_else(
|| {
// We include bounds that come from a `#[derive(_)]` but point at the user's code,
// as we use this method to get a span appropriate for suggestions.
// We include bounds that come from a `#[derive(_)]` but point at the user's
// code, as we use this method to get a span appropriate for suggestions.
let bs = bound.span();
bs.can_be_used_for_suggestions().then(|| (bs.shrink_to_hi(), None))
// We use `from_expansion` instead of `can_be_used_for_suggestions` because
// the trait bound from imperfect derives do point at the type parameter,
// but expanded to a where clause, so we want to ignore those. This is only
// true for derive intrinsics.
bs.from_expansion().not().then(|| (bs.shrink_to_hi(), None))
},
|span| Some((span.shrink_to_hi(), Some(span.shrink_to_lo()))),
)
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ hir_analysis_copy_impl_on_non_adt =
hir_analysis_copy_impl_on_type_with_dtor =
the trait `Copy` cannot be implemented for this type; the type has a destructor
.label = `Copy` not allowed on types with destructors
.note = destructor declared here

hir_analysis_cross_crate_traits = cross-crate traits with a default impl, like `{$traits}`, can only be implemented for a struct/enum type, not `{$self_ty}`
.label = can't implement cross-crate trait with a default impl for non-struct/enum type
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_hir_analysis/src/coherence/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,10 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
Err(tcx.dcx().emit_err(errors::CopyImplOnNonAdt { span }))
}
Err(CopyImplementationError::HasDestructor) => {
Err(CopyImplementationError::HasDestructor(did)) => {
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
Err(tcx.dcx().emit_err(errors::CopyImplOnTypeWithDtor { span }))
let impl_ = tcx.def_span(did);
Err(tcx.dcx().emit_err(errors::CopyImplOnTypeWithDtor { span, impl_ }))
}
Err(CopyImplementationError::HasUnsafeFields) => {
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ pub(crate) struct CopyImplOnTypeWithDtor {
#[primary_span]
#[label]
pub span: Span,
#[note]
pub impl_: Span,
}

#[derive(Diagnostic)]
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
if span.can_be_used_for_suggestions()
&& poly_trait_ref.trait_ref.trait_def_id().is_some()
&& !self.maybe_suggest_impl_trait(span, hir_id, hir_bounds, &mut diag)
&& !self.maybe_suggest_dyn_trait(hir_id, sugg, &mut diag)
&& !self.maybe_suggest_dyn_trait(hir_id, span, sugg, &mut diag)
{
self.maybe_suggest_add_generic_impl_trait(span, hir_id, &mut diag);
}
Expand Down Expand Up @@ -750,10 +750,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
fn maybe_suggest_dyn_trait(
&self,
hir_id: hir::HirId,
span: Span,
sugg: Vec<(Span, String)>,
diag: &mut Diag<'_>,
) -> bool {
let tcx = self.tcx();
if span.in_derive_expansion() {
return false;
}

// Look at the direct HIR parent, since we care about the relationship between
// the type and the thing that directly encloses it.
Expand Down
95 changes: 83 additions & 12 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1932,25 +1932,94 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None,
);
} else {
let mut suggest_derive = true;
if let Some(errors) =
self.type_implements_trait_shallow(clone_trait_did, expected_ty, self.param_env)
{
let manually_impl = "consider manually implementing `Clone` to avoid the \
implicit type parameter bounds";
match &errors[..] {
[] => {}
[error] => {
diag.help(format!(
"`Clone` is not implemented because the trait bound `{}` is \
not satisfied",
error.obligation.predicate,
));
let msg = "`Clone` is not implemented because a trait bound is not \
satisfied";
if let traits::ObligationCauseCode::ImplDerived(data) =
error.obligation.cause.code()
{
let mut span: MultiSpan = data.span.into();
if self.tcx.is_automatically_derived(data.impl_or_alias_def_id) {
span.push_span_label(
data.span,
format!(
"derive introduces an implicit `{}` bound",
error.obligation.predicate
),
);
}
diag.span_help(span, msg);
if self.tcx.is_automatically_derived(data.impl_or_alias_def_id)
&& data.impl_or_alias_def_id.is_local()
{
diag.help(manually_impl);
suggest_derive = false;
}
} else {
diag.help(msg);
}
}
_ => {
diag.help(format!(
"`Clone` is not implemented because the following trait bounds \
could not be satisfied: {}",
listify(&errors, |e| format!("`{}`", e.obligation.predicate))
.unwrap(),
));
let unsatisfied_bounds: Vec<_> = errors
.iter()
.filter_map(|error| match error.obligation.cause.code() {
traits::ObligationCauseCode::ImplDerived(data) => {
let pre = if self
.tcx
.is_automatically_derived(data.impl_or_alias_def_id)
{
"derive introduces an implicit "
} else {
""
};
Some((
data.span,
format!(
"{pre}unsatisfied trait bound `{}`",
error.obligation.predicate
),
))
}
_ => None,
})
.collect();
let msg = "`Clone` is not implemented because the some trait bounds \
could not be satisfied";
if errors.len() == unsatisfied_bounds.len() {
let mut unsatisfied_bounds_spans: MultiSpan = unsatisfied_bounds
.iter()
.map(|(span, _)| *span)
.collect::<Vec<Span>>()
.into();
for (span, label) in unsatisfied_bounds {
unsatisfied_bounds_spans.push_span_label(span, label);
}
diag.span_help(unsatisfied_bounds_spans, msg);
if errors.iter().all(|error| match error.obligation.cause.code() {
traits::ObligationCauseCode::ImplDerived(data) => {
self.tcx.is_automatically_derived(data.impl_or_alias_def_id)
&& data.impl_or_alias_def_id.is_local()
}
_ => false,
}) {
diag.help(manually_impl);
suggest_derive = false;
}
} else {
diag.help(format!(
"{msg}: {}",
listify(&errors, |e| format!("`{}`", e.obligation.predicate))
.unwrap(),
));
}
}
}
for error in errors {
Expand All @@ -1968,7 +2037,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
}
self.suggest_derive(diag, &vec![(trait_ref.upcast(self.tcx), None, None)]);
if suggest_derive {
self.suggest_derive(diag, &vec![(trait_ref.upcast(self.tcx), None, None)]);
}
}
}
}
Expand Down
Loading
Loading