@@ -26,7 +26,7 @@ use super::{
2626 FnDeclKind , GenericArgsMode , ImplTraitContext , ImplTraitPosition , LoweringContext , ParamMode ,
2727 RelaxedBoundForbiddenReason , RelaxedBoundPolicy ,
2828} ;
29- use crate :: diagnostics:: ConstComptimeFn ;
29+ use crate :: diagnostics:: { ConstComptimeFn , ResolvingRestrictionKind , RestrictionAncestorOnly } ;
3030
3131pub ( super ) struct ItemLowerer < ' a , ' hir > {
3232 pub ( super ) tcx : TyCtxt < ' hir > ,
@@ -498,7 +498,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
498498 items,
499499 } ) => {
500500 let constness = self . lower_constness ( attrs, * constness) ;
501- let impl_restriction = self . lower_impl_restriction ( impl_restriction) ;
501+ let impl_restriction = self . lower_impl_restriction ( impl_restriction, hir_id ) ;
502502 let ident = self . lower_ident ( * ident) ;
503503 let ( generics, ( safety, items, bounds) ) = self . lower_generics (
504504 generics,
@@ -895,7 +895,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
895895 None => Ident :: new ( sym:: integer ( index) , self . lower_span ( f. span ) ) ,
896896 } ,
897897 vis_span : self . lower_span ( f. vis . span ) ,
898- mut_restriction : self . lower_mut_restriction ( f. mut_restriction ( ) ) ,
898+ mut_restriction : self . lower_mut_restriction ( f. mut_restriction ( ) , hir_id ) ,
899899 default : f
900900 . default_value ( )
901901 . map ( |v| self . lower_anon_const_to_anon_const ( v, v. value . span ) ) ,
@@ -1797,26 +1797,46 @@ impl<'hir> LoweringContext<'_, 'hir> {
17971797 }
17981798 }
17991799
1800- fn lower_restriction_kind ( & mut self , kind : & RestrictionKind ) -> hir:: RestrictionKind < ' hir > {
1801- match kind {
1800+ fn lower_restriction_kind (
1801+ & mut self ,
1802+ restriction_kind : & RestrictionKind ,
1803+ hir_id : HirId ,
1804+ resolving_kind : ResolvingRestrictionKind ,
1805+ ) -> hir:: RestrictionKind < ' hir > {
1806+ match restriction_kind {
18021807 RestrictionKind :: Unrestricted => hir:: RestrictionKind :: Unrestricted ,
18031808 RestrictionKind :: Restricted { path, id, shorthand : _ } => {
18041809 let res = self . get_partial_res ( * id) ;
1810+ let parent_module = self . tcx . parent_module ( hir_id) ;
18051811 if let Some ( did) = res. and_then ( |res| res. expect_full_res ( ) . opt_def_id ( ) ) {
1806- hir:: RestrictionKind :: Restricted ( self . arena . alloc ( hir:: Path {
1807- res : did,
1808- segments : self . arena . alloc_from_iter ( path. segments . iter ( ) . map ( |segment| {
1809- self . lower_path_segment (
1810- path. span ,
1811- segment,
1812- ParamMode :: Explicit ,
1813- GenericArgsMode :: Err ,
1814- ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
1815- None ,
1816- )
1817- } ) ) ,
1818- span : self . lower_span ( path. span ) ,
1819- } ) )
1812+ if !self . tcx . is_descendant_of ( parent_module, did) {
1813+ // If the restriction path is not an ancestor of the item,
1814+ // emit an error and recover by lowering the restriction to `Unrestricted`.
1815+ self . dcx ( )
1816+ . create_err ( RestrictionAncestorOnly {
1817+ span : path. span ,
1818+ kind : resolving_kind,
1819+ } )
1820+ . emit ( ) ;
1821+ hir:: RestrictionKind :: Unrestricted
1822+ } else {
1823+ hir:: RestrictionKind :: Restricted ( self . arena . alloc ( hir:: Path {
1824+ res : did,
1825+ segments : self . arena . alloc_from_iter ( path. segments . iter ( ) . map (
1826+ |segment| {
1827+ self . lower_path_segment (
1828+ path. span ,
1829+ segment,
1830+ ParamMode :: Explicit ,
1831+ GenericArgsMode :: Err ,
1832+ ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
1833+ None ,
1834+ )
1835+ } ,
1836+ ) ) ,
1837+ span : self . lower_span ( path. span ) ,
1838+ } ) )
1839+ }
18201840 } else {
18211841 self . dcx ( ) . span_delayed_bug ( path. span , "should have errored in resolve" ) ;
18221842 hir:: RestrictionKind :: Unrestricted
@@ -1828,16 +1848,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
18281848 pub ( super ) fn lower_impl_restriction (
18291849 & mut self ,
18301850 r : & ImplRestriction ,
1851+ hir_id : HirId ,
18311852 ) -> & ' hir hir:: ImplRestriction < ' hir > {
1832- let kind = self . lower_restriction_kind ( & r. kind ) ;
1853+ let kind = self . lower_restriction_kind ( & r. kind , hir_id , ResolvingRestrictionKind :: Impl ) ;
18331854 self . arena . alloc ( hir:: ImplRestriction { kind, span : self . lower_span ( r. span ) } )
18341855 }
18351856
18361857 pub ( super ) fn lower_mut_restriction (
18371858 & mut self ,
18381859 r : & MutRestriction ,
1860+ hir_id : HirId ,
18391861 ) -> & ' hir hir:: MutRestriction < ' hir > {
1840- let kind = self . lower_restriction_kind ( & r. kind ) ;
1862+ let kind = self . lower_restriction_kind ( & r. kind , hir_id , ResolvingRestrictionKind :: Mut ) ;
18411863 self . arena . alloc ( hir:: MutRestriction { kind, span : self . lower_span ( r. span ) } )
18421864 }
18431865
0 commit comments