Skip to content

Commit 41c7d5a

Browse files
authored
Rollup merge of #135261 - compiler-errors:coverage-has-identity-substs, r=oli-obk
Account for identity substituted items in symbol mangling See the inline comment. r? oli-obk Fixes #135235
2 parents 8ff355a + b85b2c6 commit 41c7d5a

File tree

6 files changed

+137
-39
lines changed

6 files changed

+137
-39
lines changed

compiler/rustc_middle/src/ty/normalize_erasing_regions.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,14 @@ impl<'tcx> NormalizeAfterErasingRegionsFolder<'tcx> {
165165
arg: ty::GenericArg<'tcx>,
166166
) -> ty::GenericArg<'tcx> {
167167
let arg = self.typing_env.as_query_input(arg);
168-
self.tcx.try_normalize_generic_arg_after_erasing_regions(arg).unwrap_or_else(|_| bug!(
169-
"Failed to normalize {:?}, maybe try to call `try_normalize_erasing_regions` instead",
170-
arg.value
171-
))
168+
self.tcx.try_normalize_generic_arg_after_erasing_regions(arg).unwrap_or_else(|_| {
169+
bug!(
170+
"Failed to normalize {:?} in typing_env={:?}, \
171+
maybe try to call `try_normalize_erasing_regions` instead",
172+
arg.value,
173+
self.typing_env,
174+
)
175+
})
172176
}
173177
}
174178

compiler/rustc_symbol_mangling/src/legacy.rs

+38-18
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use rustc_middle::bug;
88
use rustc_middle::ty::print::{PrettyPrinter, Print, PrintError, Printer};
99
use rustc_middle::ty::{
1010
self, GenericArg, GenericArgKind, Instance, ReifyReason, Ty, TyCtxt, TypeVisitableExt,
11-
TypingEnv,
1211
};
1312
use tracing::debug;
1413

@@ -387,23 +386,44 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> {
387386
) -> Result<(), PrintError> {
388387
let self_ty = self.tcx.type_of(impl_def_id);
389388
let impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id);
390-
let (typing_env, mut self_ty, mut impl_trait_ref) =
391-
if self.tcx.generics_of(impl_def_id).count() <= args.len() {
392-
(
393-
TypingEnv::fully_monomorphized(),
394-
self_ty.instantiate(self.tcx, args),
395-
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(self.tcx, args)),
396-
)
397-
} else {
398-
// We are probably printing a nested item inside of an impl.
399-
// Use the identity substitutions for the impl. We also need
400-
// a well-formed param-env, so let's use post-analysis.
401-
(
402-
TypingEnv::post_analysis(self.tcx, impl_def_id),
403-
self_ty.instantiate_identity(),
404-
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate_identity()),
405-
)
406-
};
389+
let generics = self.tcx.generics_of(impl_def_id);
390+
// We have two cases to worry about here:
391+
// 1. We're printing a nested item inside of an impl item, like an inner
392+
// function inside of a method. Due to the way that def path printing works,
393+
// we'll render this something like `<Ty as Trait>::method::inner_fn`
394+
// but we have no substs for this impl since it's not really inheriting
395+
// generics from the outer item. We need to use the identity substs, and
396+
// to normalize we need to use the correct param-env too.
397+
// 2. We're mangling an item with identity substs. This seems to only happen
398+
// when generating coverage, since we try to generate coverage for unused
399+
// items too, and if something isn't monomorphized then we necessarily don't
400+
// have anything to substitute the instance with.
401+
// NOTE: We don't support mangling partially substituted but still polymorphic
402+
// instances, like `impl<A> Tr<A> for ()` where `A` is substituted w/ `(T,)`.
403+
let (typing_env, mut self_ty, mut impl_trait_ref) = if generics.count() > args.len()
404+
|| &args[..generics.count()]
405+
== self
406+
.tcx
407+
.erase_regions(ty::GenericArgs::identity_for_item(self.tcx, impl_def_id))
408+
.as_slice()
409+
{
410+
(
411+
ty::TypingEnv::post_analysis(self.tcx, impl_def_id),
412+
self_ty.instantiate_identity(),
413+
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate_identity()),
414+
)
415+
} else {
416+
assert!(
417+
!args.has_non_region_param(),
418+
"should not be mangling partially substituted \
419+
polymorphic instance: {impl_def_id:?} {args:?}"
420+
);
421+
(
422+
ty::TypingEnv::fully_monomorphized(),
423+
self_ty.instantiate(self.tcx, args),
424+
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(self.tcx, args)),
425+
)
426+
};
407427

