@@ -161,14 +161,28 @@ pub enum Ty {
161
161
name : Name ,
162
162
} ,
163
163
164
- /// A bound type variable. Only used during trait resolution to represent
165
- /// Chalk variables.
164
+ /// A bound type variable. Used during trait resolution to represent Chalk
165
+ /// variables, and in `Dyn` and `Opaque` bounds to represent the `Self` type .
166
166
Bound ( u32 ) ,
167
167
168
168
/// A type variable used during type checking. Not to be confused with a
169
169
/// type parameter.
170
170
Infer ( InferTy ) ,
171
171
172
+ /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust).
173
+ ///
174
+ /// The predicates are quantified over the `Self` type, i.e. `Ty::Bound(0)`
175
+ /// represents the `Self` type inside the bounds. This is currently
176
+ /// implicit; Chalk has the `Binders` struct to make it explicit, but it
177
+ /// didn't seem worth the overhead yet.
178
+ Dyn ( Arc < [ GenericPredicate ] > ) ,
179
+
180
+ /// An opaque type (`impl Trait`).
181
+ ///
182
+ /// The predicates are quantified over the `Self` type; see `Ty::Dyn` for
183
+ /// more.
184
+ Opaque ( Arc < [ GenericPredicate ] > ) ,
185
+
172
186
/// A placeholder for a type which could not be computed; this is propagated
173
187
/// to avoid useless error messages. Doubles as a placeholder where type
174
188
/// variables are inserted before type checking, since we want to try to
@@ -194,6 +208,12 @@ impl Substs {
194
208
Substs ( self . 0 . iter ( ) . cloned ( ) . take ( n) . collect :: < Vec < _ > > ( ) . into ( ) )
195
209
}
196
210
211
+ pub fn walk ( & self , f : & mut impl FnMut ( & Ty ) ) {
212
+ for t in self . 0 . iter ( ) {
213
+ t. walk ( f) ;
214
+ }
215
+ }
216
+
197
217
pub fn walk_mut ( & mut self , f : & mut impl FnMut ( & mut Ty ) ) {
198
218
// Without an Arc::make_mut_slice, we can't avoid the clone here:
199
219
let mut v: Vec < _ > = self . 0 . iter ( ) . cloned ( ) . collect ( ) ;
@@ -270,6 +290,14 @@ impl TraitRef {
270
290
} ) ;
271
291
self
272
292
}
293
+
294
+ pub fn walk ( & self , f : & mut impl FnMut ( & Ty ) ) {
295
+ self . substs . walk ( f) ;
296
+ }
297
+
298
+ pub fn walk_mut ( & mut self , f : & mut impl FnMut ( & mut Ty ) ) {
299
+ self . substs . walk_mut ( f) ;
300
+ }
273
301
}
274
302
275
303
/// Like `generics::WherePredicate`, but with resolved types: A condition on the
@@ -299,6 +327,20 @@ impl GenericPredicate {
299
327
GenericPredicate :: Error => self ,
300
328
}
301
329
}
330
+
331
+ pub fn walk ( & self , f : & mut impl FnMut ( & Ty ) ) {
332
+ match self {
333
+ GenericPredicate :: Implemented ( trait_ref) => trait_ref. walk ( f) ,
334
+ GenericPredicate :: Error => { }
335
+ }
336
+ }
337
+
338
+ pub fn walk_mut ( & mut self , f : & mut impl FnMut ( & mut Ty ) ) {
339
+ match self {
340
+ GenericPredicate :: Implemented ( trait_ref) => trait_ref. walk_mut ( f) ,
341
+ GenericPredicate :: Error => { }
342
+ }
343
+ }
302
344
}
303
345
304
346
/// Basically a claim (currently not validated / checked) that the contained
@@ -386,6 +428,11 @@ impl Ty {
386
428
t. walk ( f) ;
387
429
}
388
430
}
431
+ Ty :: Dyn ( predicates) | Ty :: Opaque ( predicates) => {
432
+ for p in predicates. iter ( ) {
433
+ p. walk ( f) ;
434
+ }
435
+ }
389
436
Ty :: Param { .. } | Ty :: Bound ( _) | Ty :: Infer ( _) | Ty :: Unknown => { }
390
437
}
391
438
f ( self ) ;
@@ -402,6 +449,13 @@ impl Ty {
402
449
Ty :: UnselectedProjection ( p_ty) => {
403
450
p_ty. parameters . walk_mut ( f) ;
404
451
}
452
+ Ty :: Dyn ( predicates) | Ty :: Opaque ( predicates) => {
453
+ let mut v: Vec < _ > = predicates. iter ( ) . cloned ( ) . collect ( ) ;
454
+ for p in & mut v {
455
+ p. walk_mut ( f) ;
456
+ }
457
+ * predicates = v. into ( ) ;
458
+ }
405
459
Ty :: Param { .. } | Ty :: Bound ( _) | Ty :: Infer ( _) | Ty :: Unknown => { }
406
460
}
407
461
f ( self ) ;
@@ -529,6 +583,19 @@ impl Ty {
529
583
ty => ty,
530
584
} )
531
585
}
586
+
587
+ /// If this is an `impl Trait` or `dyn Trait`, returns that trait.
588
+ pub fn inherent_trait ( & self ) -> Option < Trait > {
589
+ match self {
590
+ Ty :: Dyn ( predicates) | Ty :: Opaque ( predicates) => {
591
+ predicates. iter ( ) . find_map ( |pred| match pred {
592
+ GenericPredicate :: Implemented ( tr) => Some ( tr. trait_ ) ,
593
+ _ => None ,
594
+ } )
595
+ }
596
+ _ => None ,
597
+ }
598
+ }
532
599
}
533
600
534
601
impl HirDisplay for & Ty {
@@ -669,21 +736,45 @@ impl HirDisplay for Ty {
669
736
Ty :: UnselectedProjection ( p_ty) => p_ty. hir_fmt ( f) ?,
670
737
Ty :: Param { name, .. } => write ! ( f, "{}" , name) ?,
671
738
Ty :: Bound ( idx) => write ! ( f, "?{}" , idx) ?,
739
+ Ty :: Dyn ( predicates) | Ty :: Opaque ( predicates) => {
740
+ match self {
741
+ Ty :: Dyn ( _) => write ! ( f, "dyn " ) ?,
742
+ Ty :: Opaque ( _) => write ! ( f, "impl " ) ?,
743
+ _ => unreachable ! ( ) ,
744
+ } ;
745
+ // looping by hand here just to format the bounds in a slightly nicer way
746
+ let mut first = true ;
747
+ for p in predicates. iter ( ) {
748
+ if !first {
749
+ write ! ( f, " + " ) ?;
750
+ }
751
+ first = false ;
752
+ match p {
753
+ // don't show the $0 self type
754
+ GenericPredicate :: Implemented ( trait_ref) => {
755
+ trait_ref. hir_fmt_ext ( f, false ) ?
756
+ }
757
+ GenericPredicate :: Error => p. hir_fmt ( f) ?,
758
+ }
759
+ }
760
+ }
672
761
Ty :: Unknown => write ! ( f, "{{unknown}}" ) ?,
673
762
Ty :: Infer ( ..) => write ! ( f, "_" ) ?,
674
763
}
675
764
Ok ( ( ) )
676
765
}
677
766
}
678
767
679
- impl HirDisplay for TraitRef {
680
- fn hir_fmt ( & self , f : & mut HirFormatter < impl HirDatabase > ) -> fmt:: Result {
681
- write ! (
682
- f,
683
- "{}: {}" ,
684
- self . substs[ 0 ] . display( f. db) ,
685
- self . trait_. name( f. db) . unwrap_or_else( Name :: missing)
686
- ) ?;
768
+ impl TraitRef {
769
+ fn hir_fmt_ext (
770
+ & self ,
771
+ f : & mut HirFormatter < impl HirDatabase > ,
772
+ with_self_ty : bool ,
773
+ ) -> fmt:: Result {
774
+ if with_self_ty {
775
+ write ! ( f, "{}: " , self . substs[ 0 ] . display( f. db) , ) ?;
776
+ }
777
+ write ! ( f, "{}" , self . trait_. name( f. db) . unwrap_or_else( Name :: missing) ) ?;
687
778
if self . substs . len ( ) > 1 {
688
779
write ! ( f, "<" ) ?;
689
780
f. write_joined ( & self . substs [ 1 ..] , ", " ) ?;
@@ -693,6 +784,28 @@ impl HirDisplay for TraitRef {
693
784
}
694
785
}
695
786
787
+ impl HirDisplay for TraitRef {
788
+ fn hir_fmt ( & self , f : & mut HirFormatter < impl HirDatabase > ) -> fmt:: Result {
789
+ self . hir_fmt_ext ( f, true )
790
+ }
791
+ }
792
+
793
+ impl HirDisplay for & GenericPredicate {
794
+ fn hir_fmt ( & self , f : & mut HirFormatter < impl HirDatabase > ) -> fmt:: Result {
795
+ HirDisplay :: hir_fmt ( * self , f)
796
+ }
797
+ }
798
+
799
+ impl HirDisplay for GenericPredicate {
800
+ fn hir_fmt ( & self , f : & mut HirFormatter < impl HirDatabase > ) -> fmt:: Result {
801
+ match self {
802
+ GenericPredicate :: Implemented ( trait_ref) => trait_ref. hir_fmt ( f) ?,
803
+ GenericPredicate :: Error => write ! ( f, "{{error}}" ) ?,
804
+ }
805
+ Ok ( ( ) )
806
+ }
807
+ }
808
+
696
809
impl HirDisplay for Obligation {
697
810
fn hir_fmt ( & self , f : & mut HirFormatter < impl HirDatabase > ) -> fmt:: Result {
698
811
match self {
0 commit comments