@@ -22,7 +22,9 @@ use rustc_span::{sym, Span, DUMMY_SP};
22
22
23
23
use super :: ItemCtxt ;
24
24
use super :: { bad_placeholder, is_suggestable_infer_ty} ;
25
- use crate :: errors:: { OpaqueTypeConstrainedButNotInSig , UnconstrainedOpaqueType } ;
25
+ use crate :: errors:: {
26
+ OpaqueTypeConstrainedButNotInSig , OpaqueTypeConstrainedInNonSibling , UnconstrainedOpaqueType ,
27
+ } ;
26
28
27
29
/// Computes the relevant generic parameter for a potential generic const argument.
28
30
///
@@ -640,13 +642,20 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
640
642
let concrete_opaque_types = & self . tcx . mir_borrowck ( item_def_id) . concrete_opaque_types ;
641
643
debug ! ( ?concrete_opaque_types) ;
642
644
if let Some ( & concrete_type) = concrete_opaque_types. get ( & self . def_id ) {
643
- if let Err ( item_def_id) =
645
+ if let Err ( ( item_def_id, sibling ) ) =
644
646
may_define_opaque_type ( self . tcx , item_def_id, self . def_id , concrete_type. span )
645
647
{
646
- self . tcx . sess . emit_err ( OpaqueTypeConstrainedButNotInSig {
647
- span : concrete_type. span ,
648
- item_span : self . tcx . def_span ( item_def_id) ,
649
- } ) ;
648
+ if sibling {
649
+ self . tcx . sess . emit_err ( OpaqueTypeConstrainedButNotInSig {
650
+ span : concrete_type. span ,
651
+ item_span : self . tcx . def_span ( item_def_id) ,
652
+ } ) ;
653
+ } else {
654
+ self . tcx . sess . emit_err ( OpaqueTypeConstrainedInNonSibling {
655
+ span : concrete_type. span ,
656
+ item_span : self . tcx . def_span ( item_def_id) ,
657
+ } ) ;
658
+ }
650
659
}
651
660
debug ! ( ?concrete_type, "found constraint" ) ;
652
661
if let Some ( prev) = & mut self . found {
@@ -766,8 +775,27 @@ fn may_define_opaque_type<'tcx>(
766
775
def_id : LocalDefId ,
767
776
opaque_def_id : LocalDefId ,
768
777
span : Span ,
769
- ) -> Result < ( ) , LocalDefId > {
770
- if tcx. is_descendant_of ( opaque_def_id. to_def_id ( ) , def_id. to_def_id ( ) ) {
778
+ ) -> Result < ( ) , ( LocalDefId , bool ) > {
779
+ let mut parent = tcx. local_parent ( opaque_def_id) ;
780
+ loop {
781
+ trace ! ( ?parent) ;
782
+ match tcx. def_kind ( parent) {
783
+ DefKind :: AssocTy | DefKind :: TyAlias => {
784
+ parent = tcx. local_parent ( parent) ;
785
+ break ;
786
+ }
787
+ // Skip nested opaque types
788
+ DefKind :: OpaqueTy => {
789
+ parent = tcx. local_parent ( parent) ;
790
+ }
791
+ def_kind => {
792
+ trace ! ( ?def_kind) ;
793
+ return Err ( ( def_id, false ) ) ;
794
+ }
795
+ }
796
+ }
797
+ trace ! ( ?parent) ;
798
+ if parent == def_id {
771
799
// If the opaque type is defined in the body of a function, that function
772
800
// may constrain the opaque type since it can't mention it in bounds.
773
801
return Ok ( ( ) ) ;
@@ -777,9 +805,31 @@ fn may_define_opaque_type<'tcx>(
777
805
return may_define_opaque_type ( tcx, tcx. local_parent ( def_id) , opaque_def_id, span) ;
778
806
}
779
807
808
+ let mut item_parent = tcx. local_parent ( def_id) ;
809
+ while item_parent != parent {
810
+ trace ! ( ?item_parent) ;
811
+ match tcx. def_kind ( item_parent) {
812
+ // Skip impls, to allow methods to constrain opaque types from the surrounding module.
813
+ DefKind :: Impl { .. } | DefKind :: Trait => {
814
+ item_parent = tcx. local_parent ( item_parent) ;
815
+ }
816
+ // Skip modules, to allow constraining opaque types in child modules
817
+ DefKind :: Mod => {
818
+ item_parent = tcx. local_parent ( item_parent) ;
819
+ }
820
+ def_kind => {
821
+ trace ! ( ?def_kind) ;
822
+ break ;
823
+ }
824
+ }
825
+ }
826
+
827
+ if item_parent != parent {
828
+ return Err ( ( def_id, false ) ) ;
829
+ }
830
+
780
831
let param_env = tcx. param_env ( def_id) ;
781
832
782
- trace ! ( parent = ?tcx. parent( opaque_def_id. to_def_id( ) ) ) ;
783
833
fn has_tait < ' tcx > (
784
834
val : impl TypeVisitable < TyCtxt < ' tcx > > ,
785
835
opaque_def_id : LocalDefId ,
@@ -874,7 +924,7 @@ fn may_define_opaque_type<'tcx>(
874
924
let tait_in_where_bounds =
875
925
has_tait ( tcx. predicates_of ( def_id. to_def_id ( ) ) . predicates , opaque_def_id, tcx, param_env) ;
876
926
if tcx. features ( ) . type_alias_impl_trait_in_where_bounds {
877
- if tait_in_where_bounds { Ok ( ( ) ) } else { Err ( def_id) }
927
+ if tait_in_where_bounds { Ok ( ( ) ) } else { Err ( ( def_id, true ) ) }
878
928
} else {
879
929
if tait_in_where_bounds {
880
930
feature_err (
@@ -885,7 +935,7 @@ fn may_define_opaque_type<'tcx>(
885
935
)
886
936
. emit ( ) ;
887
937
}
888
- Err ( def_id)
938
+ Err ( ( def_id, true ) )
889
939
}
890
940
}
891
941
0 commit comments