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`
This commit is contained in:
commit
5e71913156
17 changed files with 71 additions and 41 deletions
|
@ -100,7 +100,7 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>)
|
||||||
// whether we are sharing generics or not. The important thing here is
|
// whether we are sharing generics or not. The important thing here is
|
||||||
// that the visibility we apply to the declaration is the same one that
|
// that the visibility we apply to the declaration is the same one that
|
||||||
// has been applied to the definition (wherever that definition may be).
|
// has been applied to the definition (wherever that definition may be).
|
||||||
let is_generic = instance.args.non_erasable_generics().next().is_some();
|
let is_generic = instance.args.non_erasable_generics(tcx, instance.def_id()).next().is_some();
|
||||||
|
|
||||||
if is_generic {
|
if is_generic {
|
||||||
// This is a monomorphization. Its expected visibility depends
|
// This is a monomorphization. Its expected visibility depends
|
||||||
|
|
|
@ -95,7 +95,8 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
|
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
|
||||||
|
|
||||||
let is_generic = instance.args.non_erasable_generics().next().is_some();
|
let is_generic =
|
||||||
|
instance.args.non_erasable_generics(tcx, instance.def_id()).next().is_some();
|
||||||
|
|
||||||
if is_generic {
|
if is_generic {
|
||||||
// This is a monomorphization. Its expected visibility depends
|
// This is a monomorphization. Its expected visibility depends
|
||||||
|
|
|
@ -349,6 +349,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
type_names::push_generic_params(
|
type_names::push_generic_params(
|
||||||
tcx,
|
tcx,
|
||||||
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args),
|
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args),
|
||||||
|
enclosing_fn_def_id,
|
||||||
&mut name,
|
&mut name,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -334,7 +334,7 @@ fn exported_symbols_provider_local(
|
||||||
|
|
||||||
match *mono_item {
|
match *mono_item {
|
||||||
MonoItem::Fn(Instance { def: InstanceDef::Item(def), args }) => {
|
MonoItem::Fn(Instance { def: InstanceDef::Item(def), args }) => {
|
||||||
if args.non_erasable_generics().next().is_some() {
|
if args.non_erasable_generics(tcx, def).next().is_some() {
|
||||||
let symbol = ExportedSymbol::Generic(def, args);
|
let symbol = ExportedSymbol::Generic(def, args);
|
||||||
symbols.push((
|
symbols.push((
|
||||||
symbol,
|
symbol,
|
||||||
|
@ -346,10 +346,10 @@ fn exported_symbols_provider_local(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MonoItem::Fn(Instance { def: InstanceDef::DropGlue(_, Some(ty)), args }) => {
|
MonoItem::Fn(Instance { def: InstanceDef::DropGlue(def_id, Some(ty)), args }) => {
|
||||||
// A little sanity-check
|
// A little sanity-check
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
args.non_erasable_generics().next(),
|
args.non_erasable_generics(tcx, def_id).next(),
|
||||||
Some(GenericArgKind::Type(ty))
|
Some(GenericArgKind::Type(ty))
|
||||||
);
|
);
|
||||||
symbols.push((
|
symbols.push((
|
||||||
|
|
|
@ -106,14 +106,14 @@ fn push_debuginfo_type_name<'tcx>(
|
||||||
ty_and_layout,
|
ty_and_layout,
|
||||||
&|output, visited| {
|
&|output, visited| {
|
||||||
push_item_name(tcx, def.did(), true, output);
|
push_item_name(tcx, def.did(), true, output);
|
||||||
push_generic_params_internal(tcx, args, output, visited);
|
push_generic_params_internal(tcx, args, def.did(), output, visited);
|
||||||
},
|
},
|
||||||
output,
|
output,
|
||||||
visited,
|
visited,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
push_item_name(tcx, def.did(), qualified, output);
|
push_item_name(tcx, def.did(), qualified, output);
|
||||||
push_generic_params_internal(tcx, args, output, visited);
|
push_generic_params_internal(tcx, args, def.did(), output, visited);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Tuple(component_types) => {
|
ty::Tuple(component_types) => {
|
||||||
|
@ -237,8 +237,13 @@ fn push_debuginfo_type_name<'tcx>(
|
||||||
let principal =
|
let principal =
|
||||||
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), principal);
|
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), principal);
|
||||||
push_item_name(tcx, principal.def_id, qualified, output);
|
push_item_name(tcx, principal.def_id, qualified, output);
|
||||||
let principal_has_generic_params =
|
let principal_has_generic_params = push_generic_params_internal(
|
||||||
push_generic_params_internal(tcx, principal.args, output, visited);
|
tcx,
|
||||||
|
principal.args,
|
||||||
|
principal.def_id,
|
||||||
|
output,
|
||||||
|
visited,
|
||||||
|
);
|
||||||
|
|
||||||
let projection_bounds: SmallVec<[_; 4]> = trait_data
|
let projection_bounds: SmallVec<[_; 4]> = trait_data
|
||||||
.projection_bounds()
|
.projection_bounds()
|
||||||
|
@ -516,7 +521,13 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
|
||||||
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), trait_ref);
|
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), trait_ref);
|
||||||
push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name);
|
push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name);
|
||||||
visited.clear();
|
visited.clear();
|
||||||
push_generic_params_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited);
|
push_generic_params_internal(
|
||||||
|
tcx,
|
||||||
|
trait_ref.args,
|
||||||
|
trait_ref.def_id,
|
||||||
|
&mut vtable_name,
|
||||||
|
&mut visited,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
vtable_name.push('_');
|
vtable_name.push('_');
|
||||||
}
|
}
|
||||||
|
@ -610,20 +621,20 @@ fn push_unqualified_item_name(
|
||||||
fn push_generic_params_internal<'tcx>(
|
fn push_generic_params_internal<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
args: GenericArgsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
|
def_id: DefId,
|
||||||
output: &mut String,
|
output: &mut String,
|
||||||
visited: &mut FxHashSet<Ty<'tcx>>,
|
visited: &mut FxHashSet<Ty<'tcx>>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if args.non_erasable_generics().next().is_none() {
|
debug_assert_eq!(args, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args));
|
||||||
|
let mut args = args.non_erasable_generics(tcx, def_id).peekable();
|
||||||
|
if args.peek().is_none() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_assert_eq!(args, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args));
|
|
||||||
|
|
||||||
let cpp_like_debuginfo = cpp_like_debuginfo(tcx);
|
let cpp_like_debuginfo = cpp_like_debuginfo(tcx);
|
||||||
|
|
||||||
output.push('<');
|
output.push('<');
|
||||||
|
|
||||||
for type_parameter in args.non_erasable_generics() {
|
for type_parameter in args {
|
||||||
match type_parameter {
|
match type_parameter {
|
||||||
GenericArgKind::Type(type_parameter) => {
|
GenericArgKind::Type(type_parameter) => {
|
||||||
push_debuginfo_type_name(tcx, type_parameter, true, output, visited);
|
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
|
||||||
pub fn push_generic_params<'tcx>(
|
pub fn push_generic_params<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
args: GenericArgsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
|
def_id: DefId,
|
||||||
output: &mut String,
|
output: &mut String,
|
||||||
) {
|
) {
|
||||||
let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name");
|
let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name");
|
||||||
let mut visited = FxHashSet::default();
|
let mut visited = FxHashSet::default();
|
||||||
push_generic_params_internal(tcx, args, output, &mut visited);
|
push_generic_params_internal(tcx, args, def_id, output, &mut visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_closure_or_generator_name<'tcx>(
|
fn push_closure_or_generator_name<'tcx>(
|
||||||
|
@ -736,7 +748,7 @@ fn push_closure_or_generator_name<'tcx>(
|
||||||
// Truncate the args to the length of the above generics. This will cut off
|
// Truncate the args to the length of the above generics. This will cut off
|
||||||
// anything closure- or generator-specific.
|
// anything closure- or generator-specific.
|
||||||
let args = args.truncate_to(tcx, generics);
|
let args = args.truncate_to(tcx, generics);
|
||||||
push_generic_params_internal(tcx, args, output, visited);
|
push_generic_params_internal(tcx, args, enclosing_fn_def_id, output, visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_close_angle_bracket(cpp_like_debuginfo: bool, output: &mut String) {
|
fn push_close_angle_bracket(cpp_like_debuginfo: bool, output: &mut String) {
|
||||||
|
|
|
@ -1642,8 +1642,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
ValuePairs::Terms(infer::ExpectedFound { expected, found }) => {
|
ValuePairs::Terms(infer::ExpectedFound { expected, found }) => {
|
||||||
match (expected.unpack(), found.unpack()) {
|
match (expected.unpack(), found.unpack()) {
|
||||||
(ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => {
|
(ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => {
|
||||||
let is_simple_err =
|
let is_simple_err = expected.is_simple_text(self.tcx)
|
||||||
expected.is_simple_text() && found.is_simple_text();
|
&& found.is_simple_text(self.tcx);
|
||||||
OpaqueTypesVisitor::visit_expected_found(
|
OpaqueTypesVisitor::visit_expected_found(
|
||||||
self.tcx, expected, found, span,
|
self.tcx, expected, found, span,
|
||||||
)
|
)
|
||||||
|
@ -1885,7 +1885,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
s
|
s
|
||||||
};
|
};
|
||||||
if !(values.expected.is_simple_text() && values.found.is_simple_text())
|
if !(values.expected.is_simple_text(self.tcx) && values.found.is_simple_text(self.tcx))
|
||||||
|| (exp_found.is_some_and(|ef| {
|
|| (exp_found.is_some_and(|ef| {
|
||||||
// This happens when the type error is a subset of the expectation,
|
// This happens when the type error is a subset of the expectation,
|
||||||
// like when you have two references but one is `usize` and the other
|
// like when you have two references but one is `usize` and the other
|
||||||
|
|
|
@ -78,9 +78,11 @@ impl<'tcx> MonoItem<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_generic_fn(&self) -> bool {
|
pub fn is_generic_fn(&self, tcx: TyCtxt<'tcx>) -> bool {
|
||||||
match *self {
|
match self {
|
||||||
MonoItem::Fn(ref instance) => instance.args.non_erasable_generics().next().is_some(),
|
MonoItem::Fn(instance) => {
|
||||||
|
instance.args.non_erasable_generics(tcx, instance.def_id()).next().is_some()
|
||||||
|
}
|
||||||
MonoItem::Static(..) | MonoItem::GlobalAsm(..) => false,
|
MonoItem::Static(..) | MonoItem::GlobalAsm(..) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,10 +70,10 @@ impl<'tcx> Ty<'tcx> {
|
||||||
/// description in error messages. This is used in the primary span label. Beyond what
|
/// description in error messages. This is used in the primary span label. Beyond what
|
||||||
/// `is_simple_ty` includes, it also accepts ADTs with no type arguments and references to
|
/// `is_simple_ty` includes, it also accepts ADTs with no type arguments and references to
|
||||||
/// ADTs with no type arguments.
|
/// ADTs with no type arguments.
|
||||||
pub fn is_simple_text(self) -> bool {
|
pub fn is_simple_text(self, tcx: TyCtxt<'tcx>) -> bool {
|
||||||
match self.kind() {
|
match self.kind() {
|
||||||
Adt(_, args) => args.non_erasable_generics().next().is_none(),
|
Adt(def, args) => args.non_erasable_generics(tcx, def.did()).next().is_none(),
|
||||||
Ref(_, ty, _) => ty.is_simple_text(),
|
Ref(_, ty, _) => ty.is_simple_text(tcx),
|
||||||
_ => self.is_simple_ty(),
|
_ => self.is_simple_ty(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -379,12 +379,17 @@ impl<'tcx> GenericArgs<'tcx> {
|
||||||
self.iter().filter_map(|k| k.as_const())
|
self.iter().filter_map(|k| k.as_const())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns generic arguments that are not lifetimes or host effect params.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn non_erasable_generics(
|
pub fn non_erasable_generics(
|
||||||
&'tcx self,
|
&'tcx self,
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
def_id: DefId,
|
||||||
) -> impl DoubleEndedIterator<Item = GenericArgKind<'tcx>> + 'tcx {
|
) -> impl DoubleEndedIterator<Item = GenericArgKind<'tcx>> + 'tcx {
|
||||||
self.iter().filter_map(|k| match k.unpack() {
|
let generics = tcx.generics_of(def_id);
|
||||||
GenericArgKind::Lifetime(_) => None,
|
self.iter().enumerate().filter_map(|(i, k)| match k.unpack() {
|
||||||
|
_ if Some(i) == generics.host_effect_index => None,
|
||||||
|
ty::GenericArgKind::Lifetime(_) => None,
|
||||||
generic => Some(generic),
|
generic => Some(generic),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,10 +212,12 @@ impl<'tcx> Generics {
|
||||||
pub fn own_requires_monomorphization(&self) -> bool {
|
pub fn own_requires_monomorphization(&self) -> bool {
|
||||||
for param in &self.params {
|
for param in &self.params {
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
|
GenericParamDefKind::Type { .. }
|
||||||
|
| GenericParamDefKind::Const { is_host_effect: false, .. } => {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
GenericParamDefKind::Lifetime => {}
|
GenericParamDefKind::Lifetime
|
||||||
|
| GenericParamDefKind::Const { is_host_effect: true, .. } => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
|
|
|
@ -139,7 +139,7 @@ impl<'tcx> Instance<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this a non-generic instance, it cannot be a shared monomorphization.
|
// If this a non-generic instance, it cannot be a shared monomorphization.
|
||||||
self.args.non_erasable_generics().next()?;
|
self.args.non_erasable_generics(tcx, self.def_id()).next()?;
|
||||||
|
|
||||||
match self.def {
|
match self.def {
|
||||||
InstanceDef::Item(def) => tcx
|
InstanceDef::Item(def) => tcx
|
||||||
|
@ -344,6 +344,7 @@ impl<'tcx> Instance<'tcx> {
|
||||||
pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> {
|
pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> {
|
||||||
let args = GenericArgs::for_item(tcx, def_id, |param, _| match param.kind {
|
let args = GenericArgs::for_item(tcx, def_id, |param, _| match param.kind {
|
||||||
ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
|
ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
|
||||||
|
ty::GenericParamDefKind::Const { is_host_effect: true, .. } => tcx.consts.true_.into(),
|
||||||
ty::GenericParamDefKind::Type { .. } => {
|
ty::GenericParamDefKind::Type { .. } => {
|
||||||
bug!("Instance::mono: {:?} has type parameters", def_id)
|
bug!("Instance::mono: {:?} has type parameters", def_id)
|
||||||
}
|
}
|
||||||
|
|
|
@ -390,7 +390,12 @@ impl<'tcx> Inliner<'tcx> {
|
||||||
|
|
||||||
// Reachability pass defines which functions are eligible for inlining. Generally inlining
|
// Reachability pass defines which functions are eligible for inlining. Generally inlining
|
||||||
// other functions is incorrect because they could reference symbols that aren't exported.
|
// other functions is incorrect because they could reference symbols that aren't exported.
|
||||||
let is_generic = callsite.callee.args.non_erasable_generics().next().is_some();
|
let is_generic = callsite
|
||||||
|
.callee
|
||||||
|
.args
|
||||||
|
.non_erasable_generics(self.tcx, callsite.callee.def_id())
|
||||||
|
.next()
|
||||||
|
.is_some();
|
||||||
if !is_generic && !callee_attrs.requests_inline() {
|
if !is_generic && !callee_attrs.requests_inline() {
|
||||||
return Err("not exported");
|
return Err("not exported");
|
||||||
}
|
}
|
||||||
|
|
|
@ -459,7 +459,7 @@ fn collect_items_rec<'tcx>(
|
||||||
// Check for PMEs and emit a diagnostic if one happened. To try to show relevant edges of the
|
// Check for PMEs and emit a diagnostic if one happened. To try to show relevant edges of the
|
||||||
// mono item graph.
|
// mono item graph.
|
||||||
if tcx.sess.diagnostic().err_count() > error_count
|
if tcx.sess.diagnostic().err_count() > error_count
|
||||||
&& starting_item.node.is_generic_fn()
|
&& starting_item.node.is_generic_fn(tcx)
|
||||||
&& starting_item.node.is_user_defined()
|
&& starting_item.node.is_user_defined()
|
||||||
{
|
{
|
||||||
let formatted_item = with_no_trimmed_paths!(starting_item.node.to_string());
|
let formatted_item = with_no_trimmed_paths!(starting_item.node.to_string());
|
||||||
|
@ -1315,6 +1315,7 @@ fn create_mono_items_for_default_impls<'tcx>(
|
||||||
// it, to validate whether or not the impl is legal to instantiate at all.
|
// it, to validate whether or not the impl is legal to instantiate at all.
|
||||||
let only_region_params = |param: &ty::GenericParamDef, _: &_| match param.kind {
|
let only_region_params = |param: &ty::GenericParamDef, _: &_| match param.kind {
|
||||||
GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
|
GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
|
||||||
|
GenericParamDefKind::Const { is_host_effect: true, .. } => tcx.consts.true_.into(),
|
||||||
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
|
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
|
||||||
unreachable!(
|
unreachable!(
|
||||||
"`own_requires_monomorphization` check means that \
|
"`own_requires_monomorphization` check means that \
|
||||||
|
|
|
@ -221,7 +221,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item);
|
let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item);
|
||||||
let is_volatile = is_incremental_build && mono_item.is_generic_fn();
|
let is_volatile = is_incremental_build && mono_item.is_generic_fn(cx.tcx);
|
||||||
|
|
||||||
let cgu_name = match characteristic_def_id {
|
let cgu_name = match characteristic_def_id {
|
||||||
Some(def_id) => compute_codegen_unit_name(
|
Some(def_id) => compute_codegen_unit_name(
|
||||||
|
@ -801,7 +801,7 @@ fn mono_item_visibility<'tcx>(
|
||||||
return Visibility::Hidden;
|
return Visibility::Hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_generic = instance.args.non_erasable_generics().next().is_some();
|
let is_generic = instance.args.non_erasable_generics(tcx, def_id).next().is_some();
|
||||||
|
|
||||||
// Upstream `DefId` instances get different handling than local ones.
|
// Upstream `DefId` instances get different handling than local ones.
|
||||||
let Some(def_id) = def_id.as_local() else {
|
let Some(def_id) = def_id.as_local() else {
|
||||||
|
|
|
@ -108,7 +108,6 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
|
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
|
||||||
use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
|
use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
use rustc_middle::ty::GenericArgsRef;
|
|
||||||
use rustc_middle::ty::{self, Instance, TyCtxt};
|
use rustc_middle::ty::{self, Instance, TyCtxt};
|
||||||
use rustc_session::config::SymbolManglingVersion;
|
use rustc_session::config::SymbolManglingVersion;
|
||||||
|
|
||||||
|
@ -144,7 +143,7 @@ fn symbol_name_provider<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> ty
|
||||||
// This closure determines the instantiating crate for instances that
|
// This closure determines the instantiating crate for instances that
|
||||||
// need an instantiating-crate-suffix for their symbol name, in order
|
// need an instantiating-crate-suffix for their symbol name, in order
|
||||||
// to differentiate between local copies.
|
// to differentiate between local copies.
|
||||||
if is_generic(instance.args) {
|
if is_generic(instance, tcx) {
|
||||||
// For generics we might find re-usable upstream instances. If there
|
// For generics we might find re-usable upstream instances. If there
|
||||||
// is one, we rely on the symbol being instantiated locally.
|
// is one, we rely on the symbol being instantiated locally.
|
||||||
instance.upstream_monomorphization(tcx).unwrap_or(LOCAL_CRATE)
|
instance.upstream_monomorphization(tcx).unwrap_or(LOCAL_CRATE)
|
||||||
|
@ -246,7 +245,7 @@ fn compute_symbol_name<'tcx>(
|
||||||
// the ID of the instantiating crate. This avoids symbol conflicts
|
// the ID of the instantiating crate. This avoids symbol conflicts
|
||||||
// in case the same instances is emitted in two crates of the same
|
// in case the same instances is emitted in two crates of the same
|
||||||
// project.
|
// project.
|
||||||
let avoid_cross_crate_conflicts = is_generic(args) || is_globally_shared_function;
|
let avoid_cross_crate_conflicts = is_generic(instance, tcx) || is_globally_shared_function;
|
||||||
|
|
||||||
let instantiating_crate = avoid_cross_crate_conflicts.then(compute_instantiating_crate);
|
let instantiating_crate = avoid_cross_crate_conflicts.then(compute_instantiating_crate);
|
||||||
|
|
||||||
|
@ -278,6 +277,6 @@ fn compute_symbol_name<'tcx>(
|
||||||
symbol
|
symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_generic(args: GenericArgsRef<'_>) -> bool {
|
fn is_generic<'tcx>(instance: Instance<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
|
||||||
args.non_erasable_generics().next().is_some()
|
instance.args.non_erasable_generics(tcx, instance.def_id()).next().is_some()
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ fn resolve_instance<'tcx>(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debug!(" => free item");
|
debug!(" => free item");
|
||||||
|
// FIXME(effects): we may want to erase the effect param if that is present on this item.
|
||||||
ty::InstanceDef::Item(def_id)
|
ty::InstanceDef::Item(def_id)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -343,7 +343,7 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h
|
||||||
// If the current self type doesn't implement Copy (due to generic constraints), search to see if
|
// If the current self type doesn't implement Copy (due to generic constraints), search to see if
|
||||||
// there's a Copy impl for any instance of the adt.
|
// there's a Copy impl for any instance of the adt.
|
||||||
if !is_copy(cx, ty) {
|
if !is_copy(cx, ty) {
|
||||||
if ty_subs.non_erasable_generics().next().is_some() {
|
if ty_subs.non_erasable_generics(cx.tcx, ty_adt.did()).next().is_some() {
|
||||||
let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(©_id).map_or(false, |impls| {
|
let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(©_id).map_or(false, |impls| {
|
||||||
impls.iter().any(|&id| {
|
impls.iter().any(|&id| {
|
||||||
matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _)
|
matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue