mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-16 22:16:53 +00:00
Account for identity substituted items in symbol mangling
This commit is contained in:
parent
b6b8361bce
commit
39daadc76e
@ -165,10 +165,14 @@ impl<'tcx> NormalizeAfterErasingRegionsFolder<'tcx> {
|
||||
arg: ty::GenericArg<'tcx>,
|
||||
) -> ty::GenericArg<'tcx> {
|
||||
let arg = self.typing_env.as_query_input(arg);
|
||||
self.tcx.try_normalize_generic_arg_after_erasing_regions(arg).unwrap_or_else(|_| bug!(
|
||||
"Failed to normalize {:?}, maybe try to call `try_normalize_erasing_regions` instead",
|
||||
arg.value
|
||||
))
|
||||
self.tcx.try_normalize_generic_arg_after_erasing_regions(arg).unwrap_or_else(|_| {
|
||||
bug!(
|
||||
"Failed to normalize {:?} in typing_env={:?}, \
|
||||
maybe try to call `try_normalize_erasing_regions` instead",
|
||||
arg.value,
|
||||
self.typing_env,
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ use rustc_middle::bug;
|
||||
use rustc_middle::ty::print::{PrettyPrinter, Print, PrintError, Printer};
|
||||
use rustc_middle::ty::{
|
||||
self, GenericArg, GenericArgKind, Instance, ReifyReason, Ty, TyCtxt, TypeVisitableExt,
|
||||
TypingEnv,
|
||||
};
|
||||
use tracing::debug;
|
||||
|
||||
@ -387,23 +386,44 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> {
|
||||
) -> Result<(), PrintError> {
|
||||
let self_ty = self.tcx.type_of(impl_def_id);
|
||||
let impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id);
|
||||
let (typing_env, mut self_ty, mut impl_trait_ref) =
|
||||
if self.tcx.generics_of(impl_def_id).count() <= args.len() {
|
||||
(
|
||||
TypingEnv::fully_monomorphized(),
|
||||
self_ty.instantiate(self.tcx, args),
|
||||
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(self.tcx, args)),
|
||||
)
|
||||
} else {
|
||||
// We are probably printing a nested item inside of an impl.
|
||||
// Use the identity substitutions for the impl. We also need
|
||||
// a well-formed param-env, so let's use post-analysis.
|
||||
(
|
||||
TypingEnv::post_analysis(self.tcx, impl_def_id),
|
||||
self_ty.instantiate_identity(),
|
||||
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate_identity()),
|
||||
)
|
||||
};
|
||||
let generics = self.tcx.generics_of(impl_def_id);
|
||||
// We have two cases to worry about here:
|
||||
// 1. We're printing a nested item inside of an impl item, like an inner
|
||||
// function inside of a method. Due to the way that def path printing works,
|
||||
// we'll render this something like `<Ty as Trait>::method::inner_fn`
|
||||
// but we have no substs for this impl since it's not really inheriting
|
||||
// generics from the outer item. We need to use the identity substs, and
|
||||
// to normalize we need to use the correct param-env too.
|
||||
// 2. We're mangling an item with identity substs. This seems to only happen
|
||||
// when generating coverage, since we try to generate coverage for unused
|
||||
// items too, and if something isn't monomorphized then we necessarily don't
|
||||
// have anything to substitute the instance with.
|
||||
// NOTE: We don't support mangling partially substituted but still polymorphic
|
||||
// instances, like `impl<A> Tr<A> for ()` where `A` is substituted w/ `(T,)`.
|
||||
let (typing_env, mut self_ty, mut impl_trait_ref) = if generics.count() > args.len()
|
||||
|| &args[..generics.count()]
|
||||
== self
|
||||
.tcx
|
||||
.erase_regions(ty::GenericArgs::identity_for_item(self.tcx, impl_def_id))
|
||||
.as_slice()
|
||||
{
|
||||
(
|
||||
ty::TypingEnv::post_analysis(self.tcx, impl_def_id),
|
||||
self_ty.instantiate_identity(),
|
||||
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate_identity()),
|
||||
)
|
||||
} else {
|
||||
assert!(
|
||||
!args.has_non_region_param(),
|
||||
"should not be mangling partially substituted \
|
||||
polymorphic instance: {impl_def_id:?} {args:?}"
|
||||
);
|
||||
(
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
self_ty.instantiate(self.tcx, args),
|
||||
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(self.tcx, args)),
|
||||
)
|
||||
};
|
||||
|
||||
match &mut impl_trait_ref {
|
||||
Some(impl_trait_ref) => {
|
||||
|
@ -233,23 +233,44 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
||||
|
||||
let self_ty = self.tcx.type_of(impl_def_id);
|
||||
let impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id);
|
||||
let (typing_env, mut self_ty, mut impl_trait_ref) =
|
||||
if self.tcx.generics_of(impl_def_id).count() <= args.len() {
|
||||
(
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
self_ty.instantiate(self.tcx, args),
|
||||
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(self.tcx, args)),
|
||||
)
|
||||
} else {
|
||||
// We are probably printing a nested item inside of an impl.
|
||||
// Use the identity substitutions for the impl. We also need
|
||||
// a well-formed param-env, so let's use post-analysis.
|
||||
(
|
||||
ty::TypingEnv::post_analysis(self.tcx, impl_def_id),
|
||||
self_ty.instantiate_identity(),
|
||||
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate_identity()),
|
||||
)
|
||||
};
|
||||
let generics = self.tcx.generics_of(impl_def_id);
|
||||
// We have two cases to worry about here:
|
||||
// 1. We're printing a nested item inside of an impl item, like an inner
|
||||
// function inside of a method. Due to the way that def path printing works,
|
||||
// we'll render this something like `<Ty as Trait>::method::inner_fn`
|
||||
// but we have no substs for this impl since it's not really inheriting
|
||||
// generics from the outer item. We need to use the identity substs, and
|
||||
// to normalize we need to use the correct param-env too.
|
||||
// 2. We're mangling an item with identity substs. This seems to only happen
|
||||
// when generating coverage, since we try to generate coverage for unused
|
||||
// items too, and if something isn't monomorphized then we necessarily don't
|
||||
// have anything to substitute the instance with.
|
||||
// NOTE: We don't support mangling partially substituted but still polymorphic
|
||||
// instances, like `impl<A> Tr<A> for ()` where `A` is substituted w/ `(T,)`.
|
||||
let (typing_env, mut self_ty, mut impl_trait_ref) = if generics.count() > args.len()
|
||||
|| &args[..generics.count()]
|
||||
== self
|
||||
.tcx
|
||||
.erase_regions(ty::GenericArgs::identity_for_item(self.tcx, impl_def_id))
|
||||
.as_slice()
|
||||
{
|
||||
(
|
||||
ty::TypingEnv::post_analysis(self.tcx, impl_def_id),
|
||||
self_ty.instantiate_identity(),
|
||||
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate_identity()),
|
||||
)
|
||||
} else {
|
||||
assert!(
|
||||
!args.has_non_region_param(),
|
||||
"should not be mangling partially substituted \
|
||||
polymorphic instance: {impl_def_id:?} {args:?}"
|
||||
);
|
||||
(
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
self_ty.instantiate(self.tcx, args),
|
||||
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(self.tcx, args)),
|
||||
)
|
||||
};
|
||||
|
||||
match &mut impl_trait_ref {
|
||||
Some(impl_trait_ref) => {
|
||||
|
18
tests/coverage/generic-unused-impl.cov-map
Normal file
18
tests/coverage/generic-unused-impl.cov-map
Normal file
@ -0,0 +1,18 @@
|
||||
Function name: <generic_unused_impl::W<_> as core::convert::From<[<_ as generic_unused_impl::Foo>::Assoc; 1]>>::from (unused)
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 00, 0a, 05, 03, 06]
|
||||
Number of files: 1
|
||||
- file 0 => global file 1
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 1
|
||||
- Code(Zero) at (prev + 10, 5) to (start + 3, 6)
|
||||
Highest counter ID seen: (none)
|
||||
|
||||
Function name: generic_unused_impl::main
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 01, 10, 01, 00, 0d]
|
||||
Number of files: 1
|
||||
- file 0 => global file 1
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 1
|
||||
- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 13)
|
||||
Highest counter ID seen: c0
|
||||
|
17
tests/coverage/generic-unused-impl.coverage
Normal file
17
tests/coverage/generic-unused-impl.coverage
Normal file
@ -0,0 +1,17 @@
|
||||
LL| |trait Foo {
|
||||
LL| | type Assoc;
|
||||
LL| |
|
||||
LL| | fn from(s: Self::Assoc) -> Self;
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| |struct W<T>(T);
|
||||
LL| |
|
||||
LL| |impl<T: Foo> From<[T::Assoc; 1]> for W<T> {
|
||||
LL| 0| fn from(from: [T::Assoc; 1]) -> Self {
|
||||
LL| 0| let [item] = from;
|
||||
LL| 0| W(Foo::from(item))
|
||||
LL| 0| }
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| 1|fn main() {}
|
||||
|
16
tests/coverage/generic-unused-impl.rs
Normal file
16
tests/coverage/generic-unused-impl.rs
Normal file
@ -0,0 +1,16 @@
|
||||
trait Foo {
|
||||
type Assoc;
|
||||
|
||||
fn from(s: Self::Assoc) -> Self;
|
||||
}
|
||||
|
||||
struct W<T>(T);
|
||||
|
||||
impl<T: Foo> From<[T::Assoc; 1]> for W<T> {
|
||||
fn from(from: [T::Assoc; 1]) -> Self {
|
||||
let [item] = from;
|
||||
W(Foo::from(item))
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user