@@ -2,6 +2,7 @@ use crate::ty::TyCtxt;
2
2
3
3
use super :: ScalarInt ;
4
4
use rustc_macros:: HashStable ;
5
+ use rustc_span:: Symbol ;
5
6
6
7
#[ derive( Copy , Clone , Debug , Hash , TyEncodable , TyDecodable , Eq , PartialEq , Ord , PartialOrd ) ]
7
8
#[ derive( HashStable ) ]
@@ -30,33 +31,42 @@ pub enum ValTree<'tcx> {
30
31
/// Enums are represented by storing their discriminant as a field, followed by all
31
32
/// the fields of the variant.
32
33
///
33
- /// `&str` and `& [T]` are encoded as if they were `&[T;N]`. So there is no wide pointer
34
+ /// `&[T]` are encoded as if they were `&[T;N]`. So there is no wide pointer
34
35
/// or metadata encoded, instead the length is taken directly from the number of elements
35
36
/// in the branch.
36
37
Branch ( & ' tcx [ ValTree < ' tcx > ] ) ,
38
+ /// `&str` could be encoded as a `Branch`, but the back and forth between valtree
39
+ /// representations and other representations of `str` is expensive.
40
+ Str ( Symbol ) ,
37
41
}
38
42
39
43
impl ValTree < ' tcx > {
40
44
pub fn zst ( ) -> Self {
41
45
Self :: Branch ( & [ ] )
42
46
}
47
+ pub fn unwrap_str ( self ) -> Symbol {
48
+ match self {
49
+ Self :: Str ( s) => s,
50
+ _ => bug ! ( "expected str, got {:?}" , self ) ,
51
+ }
52
+ }
43
53
pub fn unwrap_leaf ( self ) -> ScalarInt {
44
54
match self {
45
55
Self :: Leaf ( s) => s,
46
- Self :: Branch ( branch ) => bug ! ( "expected leaf, got {:?}" , branch ) ,
56
+ _ => bug ! ( "expected leaf, got {:?}" , self ) ,
47
57
}
48
58
}
49
59
pub fn unwrap_branch ( self ) -> & ' tcx [ Self ] {
50
60
match self {
51
- Self :: Leaf ( s) => bug ! ( "expected branch, got {:?}" , s) ,
52
61
Self :: Branch ( branch) => branch,
62
+ _ => bug ! ( "expected branch, got {:?}" , self ) ,
53
63
}
54
64
}
55
65
#[ inline]
56
66
pub fn try_to_scalar_int ( self ) -> Option < ScalarInt > {
57
67
match self {
58
68
Self :: Leaf ( s) => Some ( s) ,
59
- Self :: Branch ( _) => None ,
69
+ Self :: Str ( _ ) | Self :: Branch ( _) => None ,
60
70
}
61
71
}
62
72
0 commit comments