@@ -33,8 +33,8 @@ use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
33
33
use crate :: {
34
34
BindingKey , Determinacy , ExternPreludeEntry , Finalize , MacroData , Module , ModuleKind ,
35
35
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,
38
38
} ;
39
39
40
40
type Res = def:: Res < NodeId > ;
@@ -322,9 +322,9 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
322
322
} )
323
323
}
324
324
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
326
326
// 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,
328
328
// so we are prepending a root segment if necessary.
329
329
let ident = path. segments . get ( 0 ) . expect ( "empty path in visibility" ) . ident ;
330
330
let crate_root = if ident. is_path_segment_keyword ( ) {
@@ -406,6 +406,97 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
406
406
self . r . field_names . insert ( def_id, fields) ;
407
407
}
408
408
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
+
409
500
fn insert_field_visibilities_local ( & mut self , def_id : DefId , fields : & [ ast:: FieldDef ] ) {
410
501
let field_vis = fields
411
502
. iter ( )
@@ -809,8 +900,21 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
809
900
ItemKind :: TyAlias ( box TyAlias { ident, .. } ) | ItemKind :: TraitAlias ( ident, ..) => {
810
901
self . r . define ( parent, ident, TypeNS , ( res, vis, sp, expansion) ) ;
811
902
}
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) ;
812
906
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, _, _) => {
814
918
let module = self . r . new_module (
815
919
Some ( parent) ,
816
920
ModuleKind :: Def ( def_kind, def_id, Some ( ident. name ) ) ,
0 commit comments