Skip to content

Commit 5e71913

Browse files
committed
Auto merge of #115817 - fee1-dead-contrib:fix-codegen, r=oli-obk
treat host effect params as erased in codegen This fixes the changes brought to codegen tests when effect params are added to libcore, by not attempting to monomorphize functions that get the host param by being `const fn`. r? `@oli-obk`
2 parents df63c5f + a0a801c commit 5e71913

File tree

17 files changed

+71
-41
lines changed

17 files changed

+71
-41
lines changed

Diff for: compiler/rustc_codegen_gcc/src/callee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>)
100100
// whether we are sharing generics or not. The important thing here is
101101
// that the visibility we apply to the declaration is the same one that
102102
// has been applied to the definition (wherever that definition may be).
103-
let is_generic = instance.args.non_erasable_generics().next().is_some();
103+
let is_generic = instance.args.non_erasable_generics(tcx, instance.def_id()).next().is_some();
104104

105105
if is_generic {
106106
// This is a monomorphization. Its expected visibility depends

Diff for: compiler/rustc_codegen_llvm/src/callee.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
9595
unsafe {
9696
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
9797

98-
let is_generic = instance.args.non_erasable_generics().next().is_some();
98+
let is_generic =
99+
instance.args.non_erasable_generics(tcx, instance.def_id()).next().is_some();
99100

100101
if is_generic {
101102
// This is a monomorphization. Its expected visibility depends

Diff for: compiler/rustc_codegen_llvm/src/debuginfo/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
349349
type_names::push_generic_params(
350350
tcx,
351351
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args),
352+
enclosing_fn_def_id,
352353
&mut name,
353354
);
354355

Diff for: compiler/rustc_codegen_ssa/src/back/symbol_export.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ fn exported_symbols_provider_local(
334334

335335
match *mono_item {
336336
MonoItem::Fn(Instance { def: InstanceDef::Item(def), args }) => {
337-
if args.non_erasable_generics().next().is_some() {
337+
if args.non_erasable_generics(tcx, def).next().is_some() {
338338
let symbol = ExportedSymbol::Generic(def, args);
339339
symbols.push((
340340
symbol,
@@ -346,10 +346,10 @@ fn exported_symbols_provider_local(
346346
));
347347
}
348348
}
349-
MonoItem::Fn(Instance { def: InstanceDef::DropGlue(_, Some(ty)), args }) => {
349+
MonoItem::Fn(Instance { def: InstanceDef::DropGlue(def_id, Some(ty)), args }) => {
350350
// A little sanity-check
351351
debug_assert_eq!(
352-
args.non_erasable_generics().next(),
352+
args.non_erasable_generics(tcx, def_id).next(),
353353
Some(GenericArgKind::Type(ty))
354354
);
355355
symbols.push((

Diff for: compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs

+24-12
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,14 @@ fn push_debuginfo_type_name<'tcx>(
106106
ty_and_layout,
107107
&|output, visited| {
108108
push_item_name(tcx, def.did(), true, output);
109-
push_generic_params_internal(tcx, args, output, visited);
109+
push_generic_params_internal(tcx, args, def.did(), output, visited);
110110
},
111111
output,
112112
visited,
113113
);
114114
} else {
115115
push_item_name(tcx, def.did(), qualified, output);
116-
push_generic_params_internal(tcx, args, output, visited);
116+
push_generic_params_internal(tcx, args, def.did(), output, visited);
117117
}
118118
}
119119
ty::Tuple(component_types) => {
@@ -237,8 +237,13 @@ fn push_debuginfo_type_name<'tcx>(
237237
let principal =
238238
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), principal);
239239
push_item_name(tcx, principal.def_id, qualified, output);
240-
let principal_has_generic_params =
241-
push_generic_params_internal(tcx, principal.args, output, visited);
240+
let principal_has_generic_params = push_generic_params_internal(
241+
tcx,
242+
principal.args,
243+
principal.def_id,
244+
output,
245+
visited,
246+
);
242247

243248
let projection_bounds: SmallVec<[_; 4]> = trait_data
244249
.projection_bounds()
@@ -516,7 +521,13 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
516521
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), trait_ref);
517522
push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name);
518523
visited.clear();
519-
push_generic_params_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited);
524+
push_generic_params_internal(
525+
tcx,
526+
trait_ref.args,
527+
trait_ref.def_id,
528+
&mut vtable_name,
529+
&mut visited,
530+
);
520531
} else {
521532
vtable_name.push('_');
522533
}
@@ -610,20 +621,20 @@ fn push_unqualified_item_name(
610621
fn push_generic_params_internal<'tcx>(
611622
tcx: TyCtxt<'tcx>,
612623
args: GenericArgsRef<'tcx>,
624+
def_id: DefId,
613625
output: &mut String,
614626
visited: &mut FxHashSet<Ty<'tcx>>,
615627
) -> bool {
616-
if args.non_erasable_generics().next().is_none() {
628+
debug_assert_eq!(args, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args));
629+
let mut args = args.non_erasable_generics(tcx, def_id).peekable();
630+
if args.peek().is_none() {
617631
return false;
618632
}
619-
620-
debug_assert_eq!(args, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args));
621-
622633
let cpp_like_debuginfo = cpp_like_debuginfo(tcx);
623634

624635
output.push('<');
625636

626-
for type_parameter in args.non_erasable_generics() {
637+
for type_parameter in args {
627638
match type_parameter {
628639
GenericArgKind::Type(type_parameter) => {
629640
push_debuginfo_type_name(tcx, type_parameter, true, output, visited);
@@ -689,11 +700,12 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
689700
pub fn push_generic_params<'tcx>(
690701
tcx: TyCtxt<'tcx>,
691702
args: GenericArgsRef<'tcx>,
703+
def_id: DefId,
692704
output: &mut String,
693705
) {
694706
let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name");
695707
let mut visited = FxHashSet::default();
696-
push_generic_params_internal(tcx, args, output, &mut visited);
708+
push_generic_params_internal(tcx, args, def_id, output, &mut visited);
697709
}
698710

699711
fn push_closure_or_generator_name<'tcx>(
@@ -736,7 +748,7 @@ fn push_closure_or_generator_name<'tcx>(
736748
// Truncate the args to the length of the above generics. This will cut off
737749
// anything closure- or generator-specific.
738750
let args = args.truncate_to(tcx, generics);
739-
push_generic_params_internal(tcx, args, output, visited);
751+
push_generic_params_internal(tcx, args, enclosing_fn_def_id, output, visited);
740752
}
741753

742754
fn push_close_angle_bracket(cpp_like_debuginfo: bool, output: &mut String) {

Diff for: compiler/rustc_infer/src/infer/error_reporting/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1642,8 +1642,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
16421642
ValuePairs::Terms(infer::ExpectedFound { expected, found }) => {
16431643
match (expected.unpack(), found.unpack()) {
16441644
(ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => {
1645-
let is_simple_err =
1646-
expected.is_simple_text() && found.is_simple_text();
1645+
let is_simple_err = expected.is_simple_text(self.tcx)
1646+
&& found.is_simple_text(self.tcx);
16471647
OpaqueTypesVisitor::visit_expected_found(
16481648
self.tcx, expected, found, span,
16491649
)
@@ -1885,7 +1885,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
18851885
}
18861886
s
18871887
};
1888-
if !(values.expected.is_simple_text() && values.found.is_simple_text())
1888+
if !(values.expected.is_simple_text(self.tcx) && values.found.is_simple_text(self.tcx))
18891889
|| (exp_found.is_some_and(|ef| {
18901890
// This happens when the type error is a subset of the expectation,
18911891
// like when you have two references but one is `usize` and the other

Diff for: compiler/rustc_middle/src/mir/mono.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,11 @@ impl<'tcx> MonoItem<'tcx> {
7878
}
7979
}
8080

81-
pub fn is_generic_fn(&self) -> bool {
82-
match *self {
83-
MonoItem::Fn(ref instance) => instance.args.non_erasable_generics().next().is_some(),
81+
pub fn is_generic_fn(&self, tcx: TyCtxt<'tcx>) -> bool {
82+
match self {
83+
MonoItem::Fn(instance) => {
84+
instance.args.non_erasable_generics(tcx, instance.def_id()).next().is_some()
85+
}
8486
MonoItem::Static(..) | MonoItem::GlobalAsm(..) => false,
8587
}
8688
}

Diff for: compiler/rustc_middle/src/ty/diagnostics.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,10 @@ impl<'tcx> Ty<'tcx> {
7070
/// description in error messages. This is used in the primary span label. Beyond what
7171
/// `is_simple_ty` includes, it also accepts ADTs with no type arguments and references to
7272
/// ADTs with no type arguments.
73-
pub fn is_simple_text(self) -> bool {
73+
pub fn is_simple_text(self, tcx: TyCtxt<'tcx>) -> bool {
7474
match self.kind() {
75-
Adt(_, args) => args.non_erasable_generics().next().is_none(),
76-
Ref(_, ty, _) => ty.is_simple_text(),
75+
Adt(def, args) => args.non_erasable_generics(tcx, def.did()).next().is_none(),
76+
Ref(_, ty, _) => ty.is_simple_text(tcx),
7777
_ => self.is_simple_ty(),
7878
}
7979
}

Diff for: compiler/rustc_middle/src/ty/generic_args.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -379,12 +379,17 @@ impl<'tcx> GenericArgs<'tcx> {
379379
self.iter().filter_map(|k| k.as_const())
380380
}
381381

382+
/// Returns generic arguments that are not lifetimes or host effect params.
382383
#[inline]
383384
pub fn non_erasable_generics(
384385
&'tcx self,
386+
tcx: TyCtxt<'tcx>,
387+
def_id: DefId,
385388
) -> impl DoubleEndedIterator<Item = GenericArgKind<'tcx>> + 'tcx {
386-
self.iter().filter_map(|k| match k.unpack() {
387-
GenericArgKind::Lifetime(_) => None,
389+
let generics = tcx.generics_of(def_id);
390+
self.iter().enumerate().filter_map(|(i, k)| match k.unpack() {
391+
_ if Some(i) == generics.host_effect_index => None,
392+
ty::GenericArgKind::Lifetime(_) => None,
388393
generic => Some(generic),
389394
})
390395
}

Diff for: compiler/rustc_middle/src/ty/generics.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,12 @@ impl<'tcx> Generics {
212212
pub fn own_requires_monomorphization(&self) -> bool {
213213
for param in &self.params {
214214
match param.kind {
215-
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
215+
GenericParamDefKind::Type { .. }
216+
| GenericParamDefKind::Const { is_host_effect: false, .. } => {
216217
return true;
217218
}
218-
GenericParamDefKind::Lifetime => {}
219+
GenericParamDefKind::Lifetime
220+
| GenericParamDefKind::Const { is_host_effect: true, .. } => {}
219221
}
220222
}
221223
false

Diff for: compiler/rustc_middle/src/ty/instance.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ impl<'tcx> Instance<'tcx> {
139139
}
140140

141141
// If this a non-generic instance, it cannot be a shared monomorphization.
142-
self.args.non_erasable_generics().next()?;
142+
self.args.non_erasable_generics(tcx, self.def_id()).next()?;
143143

144144
match self.def {
145145
InstanceDef::Item(def) => tcx
@@ -344,6 +344,7 @@ impl<'tcx> Instance<'tcx> {
344344
pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> {
345345
let args = GenericArgs::for_item(tcx, def_id, |param, _| match param.kind {
346346
ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
347+
ty::GenericParamDefKind::Const { is_host_effect: true, .. } => tcx.consts.true_.into(),
347348
ty::GenericParamDefKind::Type { .. } => {
348349
bug!("Instance::mono: {:?} has type parameters", def_id)
349350
}

Diff for: compiler/rustc_mir_transform/src/inline.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,12 @@ impl<'tcx> Inliner<'tcx> {
390390

391391
// Reachability pass defines which functions are eligible for inlining. Generally inlining
392392
// other functions is incorrect because they could reference symbols that aren't exported.
393-
let is_generic = callsite.callee.args.non_erasable_generics().next().is_some();
393+
let is_generic = callsite
394+
.callee
395+
.args
396+
.non_erasable_generics(self.tcx, callsite.callee.def_id())
397+
.next()
398+
.is_some();
394399
if !is_generic && !callee_attrs.requests_inline() {
395400
return Err("not exported");
396401
}

Diff for: compiler/rustc_monomorphize/src/collector.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ fn collect_items_rec<'tcx>(
459459
// Check for PMEs and emit a diagnostic if one happened. To try to show relevant edges of the
460460
// mono item graph.
461461
if tcx.sess.diagnostic().err_count() > error_count
462-
&& starting_item.node.is_generic_fn()
462+
&& starting_item.node.is_generic_fn(tcx)
463463
&& starting_item.node.is_user_defined()
464464
{
465465
let formatted_item = with_no_trimmed_paths!(starting_item.node.to_string());
@@ -1315,6 +1315,7 @@ fn create_mono_items_for_default_impls<'tcx>(
13151315
// it, to validate whether or not the impl is legal to instantiate at all.
13161316
let only_region_params = |param: &ty::GenericParamDef, _: &_| match param.kind {
13171317
GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
1318+
GenericParamDefKind::Const { is_host_effect: true, .. } => tcx.consts.true_.into(),
13181319
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
13191320
unreachable!(
13201321
"`own_requires_monomorphization` check means that \

Diff for: compiler/rustc_monomorphize/src/partitioning.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ where
221221
}
222222

223223
let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item);
224-
let is_volatile = is_incremental_build && mono_item.is_generic_fn();
224+
let is_volatile = is_incremental_build && mono_item.is_generic_fn(cx.tcx);
225225

226226
let cgu_name = match characteristic_def_id {
227227
Some(def_id) => compute_codegen_unit_name(
@@ -801,7 +801,7 @@ fn mono_item_visibility<'tcx>(
801801
return Visibility::Hidden;
802802
}
803803

804-
let is_generic = instance.args.non_erasable_generics().next().is_some();
804+
let is_generic = instance.args.non_erasable_generics(tcx, def_id).next().is_some();
805805

806806
// Upstream `DefId` instances get different handling than local ones.
807807
let Some(def_id) = def_id.as_local() else {

Diff for: compiler/rustc_symbol_mangling/src/lib.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
108108
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
109109
use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
110110
use rustc_middle::query::Providers;
111-
use rustc_middle::ty::GenericArgsRef;
112111
use rustc_middle::ty::{self, Instance, TyCtxt};
113112
use rustc_session::config::SymbolManglingVersion;
114113

@@ -144,7 +143,7 @@ fn symbol_name_provider<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> ty
144143
// This closure determines the instantiating crate for instances that
145144
// need an instantiating-crate-suffix for their symbol name, in order
146145
// to differentiate between local copies.
147-
if is_generic(instance.args) {
146+
if is_generic(instance, tcx) {
148147
// For generics we might find re-usable upstream instances. If there
149148
// is one, we rely on the symbol being instantiated locally.
150149
instance.upstream_monomorphization(tcx).unwrap_or(LOCAL_CRATE)
@@ -246,7 +245,7 @@ fn compute_symbol_name<'tcx>(
246245
// the ID of the instantiating crate. This avoids symbol conflicts
247246
// in case the same instances is emitted in two crates of the same
248247
// project.
249-
let avoid_cross_crate_conflicts = is_generic(args) || is_globally_shared_function;
248+
let avoid_cross_crate_conflicts = is_generic(instance, tcx) || is_globally_shared_function;
250249

251250
let instantiating_crate = avoid_cross_crate_conflicts.then(compute_instantiating_crate);
252251

@@ -278,6 +277,6 @@ fn compute_symbol_name<'tcx>(
278277
symbol
279278
}
280279

281-
fn is_generic(args: GenericArgsRef<'_>) -> bool {
282-
args.non_erasable_generics().next().is_some()
280+
fn is_generic<'tcx>(instance: Instance<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
281+
instance.args.non_erasable_generics(tcx, instance.def_id()).next().is_some()
283282
}

Diff for: compiler/rustc_ty_utils/src/instance.rs

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ fn resolve_instance<'tcx>(
5555
}
5656
} else {
5757
debug!(" => free item");
58+
// FIXME(effects): we may want to erase the effect param if that is present on this item.
5859
ty::InstanceDef::Item(def_id)
5960
};
6061

Diff for: src/tools/clippy/clippy_lints/src/derive.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h
343343
// If the current self type doesn't implement Copy (due to generic constraints), search to see if
344344
// there's a Copy impl for any instance of the adt.
345345
if !is_copy(cx, ty) {
346-
if ty_subs.non_erasable_generics().next().is_some() {
346+
if ty_subs.non_erasable_generics(cx.tcx, ty_adt.did()).next().is_some() {
347347
let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(&copy_id).map_or(false, |impls| {
348348
impls.iter().any(|&id| {
349349
matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _)

0 commit comments

Comments
 (0)