408428
match &mut impl_trait_ref {
409429
Some(impl_trait_ref) => {

compiler/rustc_symbol_mangling/src/v0.rs

+38-17
Original file line numberDiff line numberDiff line change
@@ -233,23 +233,44 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
233233

234234
let self_ty = self.tcx.type_of(impl_def_id);
235235
let impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id);
236-
let (typing_env, mut self_ty, mut impl_trait_ref) =
237-
if self.tcx.generics_of(impl_def_id).count() <= args.len() {
238-
(
239-
ty::TypingEnv::fully_monomorphized(),
240-
self_ty.instantiate(self.tcx, args),
241-
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(self.tcx, args)),
242-
)
243-
} else {
244-
// We are probably printing a nested item inside of an impl.
245-
// Use the identity substitutions for the impl. We also need
246-
// a well-formed param-env, so let's use post-analysis.
247-
(
248-
ty::TypingEnv::post_analysis(self.tcx, impl_def_id),
249-
self_ty.instantiate_identity(),
250-
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate_identity()),
251-
)
252-
};
236+
let generics = self.tcx.generics_of(impl_def_id);
237+
// We have two cases to worry about here:
238+
// 1. We're printing a nested item inside of an impl item, like an inner
239+
// function inside of a method. Due to the way that def path printing works,
240+
// we'll render this something like `<Ty as Trait>::method::inner_fn`
241+
// but we have no substs for this impl since it's not really inheriting
242+
// generics from the outer item. We need to use the identity substs, and
243+
// to normalize we need to use the correct param-env too.
244+
// 2. We're mangling an item with identity substs. This seems to only happen
245+
// when generating coverage, since we try to generate coverage for unused
246+
// items too, and if something isn't monomorphized then we necessarily don't
247+
// have anything to substitute the instance with.
248+
// NOTE: We don't support mangling partially substituted but still polymorphic
249+
// instances, like `impl<A> Tr<A> for ()` where `A` is substituted w/ `(T,)`.
250+
let (typing_env, mut self_ty, mut impl_trait_ref) = if generics.count() > args.len()
251+
|| &args[..generics.count()]
252+
== self
253+
.tcx
254+
.erase_regions(ty::GenericArgs::identity_for_item(self.tcx, impl_def_id))
255+
.as_slice()
256+
{
257+
(
258+
ty::TypingEnv::post_analysis(self.tcx, impl_def_id),
259+
self_ty.instantiate_identity(),
260+
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate_identity()),
261+
)
262+
} else {
263+
assert!(
264+
!args.has_non_region_param(),
265+
"should not be mangling partially substituted \
266+
polymorphic instance: {impl_def_id:?} {args:?}"
267+
);
268+
(
269+
ty::TypingEnv::fully_monomorphized(),
270+
self_ty.instantiate(self.tcx, args),
271+
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(self.tcx, args)),
272+
)
273+
};
253274

254275
match &mut impl_trait_ref {
255276
Some(impl_trait_ref) => {
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Function name: <generic_unused_impl::W<_> as core::convert::From<[<_ as generic_unused_impl::Foo>::Assoc; 1]>>::from (unused)
2+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 0b, 05, 03, 06]
3+
Number of files: 1
4+
- file 0 => global file 1
5+
Number of expressions: 0
6+
Number of file 0 mappings: 1
7+
- Code(Zero) at (prev + 11, 5) to (start + 3, 6)
8+
Highest counter ID seen: (none)
9+
10+
Function name: generic_unused_impl::main
11+
Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 01, 00, 0d]
12+
Number of files: 1
13+
- file 0 => global file 1
14+
Number of expressions: 0
15+
Number of file 0 mappings: 1
16+
- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 13)
17+
Highest counter ID seen: c0
18+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
LL| |// Regression test for #135235.
2+
LL| |trait Foo {
3+
LL| | type Assoc;
4+
LL| |
5+
LL| | fn from(s: Self::Assoc) -> Self;
6+
LL| |}
7+
LL| |
8+
LL| |struct W<T>(T);
9+
LL| |
10+
LL| |impl<T: Foo> From<[T::Assoc; 1]> for W<T> {
11+
LL| 0| fn from(from: [T::Assoc; 1]) -> Self {
12+
LL| 0| let [item] = from;
13+
LL| 0| W(Foo::from(item))
14+
LL| 0| }
15+
LL| |}
16+
LL| |
17+
LL| 1|fn main() {}
18+

tests/coverage/generic-unused-impl.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Regression test for #135235.
2+
trait Foo {
3+
type Assoc;
4+
5+
fn from(s: Self::Assoc) -> Self;
6+
}
7+
8+
struct W<T>(T);
9+
10+
impl<T: Foo> From<[T::Assoc; 1]> for W<T> {
11+
fn from(from: [T::Assoc; 1]) -> Self {
12+
let [item] = from;
13+
W(Foo::from(item))
14+
}
15+
}
16+
17+
fn main() {}

0 commit comments

Comments
 (0)