Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
46a474b
ci: add runners for vanilla LLVM 21
cuviper Oct 28, 2025
3a02b35
Add tests to demonstrate explicit tail call bug
InvalidPathException Oct 29, 2025
52959a8
Fix musttail returns for cast/indirect ABIs
InvalidPathException Oct 29, 2025
973ab7d
Make "add param to inner item" suggestion verbose
estebank Nov 1, 2025
f693870
Point at inner item when using outer item type param
estebank Nov 1, 2025
8fdd347
Point at inner item on E0401 generated by hir_typeck
estebank Nov 1, 2025
44ece2e
Point at inner item when using outer const param
estebank Nov 1, 2025
86d7556
Pass `DiagMetadata` through in more cases
estebank Nov 1, 2025
72c9762
Fix CI failure by ignoring wasm target and cross compile run
InvalidPathException Nov 2, 2025
964d3af
Move a special case for rust_eh_personality from reachable_non_generi…
bjorn3 Oct 29, 2025
e8d88c0
Remove special case for the panic runtime from reachable_non_generics
bjorn3 Oct 29, 2025
c962b95
review comments
estebank Nov 2, 2025
f171c41
Do not suggest adding type param to fn delegation
estebank Nov 2, 2025
528137f
Point at non-const trait impl when encountering unmet `[const]` bound
estebank Jul 18, 2025
a08bdff
Point at non-const trait when using them in const context
estebank Jul 19, 2025
eb79e68
Only suggest `#[const_trait]` only on local traits
estebank Jul 19, 2025
9bc814c
Point at the enclosing const context
estebank Jul 19, 2025
bf45da7
Account for `#![feature(const_trait_impl)]` state
estebank Jul 19, 2025
a2c3913
review comments
estebank Jul 23, 2025
74b7592
fix rebase
estebank Oct 31, 2025
10e445c
Rollup merge of #144194 - estebank:const-traits, r=davidtwco
Zalathar Nov 3, 2025
a44b547
Rollup merge of #148232 - cuviper:ci-llvm-21, r=Mark-Simulacrum
Zalathar Nov 3, 2025
f8ff304
Rollup merge of #148240 - InvalidPathException:master, r=WaffleLapkin
Zalathar Nov 3, 2025
4b28573
Rollup merge of #148247 - bjorn3:minor_symbol_export_cleanup, r=Waffl…
Zalathar Nov 3, 2025
c10e1e4
Rollup merge of #148370 - estebank:outer-param, r=JonathanBrouwer
Zalathar Nov 3, 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
3 changes: 3 additions & 0 deletions compiler/rustc_codegen_llvm/src/back/lto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ fn prepare_lto(
// should have default visibility.
symbols_below_threshold.push(c"__llvm_profile_counter_bias".to_owned());

// LTO seems to discard this otherwise under certain circumstances.
symbols_below_threshold.push(c"rust_eh_personality".to_owned());

// If we're performing LTO for the entire crate graph, then for each of our
// upstream dependencies, find the corresponding rlib and load the bitcode
// from the archive.
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_hir::def_id::DefId;
use rustc_middle::bug;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::ty::layout::{
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers,
Expand Down Expand Up @@ -1458,10 +1457,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {

match &fn_abi.ret.mode {
PassMode::Ignore | PassMode::Indirect { .. } => self.ret_void(),
PassMode::Direct(_) | PassMode::Pair { .. } => self.ret(call),
mode @ PassMode::Cast { .. } => {
bug!("Encountered `PassMode::{mode:?}` during codegen")
}
PassMode::Direct(_) | PassMode::Pair { .. } | PassMode::Cast { .. } => self.ret(call),
}
}

Expand Down
24 changes: 8 additions & 16 deletions compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S
return Default::default();
}

// Check to see if this crate is a "special runtime crate". These
// crates, implementation details of the standard library, typically
// have a bunch of `pub extern` and `#[no_mangle]` functions as the
// ABI between them. We don't want their symbols to have a `C`
// export level, however, as they're just implementation details.
// Down below we'll hardwire all of the symbols to the `Rust` export
// level instead.
let special_runtime_crate =
tcx.is_panic_runtime(LOCAL_CRATE) || tcx.is_compiler_builtins(LOCAL_CRATE);
let is_compiler_builtins = tcx.is_compiler_builtins(LOCAL_CRATE);

let mut reachable_non_generics: DefIdMap<_> = tcx
.reachable_set(())
Expand Down Expand Up @@ -104,11 +96,12 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S
if tcx.cross_crate_inlinable(def_id) { None } else { Some(def_id) }
})
.map(|def_id| {
// We won't link right if this symbol is stripped during LTO.
let name = tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())).name;
let used = name == "rust_eh_personality";

