4
4
5
5
use std:: fmt:: { self , Debug } ;
6
6
7
+ use base_db:: CrateId ;
7
8
use chalk_ir:: BoundVar ;
8
9
use hir_def:: {
9
10
body,
@@ -15,7 +16,7 @@ use hir_def::{
15
16
path:: { Path , PathKind } ,
16
17
type_ref:: { TraitBoundModifier , TypeBound , TypeRef } ,
17
18
visibility:: Visibility ,
18
- AssocContainerId , Lookup , ModuleId , TraitId ,
19
+ AssocContainerId , HasModule , Lookup , ModuleId , TraitId ,
19
20
} ;
20
21
use hir_expand:: { hygiene:: Hygiene , name:: Name } ;
21
22
use itertools:: Itertools ;
@@ -582,10 +583,11 @@ impl HirDisplay for Ty {
582
583
. as_ref ( )
583
584
. map ( |rpit| rpit. impl_traits [ idx as usize ] . bounds . clone ( ) ) ;
584
585
let bounds = data. substitute ( & Interner , & parameters) ;
586
+ let krate = func. lookup ( f. db . upcast ( ) ) . module ( f. db . upcast ( ) ) . krate ( ) ;
585
587
write_bounds_like_dyn_trait_with_prefix (
586
588
"impl" ,
587
589
bounds. skip_binders ( ) ,
588
- SizedByDefault :: Sized ,
590
+ SizedByDefault :: Sized { anchor : krate } ,
589
591
f,
590
592
) ?;
591
593
// FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
@@ -646,10 +648,11 @@ impl HirDisplay for Ty {
646
648
_ => false ,
647
649
} )
648
650
. collect :: < Vec < _ > > ( ) ;
651
+ let krate = id. parent . module ( f. db . upcast ( ) ) . krate ( ) ;
649
652
write_bounds_like_dyn_trait_with_prefix (
650
653
"impl" ,
651
654
& bounds,
652
- SizedByDefault :: Sized ,
655
+ SizedByDefault :: Sized { anchor : krate } ,
653
656
f,
654
657
) ?;
655
658
}
@@ -675,10 +678,11 @@ impl HirDisplay for Ty {
675
678
. as_ref ( )
676
679
. map ( |rpit| rpit. impl_traits [ idx as usize ] . bounds . clone ( ) ) ;
677
680
let bounds = data. substitute ( & Interner , & opaque_ty. substitution ) ;
681
+ let krate = func. lookup ( f. db . upcast ( ) ) . module ( f. db . upcast ( ) ) . krate ( ) ;
678
682
write_bounds_like_dyn_trait_with_prefix (
679
683
"impl" ,
680
684
bounds. skip_binders ( ) ,
681
- SizedByDefault :: Sized ,
685
+ SizedByDefault :: Sized { anchor : krate } ,
682
686
f,
683
687
) ?;
684
688
}
@@ -729,17 +733,23 @@ fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator<Item = Trai
729
733
utils:: fn_traits ( db, krate)
730
734
}
731
735
732
- fn is_sized_trait ( db : & dyn DefDatabase , trait_ : TraitId ) -> Option < bool > {
733
- let krate = trait_. lookup ( db) . container . krate ( ) ;
734
- let sized_trait =
735
- db. lang_item ( krate, "sized" . into ( ) ) . and_then ( |lang_item| lang_item. as_trait ( ) ) ?;
736
- Some ( trait_ == sized_trait)
737
- }
738
-
739
736
#[ derive( Clone , Copy , PartialEq , Eq ) ]
740
737
pub enum SizedByDefault {
741
738
NotSized ,
742
- Sized ,
739
+ Sized { anchor : CrateId } ,
740
+ }
741
+
742
+ impl SizedByDefault {
743
+ fn is_sized_trait ( self , trait_ : TraitId , db : & dyn DefDatabase ) -> bool {
744
+ match self {
745
+ Self :: NotSized => false ,
746
+ Self :: Sized { anchor } => {
747
+ let sized_trait =
748
+ db. lang_item ( anchor, "sized" . into ( ) ) . and_then ( |lang_item| lang_item. as_trait ( ) ) ;
749
+ Some ( trait_) == sized_trait
750
+ }
751
+ }
752
+ }
743
753
}
744
754
745
755
pub fn write_bounds_like_dyn_trait_with_prefix (
@@ -749,7 +759,9 @@ pub fn write_bounds_like_dyn_trait_with_prefix(
749
759
f : & mut HirFormatter ,
750
760
) -> Result < ( ) , HirDisplayError > {
751
761
write ! ( f, "{}" , prefix) ?;
752
- if !predicates. is_empty ( ) {
762
+ if !predicates. is_empty ( )
763
+ || predicates. is_empty ( ) && matches ! ( default_sized, SizedByDefault :: Sized { .. } )
764
+ {
753
765
write ! ( f, " " ) ?;
754
766
write_bounds_like_dyn_trait ( predicates, default_sized, f)
755
767
} else {
@@ -771,22 +783,18 @@ fn write_bounds_like_dyn_trait(
771
783
let mut first = true ;
772
784
let mut angle_open = false ;
773
785
let mut is_fn_trait = false ;
774
- let mut is_sized = None ;
786
+ let mut is_sized = false ;
775
787
for p in predicates. iter ( ) {
776
788
match p. skip_binders ( ) {
777
789
WhereClause :: Implemented ( trait_ref) => {
778
790
let trait_ = trait_ref. hir_trait_id ( ) ;
779
- match is_sized_trait ( f. db . upcast ( ) , trait_) {
780
- Some ( true ) => {
781
- is_sized = Some ( true ) ;
782
- if default_sized == SizedByDefault :: Sized {
791
+ if default_sized. is_sized_trait ( trait_, f. db . upcast ( ) ) {
792
+ is_sized = true ;
793
+ if matches ! ( default_sized, SizedByDefault :: Sized { .. } ) {
783
794
// Don't print +Sized, but rather +?Sized if absent.
784
795
continue ;
785
796
}
786
797
}
787
- Some ( false ) => is_sized = is_sized. or ( Some ( false ) ) ,
788
- None => ( ) ,
789
- }
790
798
if !is_fn_trait {
791
799
is_fn_trait = fn_traits ( f. db . upcast ( ) , trait_) . any ( |it| it == trait_) ;
792
800
}
@@ -851,8 +859,8 @@ fn write_bounds_like_dyn_trait(
851
859
if angle_open {
852
860
write ! ( f, ">" ) ?;
853
861
}
854
- if default_sized == SizedByDefault :: Sized && is_sized . is_some ( ) {
855
- if is_sized == Some ( false ) {
862
+ if matches ! ( default_sized, SizedByDefault :: Sized { .. } ) {
863
+ if ! is_sized {
856
864
write ! ( f, "{}?Sized" , if first { "" } else { " + " } ) ?;
857
865
} else if first {
858
866
write ! ( f, "Sized" ) ?;
0 commit comments