@@ -8,7 +8,6 @@ use rustc_middle::bug;
88use rustc_middle:: ty:: print:: { PrettyPrinter , Print , PrintError , Printer } ;
99use rustc_middle:: ty:: {
1010 self , GenericArg , GenericArgKind , Instance , ReifyReason , Ty , TyCtxt , TypeVisitableExt ,
11- TypingEnv ,
1211} ;
1312use 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) => {
0 commit comments