let export_level = if special_runtime_crate {
let export_level = if is_compiler_builtins {
// We don't want to export compiler-builtins symbols from any
// dylibs, even rust dylibs. Unlike all other crates it gets
// duplicated in every linker invocation and it may otherwise
// unintentionally override definitions of these symbols by
// libgcc or compiler-rt for C code.
SymbolExportLevel::Rust
} else {
symbol_export_level(tcx, def_id.to_def_id())
Expand All @@ -131,8 +124,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S
SymbolExportKind::Text
},
used: codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER)
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
|| used,
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER),
rustc_std_internal_symbol: codegen_attrs
.flags
.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL),
Expand Down
12 changes: 11 additions & 1 deletion compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1063,7 +1063,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let return_dest = self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs);
target.map(|target| (return_dest, target))
}
CallKind::Tail => None,
CallKind::Tail => {
if fn_abi.ret.is_indirect() {
match self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs) {
ReturnDest::Nothing => {}
_ => bug!(
"tail calls to functions with indirect returns cannot store into a destination"
),
}
}
None
}
};

// Split the rust-call tupled arguments off.
Expand Down
77 changes: 65 additions & 12 deletions compiler/rustc_const_eval/src/check_consts/ops.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Concrete error types for all operations which may be invalid in a certain const context.

use hir::{ConstContext, LangItem};
use rustc_errors::Diag;
use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diag, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt;
Expand All @@ -11,8 +11,8 @@ use rustc_middle::mir::CallSource;
use rustc_middle::span_bug;
use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
use rustc_middle::ty::{
self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty,
suggest_constraining_type_param,
self, AssocContainer, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef,
Ty, suggest_constraining_type_param,
};
use rustc_session::parse::add_feature_diagnostics;
use rustc_span::{BytePos, Pos, Span, Symbol, sym};
Expand Down Expand Up @@ -352,18 +352,71 @@ fn build_error_for_const_call<'tcx>(
non_or_conditionally,
})
}
_ => ccx.dcx().create_err(errors::NonConstFnCall {
span,
def_descr: ccx.tcx.def_descr(callee),
def_path_str: ccx.tcx.def_path_str_with_args(callee, args),
kind: ccx.const_kind(),
non_or_conditionally,
}),
_ => {
let def_descr = ccx.tcx.def_descr(callee);
let mut err = ccx.dcx().create_err(errors::NonConstFnCall {
span,
def_descr,
def_path_str: ccx.tcx.def_path_str_with_args(callee, args),
kind: ccx.const_kind(),
non_or_conditionally,
});
if let Some(item) = ccx.tcx.opt_associated_item(callee) {
if let AssocContainer::Trait = item.container
&& let parent = item.container_id(ccx.tcx)
&& !ccx.tcx.is_const_trait(parent)
{
let assoc_span = ccx.tcx.def_span(callee);
let assoc_name = ccx.tcx.item_name(callee);
let mut span: MultiSpan = ccx.tcx.def_span(parent).into();
span.push_span_label(assoc_span, format!("this {def_descr} is not const"));
let trait_descr = ccx.tcx.def_descr(parent);
let trait_span = ccx.tcx.def_span(parent);
let trait_name = ccx.tcx.item_name(parent);
span.push_span_label(trait_span, format!("this {trait_descr} is not const"));
err.span_note(
span,
format!(
"{def_descr} `{assoc_name}` is not const because {trait_descr} \
`{trait_name}` is not const",
),
);
if parent.is_local() && ccx.tcx.sess.is_nightly_build() {
if !ccx.tcx.features().const_trait_impl() {
err.help(
"add `#![feature(const_trait_impl)]` to the crate attributes to \
enable `#[const_trait]`",
);
}
let indentation = ccx
.tcx
.sess
.source_map()
.indentation_before(trait_span)
.unwrap_or_default();
err.span_suggestion_verbose(
trait_span.shrink_to_lo(),
format!("consider making trait `{trait_name}` const"),
format!("#[const_trait]\n{indentation}"),
Applicability::MaybeIncorrect,
);
} else if !ccx.tcx.sess.is_nightly_build() {
err.help("const traits are not yet supported on stable Rust");
}
}
} else if ccx.tcx.constness(callee) != hir::Constness::Const {
let name = ccx.tcx.item_name(callee);
err.span_note(
ccx.tcx.def_span(callee),
format!("{def_descr} `{name}` is not const"),
);
}
err
}
};

