@@ -801,18 +801,14 @@ fn check_where_clauses<'tcx, 'fcx>(
801
801
traits:: Obligation :: new ( cause, fcx. param_env , pred)
802
802
} ) ;
803
803
804
- let mut predicates = predicates. instantiate_identity ( fcx. tcx ) ;
804
+ let predicates = predicates. instantiate_identity ( fcx. tcx ) ;
805
805
806
806
if let Some ( ( mut return_ty, span) ) = return_ty {
807
807
if return_ty. has_infer_types_or_consts ( ) {
808
808
fcx. select_obligations_where_possible ( false , |_| { } ) ;
809
809
return_ty = fcx. resolve_vars_if_possible ( & return_ty) ;
810
810
}
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) ;
816
812
}
817
813
818
814
let predicates = fcx. normalize_associated_types_in ( span, & predicates) ;
@@ -884,113 +880,109 @@ fn check_opaque_types<'fcx, 'tcx>(
884
880
fn_def_id : LocalDefId ,
885
881
span : Span ,
886
882
ty : Ty < ' tcx > ,
887
- ) -> Vec < ty :: Predicate < ' tcx > > {
883
+ ) {
888
884
trace ! ( "check_opaque_types(ty={:?})" , ty) ;
889
- let mut substituted_predicates = Vec :: new ( ) ;
890
885
ty. fold_with ( & mut ty:: fold:: BottomUpFolder {
891
886
tcx : fcx. tcx ,
892
887
ty_op : |ty| {
893
888
if let ty:: Opaque ( def_id, substs) = ty. kind {
894
889
trace ! ( "check_opaque_types: opaque_ty, {:?}, {:?}" , def_id, substs) ;
895
890
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.
898
896
return ty;
899
- }
900
- let opaque_hir_id = tcx. hir ( ) . as_local_hir_id ( def_id. expect_local ( ) ) ;
897
+ } ;
901
898
if let hir:: ItemKind :: OpaqueTy ( hir:: OpaqueTy { impl_trait_fn : Some ( _) , .. } ) =
902
899
tcx. hir ( ) . expect_item ( opaque_hir_id) . kind
903
900
{
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) {
905
925
return ty;
906
926
}
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 \
924
943
instead or remove the lifetime parameter from the \
925
944
opaque type",
926
- )
927
- . emit ( ) ;
928
- continue ;
929
- }
930
-
931
- true
945
+ )
946
+ . emit ( ) ;
947
+ continue ;
932
948
}
933
949
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
973
951
}
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 ( ) ;
974
972
}
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 ( ) ;
994
986
}
995
987
}
996
988
} // if let Opaque
@@ -999,7 +991,6 @@ fn check_opaque_types<'fcx, 'tcx>(
999
991
lt_op : |lt| lt,
1000
992
ct_op : |ct| ct,
1001
993
} ) ;
1002
- substituted_predicates
1003
994
}
1004
995
1005
996
const HELP_FOR_SELF_TYPE : & str = "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
0 commit comments