@@ -801,18 +801,14 @@ fn check_where_clauses<'tcx, 'fcx>(
801801 traits:: Obligation :: new ( cause, fcx. param_env , pred)
802802 } ) ;
803803
804- let mut predicates = predicates. instantiate_identity ( fcx. tcx ) ;
804+ let predicates = predicates. instantiate_identity ( fcx. tcx ) ;
805805
806806 if let Some ( ( mut return_ty, span) ) = return_ty {
807807 if return_ty. has_infer_types_or_consts ( ) {
808808 fcx. select_obligations_where_possible ( false , |_| { } ) ;
809809 return_ty = fcx. resolve_vars_if_possible ( & return_ty) ;
810810 }
811- let opaque_types = check_opaque_types ( tcx, fcx, def_id. expect_local ( ) , span, return_ty) ;
812- for _ in 0 ..opaque_types. len ( ) {
813- predicates. spans . push ( span) ;
814- }
815- predicates. predicates . extend ( opaque_types) ;
811+ check_opaque_types ( tcx, fcx, def_id. expect_local ( ) , span, return_ty) ;
816812 }
817813
818814 let predicates = fcx. normalize_associated_types_in ( span, & predicates) ;
@@ -884,113 +880,109 @@ fn check_opaque_types<'fcx, 'tcx>(
884880 fn_def_id : LocalDefId ,
885881 span : Span ,
886882 ty : Ty < ' tcx > ,
887- ) -> Vec < ty :: Predicate < ' tcx > > {
883+ ) {
888884 trace ! ( "check_opaque_types(ty={:?})" , ty) ;
889- let mut substituted_predicates = Vec :: new ( ) ;
890885 ty. fold_with ( & mut ty:: fold:: BottomUpFolder {
891886 tcx : fcx. tcx ,
892887 ty_op : |ty| {
893888 if let ty:: Opaque ( def_id, substs) = ty. kind {
894889 trace ! ( "check_opaque_types: opaque_ty, {:?}, {:?}" , def_id, substs) ;
895890 let generics = tcx. generics_of ( def_id) ;
896- // Only check named `impl Trait` types defined in this crate.
897- if !def_id. is_local ( ) {
891+
892+ let opaque_hir_id = if let Some ( local_id) = def_id. as_local ( ) {
893+ tcx. hir ( ) . as_local_hir_id ( local_id)
894+ } else {
895+ // Opaque types from other crates won't have defining uses in this crate.
898896 return ty;
899- }
900- let opaque_hir_id = tcx. hir ( ) . as_local_hir_id ( def_id. expect_local ( ) ) ;
897+ } ;
901898 if let hir:: ItemKind :: OpaqueTy ( hir:: OpaqueTy { impl_trait_fn : Some ( _) , .. } ) =
902899 tcx. hir ( ) . expect_item ( opaque_hir_id) . kind
903900 {
904- // Don't check return position impl trait.
901+ // No need to check return position impl trait (RPIT)
902+ // because for type and const parameters they are correct
903+ // by construction: we convert
904+ //
905+ // fn foo<P0..Pn>() -> impl Trait
906+ //
907+ // into
908+ //
909+ // type Foo<P0...Pn>
910+ // fn foo<P0..Pn>() -> Foo<P0...Pn>.
911+ //
912+ // For lifetime parameters we convert
913+ //
914+ // fn foo<'l0..'ln>() -> impl Trait<'l0..'lm>
915+ //
916+ // into
917+ //
918+ // type foo::<'p0..'pn>::Foo<'q0..'qm>
919+ // fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
920+ //
921+ // which would error here on all of the `'static` args.
922+ return ty;
923+ }
924+ if !may_define_opaque_type ( tcx, fn_def_id, opaque_hir_id) {
905925 return ty;
906926 }
907- if may_define_opaque_type ( tcx, fn_def_id, opaque_hir_id) {
908- trace ! ( "check_opaque_types: may define, generics={:#?}" , generics) ;
909- let mut seen_params: FxHashMap < _ , Vec < _ > > = FxHashMap :: default ( ) ;
910- for ( i, arg) in substs. iter ( ) . enumerate ( ) {
911- let arg_is_param = match arg. unpack ( ) {
912- GenericArgKind :: Type ( ty) => matches ! ( ty. kind, ty:: Param ( _) ) ,
913-
914- GenericArgKind :: Lifetime ( region) => {
915- if let ty:: ReStatic = region {
916- tcx. sess
917- . struct_span_err (
918- span,
919- "non-defining opaque type use in defining scope" ,
920- )
921- . span_label (
922- tcx. def_span ( generics. param_at ( i, tcx) . def_id ) ,
923- "cannot use static lifetime; use a bound lifetime \
927+ trace ! ( "check_opaque_types: may define, generics={:#?}" , generics) ;
928+ let mut seen_params: FxHashMap < _ , Vec < _ > > = FxHashMap :: default ( ) ;
929+ for ( i, arg) in substs. iter ( ) . enumerate ( ) {
930+ let arg_is_param = match arg. unpack ( ) {
931+ GenericArgKind :: Type ( ty) => matches ! ( ty. kind, ty:: Param ( _) ) ,
932+
933+ GenericArgKind :: Lifetime ( region) => {
934+ if let ty:: ReStatic = region {
935+ tcx. sess
936+ . struct_span_err (
937+ span,
938+ "non-defining opaque type use in defining scope" ,
939+ )
940+ . span_label (
941+ tcx. def_span ( generics. param_at ( i, tcx) . def_id ) ,
942+ "cannot use static lifetime; use a bound lifetime \
924943 instead or remove the lifetime parameter from the \
925944 opaque type",
926- )
927- . emit ( ) ;
928- continue ;
929- }
930-
931- true
945+ )
946+ . emit ( ) ;
947+ continue ;
932948 }
933949
934- GenericArgKind :: Const ( ct) => matches ! ( ct. val, ty:: ConstKind :: Param ( _) ) ,
935- } ;
936-
937- if arg_is_param {
938- seen_params. entry ( arg) . or_default ( ) . push ( i) ;
939- } else {
940- // Prevent `fn foo() -> Foo<u32>` from being defining.
941- let opaque_param = generics. param_at ( i, tcx) ;
942- tcx. sess
943- . struct_span_err (
944- span,
945- "non-defining opaque type use in defining scope" ,
946- )
947- . span_note (
948- tcx. def_span ( opaque_param. def_id ) ,
949- & format ! (
950- "used non-generic {} `{}` for generic parameter" ,
951- opaque_param. kind. descr( ) ,
952- arg,
953- ) ,
954- )
955- . emit ( ) ;
956- }
957- } // for (arg, param)
958-
959- for ( _, indices) in seen_params {
960- if indices. len ( ) > 1 {
961- let descr = generics. param_at ( indices[ 0 ] , tcx) . kind . descr ( ) ;
962- let spans: Vec < _ > = indices
963- . into_iter ( )
964- . map ( |i| tcx. def_span ( generics. param_at ( i, tcx) . def_id ) )
965- . collect ( ) ;
966- tcx. sess
967- . struct_span_err (
968- span,
969- "non-defining opaque type use in defining scope" ,
970- )
971- . span_note ( spans, & format ! ( "{} used multiple times" , descr) )
972- . emit ( ) ;
950+ true
973951 }
952+
953+ GenericArgKind :: Const ( ct) => matches ! ( ct. val, ty:: ConstKind :: Param ( _) ) ,
954+ } ;
955+
956+ if arg_is_param {
957+ seen_params. entry ( arg) . or_default ( ) . push ( i) ;
958+ } else {
959+ // Prevent `fn foo() -> Foo<u32>` from being defining.
960+ let opaque_param = generics. param_at ( i, tcx) ;
961+ tcx. sess
962+ . struct_span_err ( span, "non-defining opaque type use in defining scope" )
963+ . span_note (
964+ tcx. def_span ( opaque_param. def_id ) ,
965+ & format ! (
966+ "used non-generic {} `{}` for generic parameter" ,
967+ opaque_param. kind. descr( ) ,
968+ arg,
969+ ) ,
970+ )
971+ . emit ( ) ;
974972 }
975- } // if may_define_opaque_type
976-
977- // Now register the bounds on the parameters of the opaque type
978- // so the parameters given by the function need to fulfill them.
979- //
980- // type Foo<T: Bar> = impl Baz + 'static;
981- // fn foo<U>() -> Foo<U> { .. *}
982- //
983- // becomes
984- //
985- // type Foo<T: Bar> = impl Baz + 'static;
986- // fn foo<U: Bar>() -> Foo<U> { .. *}
987- let predicates = tcx. predicates_of ( def_id) ;
988- trace ! ( "check_opaque_types: may define, predicates={:#?}" , predicates, ) ;
989- for & ( pred, _) in predicates. predicates {
990- let substituted_pred = pred. subst ( fcx. tcx , substs) ;
991- // Avoid duplication of predicates that contain no parameters, for example.
992- if !predicates. predicates . iter ( ) . any ( |& ( p, _) | p == substituted_pred) {
993- substituted_predicates. push ( substituted_pred) ;
973+ } // for (arg, param)
974+
975+ for ( _, indices) in seen_params {
976+ if indices. len ( ) > 1 {
977+ let descr = generics. param_at ( indices[ 0 ] , tcx) . kind . descr ( ) ;
978+ let spans: Vec < _ > = indices
979+ . into_iter ( )
980+ . map ( |i| tcx. def_span ( generics. param_at ( i, tcx) . def_id ) )
981+ . collect ( ) ;
982+ tcx. sess
983+ . struct_span_err ( span, "non-defining opaque type use in defining scope" )
984+ . span_note ( spans, & format ! ( "{} used multiple times" , descr) )
985+ . emit ( ) ;
994986 }
995987 }
996988 } // if let Opaque
@@ -999,7 +991,6 @@ fn check_opaque_types<'fcx, 'tcx>(
999991 lt_op : |lt| lt,
1000992 ct_op : |ct| ct,
1001993 } ) ;
1002- substituted_predicates
1003994}
1004995
1005996const HELP_FOR_SELF_TYPE : & str = "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
0 commit comments