@@ -33,8 +33,8 @@ use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
3333use crate :: {
3434 BindingKey , Determinacy , ExternPreludeEntry , Finalize , MacroData , Module , ModuleKind ,
3535 ModuleOrUniformRoot , NameBinding , NameBindingData , NameBindingKind , ParentScope , PathResult ,
36- ResolutionError , Resolver , ResolverArenas , Segment , ToNameBinding , Used , VisResolutionError ,
37- errors,
36+ ResolutionError , Resolver , ResolverArenas , RestrictionResolutionError , Segment , ToNameBinding ,
37+ Used , VisResolutionError , errors,
3838} ;
3939
4040type Res = def:: Res < NodeId > ;
@@ -322,9 +322,9 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
322322 } )
323323 }
324324 ast:: VisibilityKind :: Restricted { ref path, id, .. } => {
325- // For visibilities we are not ready to provide correct implementation of "uniform
325+ // For restrictions we are not ready to provide correct implementation of "uniform
326326 // paths" right now, so on 2018 edition we only allow module-relative paths for now.
327- // On 2015 edition visibilities are resolved as crate-relative by default,
327+ // On 2015 edition restrictions are resolved as crate-relative by default,
328328 // so we are prepending a root segment if necessary.
329329 let ident = path. segments . get ( 0 ) . expect ( "empty path in visibility" ) . ident ;
330330 let crate_root = if ident. is_path_segment_keyword ( ) {
@@ -406,6 +406,97 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
406406 self . r . field_names . insert ( def_id, fields) ;
407407 }
408408
409+ fn resolve_restriction ( & mut self , restriction : & ast:: Restriction ) -> ty:: Restriction {
410+ self . try_resolve_restriction ( restriction, true ) . unwrap_or_else ( |err| {
411+ self . r . report_restriction_error ( err) ;
412+ ty:: Restriction :: Unrestricted
413+ } )
414+ }
415+
416+ fn try_resolve_restriction < ' ast > (
417+ & mut self ,
418+ restriction : & ' ast ast:: Restriction ,
419+ finalize : bool ,
420+ ) -> Result < ty:: Restriction , RestrictionResolutionError < ' ast > > {
421+ let parent_scope = & self . parent_scope ;
422+ match restriction. kind {
423+ // If the restriction is implied, it has no effect when the item is otherwise visible.
424+ ast:: RestrictionKind :: Unrestricted | ast:: RestrictionKind :: Implied => {
425+ Ok ( ty:: Restriction :: Unrestricted )
426+ }
427+ ast:: RestrictionKind :: Restricted { ref path, id, shorthand : _ } => {
428+ // For restrictions we are not ready to provide correct implementation of "uniform
429+ // paths" right now, so on 2018 edition we only allow module-relative paths for now.
430+ // On 2015 edition visibilities are resolved as crate-relative by default,
431+ // so we are prepending a root segment if necessary.
432+ let ident = path. segments . get ( 0 ) . expect ( "empty path in restriction" ) . ident ;
433+ let crate_root = if ident. is_path_segment_keyword ( ) {
434+ None
435+ } else if ident. span . is_rust_2015 ( ) {
436+ Some ( Segment :: from_ident ( Ident :: new (
437+ kw:: PathRoot ,
438+ path. span . shrink_to_lo ( ) . with_ctxt ( ident. span . ctxt ( ) ) ,
439+ ) ) )
440+ } else {
441+ return Err ( RestrictionResolutionError :: Relative2018 ( ident. span , path) ) ;
442+ } ;
443+
444+ let segments = crate_root
445+ . into_iter ( )
446+ . chain ( path. segments . iter ( ) . map ( |seg| seg. into ( ) ) )
447+ . collect :: < Vec < _ > > ( ) ;
448+ let expected_found_error = |res| {
449+ Err ( RestrictionResolutionError :: ExpectedFound (
450+ path. span ,
451+ Segment :: names_to_string ( & segments) ,
452+ res,
453+ ) )
454+ } ;
455+ match self . r . resolve_path (
456+ & segments,
457+ Some ( TypeNS ) ,
458+ parent_scope,
459+ finalize. then ( || Finalize :: new ( id, path. span ) ) ,
460+ None ,
461+ None ,
462+ ) {
463+ PathResult :: Module ( ModuleOrUniformRoot :: Module ( module) ) => {
464+ let res = module. res ( ) . expect ( "restriction resolved to unnamed block" ) ;
465+ if finalize {
466+ self . r . record_partial_res ( id, PartialRes :: new ( res) ) ;
467+ }
468+ if module. is_normal ( ) {
469+ if res == Res :: Err {
470+ Ok ( ty:: Restriction :: Unrestricted )
471+ } else {
472+ let vis = ty:: Visibility :: Restricted ( res. def_id ( ) ) ;
473+ if self . r . is_accessible_from ( vis, parent_scope. module ) {
474+ Ok ( ty:: Restriction :: Restricted ( res. def_id ( ) , restriction. span ) )
475+ } else {
476+ Err ( RestrictionResolutionError :: AncestorOnly ( path. span ) )
477+ }
478+ }
479+ } else {
480+ expected_found_error ( res)
481+ }
482+ }
483+ PathResult :: Module ( ..) => {
484+ Err ( RestrictionResolutionError :: ModuleOnly ( path. span ) )
485+ }
486+ PathResult :: NonModule ( partial_res) => {
487+ expected_found_error ( partial_res. base_res ( ) )
488+ }
489+ PathResult :: Failed { span, label, suggestion, .. } => {
490+ Err ( RestrictionResolutionError :: FailedToResolve ( span, label, suggestion) )
491+ }
492+ PathResult :: Indeterminate => {
493+ Err ( RestrictionResolutionError :: Indeterminate ( path. span ) )
494+ }
495+ }
496+ }
497+ }
498+ }
499+
409500 fn insert_field_visibilities_local ( & mut self , def_id : DefId , fields : & [ ast:: FieldDef ] ) {
410501 let field_vis = fields
411502 . iter ( )
@@ -809,8 +900,21 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
809900 ItemKind :: TyAlias ( box TyAlias { ident, .. } ) | ItemKind :: TraitAlias ( ident, ..) => {
810901 self . r . define ( parent, ident, TypeNS , ( res, vis, sp, expansion) ) ;
811902 }
903+ ItemKind :: Trait ( box ast:: Trait { ident, ref impl_restriction, .. } ) => {
904+ let impl_restriction = self . resolve_restriction ( impl_restriction) ;
905+ self . r . impl_restrictions . insert ( local_def_id, impl_restriction) ;
812906
813- ItemKind :: Enum ( ident, _, _) | ItemKind :: Trait ( box ast:: Trait { ident, .. } ) => {
907+ let module = self . r . new_module (
908+ Some ( parent) ,
909+ ModuleKind :: Def ( def_kind, def_id, Some ( ident. name ) ) ,
910+ expansion. to_expn_id ( ) ,
911+ item. span ,
912+ parent. no_implicit_prelude ,
913+ ) ;
914+ self . r . define ( parent, ident, TypeNS , ( module, vis, sp, expansion) ) ;
915+ self . parent_scope . module = module;
916+ }
917+ ItemKind :: Enum ( ident, _, _) => {
814918 let module = self . r . new_module (
815919 Some ( parent) ,
816920 ModuleKind :: Def ( def_kind, def_id, Some ( ident. name ) ) ,
0 commit comments