err.note(format!(
"calls in {}s are limited to constant functions, \
tuple structs and tuple variants",
"calls in {}s are limited to constant functions, tuple structs and tuple variants",
ccx.const_kind(),
));

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir_typeck/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ hir_typeck_self_ctor_from_outer_item = can't reference `Self` constructor from o
.label = the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference
.suggestion = replace `Self` with the actual type
hir_typeck_self_ctor_from_outer_item_inner_item = `Self` used in this inner item
hir_typeck_slicing_suggestion = consider slicing here
hir_typeck_struct_expr_non_exhaustive =
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_hir_typeck/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,15 @@ pub(crate) struct SelfCtorFromOuterItem {
pub impl_span: Span,
#[subdiagnostic]
pub sugg: Option<ReplaceWithName>,
#[subdiagnostic]
pub item: Option<InnerItem>,
}

#[derive(Subdiagnostic)]
#[label(hir_typeck_self_ctor_from_outer_item_inner_item)]
pub(crate) struct InnerItem {
#[primary_span]
pub span: Span,
}

#[derive(LintDiagnostic)]
Expand All @@ -987,6 +996,8 @@ pub(crate) struct SelfCtorFromOuterItemLint {
pub impl_span: Span,
#[subdiagnostic]
pub sugg: Option<ReplaceWithName>,
#[subdiagnostic]
pub item: Option<InnerItem>,
}

