@@ -9,10 +9,8 @@ use rustc::hir::def_id::{DefId, DefIndex};
99use rustc:: hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
1010use rustc:: infer:: InferCtxt ;
1111use rustc:: ty:: adjustment:: { Adjust , Adjustment , PointerCast } ;
12- use rustc:: ty:: fold:: { BottomUpFolder , TypeFoldable , TypeFolder } ;
13- use rustc:: ty:: subst:: UnpackedKind ;
12+ use rustc:: ty:: fold:: { TypeFoldable , TypeFolder } ;
1413use rustc:: ty:: { self , Ty , TyCtxt } ;
15- use rustc:: mir:: interpret:: ConstValue ;
1614use rustc:: util:: nodemap:: DefIdSet ;
1715use rustc_data_structures:: sync:: Lrc ;
1816use std:: mem;
@@ -440,141 +438,20 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
440438
441439 debug_assert ! ( !instantiated_ty. has_escaping_bound_vars( ) ) ;
442440
443- let generics = self . tcx ( ) . generics_of ( def_id) ;
444-
445- let definition_ty = if generics. parent . is_some ( ) {
446- // `impl Trait`
447- self . fcx . infer_opaque_definition_from_instantiation (
448- def_id,
449- opaque_defn,
450- instantiated_ty,
451- )
452- } else {
453- // Prevent:
454- // * `fn foo<T>() -> Foo<T>`
455- // * `fn foo<T: Bound + Other>() -> Foo<T>`
456- // from being defining.
457-
458- // Also replace all generic params with the ones from the existential type
459- // definition so that
460- // ```rust
461- // existential type Foo<T>: 'static;
462- // fn foo<U>() -> Foo<U> { .. }
463- // ```
464- // figures out the concrete type with `U`, but the stored type is with `T`.
465- instantiated_ty. fold_with ( & mut BottomUpFolder {
466- tcx : self . tcx ( ) . global_tcx ( ) ,
467- ty_op : |ty| {
468- trace ! ( "checking type {:?}" , ty) ;
469- // Find a type parameter.
470- if let ty:: Param ( ..) = ty. sty {
471- // Look it up in the substitution list.
472- assert_eq ! ( opaque_defn. substs. len( ) , generics. params. len( ) ) ;
473- for ( subst, param) in opaque_defn. substs . iter ( ) . zip ( & generics. params ) {
474- if let UnpackedKind :: Type ( subst) = subst. unpack ( ) {
475- if subst == ty {
476- // Found it in the substitution list; replace with the
477- // parameter from the existential type.
478- return self . tcx ( )
479- . global_tcx ( )
480- . mk_ty_param ( param. index , param. name ) ;
481- }
482- }
483- }
484- self . tcx ( )
485- . sess
486- . struct_span_err (
487- span,
488- & format ! (
489- "type parameter `{}` is part of concrete type but not used \
490- in parameter list for existential type",
491- ty,
492- ) ,
493- )
494- . emit ( ) ;
495- return self . tcx ( ) . types . err ;
496- }
497- ty
498- } ,
499- lt_op : |region| {
500- match region {
501- // Skip static and bound regions: they don't require substitution.
502- ty:: ReStatic | ty:: ReLateBound ( ..) => region,
503- _ => {
504- trace ! ( "checking {:?}" , region) ;
505- for ( subst, p) in opaque_defn. substs . iter ( ) . zip ( & generics. params ) {
506- if let UnpackedKind :: Lifetime ( subst) = subst. unpack ( ) {
507- if subst == region {
508- // Found it in the substitution list; replace with the
509- // parameter from the existential type.
510- let reg = ty:: EarlyBoundRegion {
511- def_id : p. def_id ,
512- index : p. index ,
513- name : p. name ,
514- } ;
515- trace ! ( "replace {:?} with {:?}" , region, reg) ;
516- return self . tcx ( )
517- . global_tcx ( )
518- . mk_region ( ty:: ReEarlyBound ( reg) ) ;
519- }
520- }
521- }
522- trace ! ( "opaque_defn: {:#?}" , opaque_defn) ;
523- trace ! ( "generics: {:#?}" , generics) ;
524- self . tcx ( )
525- . sess
526- . struct_span_err (
527- span,
528- "non-defining existential type use in defining scope" ,
529- )
530- . span_label (
531- span,
532- format ! (
533- "lifetime `{}` is part of concrete type but not used \
534- in parameter list of existential type",
535- region,
536- ) ,
537- )
538- . emit ( ) ;
539- self . tcx ( ) . global_tcx ( ) . mk_region ( ty:: ReStatic )
540- }
541- }
542- } ,
543- ct_op : |ct| {
544- trace ! ( "checking const {:?}" , ct) ;
545- // Find a const parameter
546- if let ConstValue :: Param ( ..) = ct. val {
547- // look it up in the substitution list
548- assert_eq ! ( opaque_defn. substs. len( ) , generics. params. len( ) ) ;
549- for ( subst, param) in opaque_defn. substs . iter ( )
550- . zip ( & generics. params ) {
551- if let UnpackedKind :: Const ( subst) = subst. unpack ( ) {
552- if subst == ct {
553- // found it in the substitution list, replace with the
554- // parameter from the existential type
555- return self . tcx ( )
556- . global_tcx ( )
557- . mk_const_param ( param. index , param. name , ct. ty ) ;
558- }
559- }
560- }
561- self . tcx ( )
562- . sess
563- . struct_span_err (
564- span,
565- & format ! (
566- "const parameter `{}` is part of concrete type but not \
567- used in parameter list for existential type",
568- ct,
569- ) ,
570- )
571- . emit ( ) ;
572- return self . tcx ( ) . consts . err ;
573- }
574- ct
575- }
576- } )
577- } ;
441+ // Prevent:
442+ // * `fn foo<T>() -> Foo<T>`
443+ // * `fn foo<T: Bound + Other>() -> Foo<T>`
444+ // from being defining.
445+
446+ // Also replace all generic params with the ones from the existential type
447+ // definition so that
448+ // ```rust
449+ // existential type Foo<T>: 'static;
450+ // fn foo<U>() -> Foo<U> { .. }
451+ // ```
452+ // figures out the concrete type with `U`, but the stored type is with `T`.
453+ let definition_ty = self . fcx . infer_opaque_definition_from_instantiation (
454+ def_id, opaque_defn, instantiated_ty, span) ;
578455
579456 if let ty:: Opaque ( defin_ty_def_id, _substs) = definition_ty. sty {
580457 if def_id == defin_ty_def_id {
0 commit comments