#[derive(Subdiagnostic)]
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1094,11 +1094,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span: path_span,
name: self.tcx.item_name(def.did()).to_ident_string(),
});
let item = match self
.tcx
.hir_node_by_def_id(self.tcx.hir_get_parent_item(hir_id).def_id)
{
hir::Node::Item(item) => Some(errors::InnerItem {
span: item.kind.ident().map(|i| i.span).unwrap_or(item.span),
}),
_ => None,
};
if ty.raw.has_param() {
let guar = self.dcx().emit_err(errors::SelfCtorFromOuterItem {
span: path_span,
impl_span: tcx.def_span(impl_def_id),
sugg,
item,
});
return (Ty::new_error(self.tcx, guar), res);
} else {
Expand All @@ -1109,6 +1119,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
errors::SelfCtorFromOuterItemLint {
impl_span: tcx.def_span(impl_def_id),
sugg,
item,
},
);
}
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_resolve/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ resolve_generic_params_from_outer_item_const = a `const` is a separate item from
resolve_generic_params_from_outer_item_const_param = const parameter from outer item
resolve_generic_params_from_outer_item_inner_item = {$is_self ->
[true] `Self`
*[false] generic parameter
} used in this inner {$descr}
resolve_generic_params_from_outer_item_self_ty_alias = `Self` type implicitly declared here, by this `impl`
resolve_generic_params_from_outer_item_self_ty_param = can't use `Self` here
Expand Down
20 changes: 16 additions & 4 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use crate::errors::{
MaybeMissingMacroRulesName,
};
use crate::imports::{Import, ImportKind};
use crate::late::{PatternSource, Rib};
use crate::late::{DiagMetadata, PatternSource, Rib};
use crate::{
AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, BindingKey, Finalize,
ForwardGenericParamBanReason, HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module,
Expand Down Expand Up @@ -553,11 +553,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
resolution_error: ResolutionError<'ra>,
) -> Diag<'_> {
match resolution_error {
ResolutionError::GenericParamsFromOuterItem(
ResolutionError::GenericParamsFromOuterItem {
outer_res,
has_generic_params,
def_kind,
) => {
inner_item,
} => {
use errs::GenericParamsFromOuterItemLabel as Label;
let static_or_const = match def_kind {
DefKind::Static { .. } => {
Expand All @@ -575,6 +576,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
sugg: None,
static_or_const,
is_self,
item: inner_item.as_ref().map(|(span, kind)| {
errs::GenericParamsFromOuterItemInnerItem {
span: *span,
descr: kind.descr().to_string(),
}
}),
};

let sm = self.tcx.sess.source_map();
Expand Down Expand Up @@ -608,7 +615,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
};

if let HasGenericParams::Yes(span) = has_generic_params {
if let HasGenericParams::Yes(span) = has_generic_params
&& !matches!(inner_item, Some((_, ItemKind::Delegation(..))))
{
let name = self.tcx.item_name(def_id);
let (span, snippet) = if span.is_empty() {
let snippet = format!("<{name}>");
Expand Down Expand Up @@ -2401,6 +2410,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
module: Option<ModuleOrUniformRoot<'ra>>,
failed_segment_idx: usize,
ident: Ident,
diag_metadata: Option<&DiagMetadata<'_>>,
) -> (String, Option<Suggestion>) {
let is_last = failed_segment_idx == path.len() - 1;
let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
Expand Down Expand Up @@ -2506,6 +2516,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None,
&ribs[ns_to_try],
ignore_binding,
diag_metadata,
) {
// we found a locally-imported or available item/module
Some(LexicalScopeBinding::Item(binding)) => Some(binding),
Expand Down Expand Up @@ -2556,6 +2567,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None,
&ribs[ValueNS],
ignore_binding,
diag_metadata,
)
} else {
None
Expand Down
17 changes: 16 additions & 1 deletion compiler/rustc_resolve/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ pub(crate) struct GenericParamsFromOuterItem {
#[subdiagnostic]
pub(crate) static_or_const: Option<GenericParamsFromOuterItemStaticOrConst>,
pub(crate) is_self: bool,
#[subdiagnostic]
pub(crate) item: Option<GenericParamsFromOuterItemInnerItem>,
}

#[derive(Subdiagnostic)]
#[label(resolve_generic_params_from_outer_item_inner_item)]
pub(crate) struct GenericParamsFromOuterItemInnerItem {
#[primary_span]
pub(crate) span: Span,
pub(crate) descr: String,
}

#[derive(Subdiagnostic)]
Expand All @@ -47,7 +57,12 @@ pub(crate) enum GenericParamsFromOuterItemLabel {
}

#[derive(Subdiagnostic)]
#[suggestion(resolve_suggestion, code = "{snippet}", applicability = "maybe-incorrect")]
#[suggestion(
resolve_suggestion,
code = "{snippet}",
applicability = "maybe-incorrect",
style = "verbose"
)]
pub(crate) struct GenericParamsFromOuterItemSugg {
#[primary_span]
pub(crate) span: Span,
Expand Down
Loading
Loading