@@ -29,7 +29,7 @@ use crate::{
29
29
infer:: PointerCast ,
30
30
layout:: { Layout , LayoutError , RustcEnumVariantIdx } ,
31
31
mapping:: from_chalk,
32
- method_resolution:: is_dyn_method,
32
+ method_resolution:: { is_dyn_method, lookup_impl_const } ,
33
33
name, static_lifetime,
34
34
traits:: FnTrait ,
35
35
utils:: { detect_variant_from_bytes, ClosureSubst } ,
@@ -1571,35 +1571,51 @@ impl Evaluator<'_> {
1571
1571
let chalk_ir:: ConstValue :: Concrete ( c) = & konst. data ( Interner ) . value else {
1572
1572
not_supported ! ( "evaluating non concrete constant" ) ;
1573
1573
} ;
1574
- Ok ( match & c. interned {
1575
- ConstScalar :: Bytes ( v, memory_map) => {
1576
- let mut v: Cow < ' _ , [ u8 ] > = Cow :: Borrowed ( v) ;
1577
- let patch_map = memory_map. transform_addresses ( |b, align| {
1578
- let addr = self . heap_allocate ( b. len ( ) , align) ?;
1579
- self . write_memory ( addr, b) ?;
1580
- Ok ( addr. to_usize ( ) )
1574
+ let result_owner;
1575
+ let ( v, memory_map) = match & c. interned {
1576
+ ConstScalar :: Bytes ( v, mm) => ( v, mm) ,
1577
+ ConstScalar :: UnevaluatedConst ( const_id, subst) => ' b: {
1578
+ let mut const_id = * const_id;
1579
+ let mut subst = subst. clone ( ) ;
1580
+ if let hir_def:: GeneralConstId :: ConstId ( c) = const_id {
1581
+ let ( c, s) = lookup_impl_const ( self . db , self . trait_env . clone ( ) , c, subst) ;
1582
+ const_id = hir_def:: GeneralConstId :: ConstId ( c) ;
1583
+ subst = s;
1584
+ }
1585
+ result_owner = self . db . const_eval ( const_id. into ( ) , subst) . map_err ( |e| {
1586
+ let name = const_id. name ( self . db . upcast ( ) ) ;
1587
+ MirEvalError :: ConstEvalError ( name, Box :: new ( e) )
1581
1588
} ) ?;
1582
- let ( size, align) = self . size_align_of ( ty, locals) ?. unwrap_or ( ( v. len ( ) , 1 ) ) ;
1583
- if size != v. len ( ) {
1584
- // Handle self enum
1585
- if size == 16 && v. len ( ) < 16 {
1586
- v = Cow :: Owned ( pad16 ( & v, false ) . to_vec ( ) ) ;
1587
- } else if size < 16 && v. len ( ) == 16 {
1588
- v = Cow :: Owned ( v[ 0 ..size] . to_vec ( ) ) ;
1589
- } else {
1590
- return Err ( MirEvalError :: InvalidConst ( konst. clone ( ) ) ) ;
1589
+ if let chalk_ir:: ConstValue :: Concrete ( c) = & result_owner. data ( Interner ) . value {
1590
+ if let ConstScalar :: Bytes ( v, mm) = & c. interned {
1591
+ break ' b ( v, mm) ;
1591
1592
}
1592
1593
}
1593
- let addr = self . heap_allocate ( size, align) ?;
1594
- self . write_memory ( addr, & v) ?;
1595
- self . patch_addresses ( & patch_map, & memory_map. vtable , addr, ty, locals) ?;
1596
- Interval :: new ( addr, size)
1597
- }
1598
- ConstScalar :: UnevaluatedConst ( ..) => {
1599
- not_supported ! ( "unevaluated const present in monomorphized mir" ) ;
1594
+ not_supported ! ( "unevaluatable constant" ) ;
1600
1595
}
1601
1596
ConstScalar :: Unknown => not_supported ! ( "evaluating unknown const" ) ,
1602
- } )
1597
+ } ;
1598
+ let mut v: Cow < ' _ , [ u8 ] > = Cow :: Borrowed ( v) ;
1599
+ let patch_map = memory_map. transform_addresses ( |b, align| {
1600
+ let addr = self . heap_allocate ( b. len ( ) , align) ?;
1601
+ self . write_memory ( addr, b) ?;
1602
+ Ok ( addr. to_usize ( ) )
1603
+ } ) ?;
1604
+ let ( size, align) = self . size_align_of ( ty, locals) ?. unwrap_or ( ( v. len ( ) , 1 ) ) ;
1605
+ if size != v. len ( ) {
1606
+ // Handle self enum
1607
+ if size == 16 && v. len ( ) < 16 {
1608
+ v = Cow :: Owned ( pad16 ( & v, false ) . to_vec ( ) ) ;
1609
+ } else if size < 16 && v. len ( ) == 16 {
1610
+ v = Cow :: Owned ( v[ 0 ..size] . to_vec ( ) ) ;
1611
+ } else {
1612
+ return Err ( MirEvalError :: InvalidConst ( konst. clone ( ) ) ) ;
1613
+ }
1614
+ }
1615
+ let addr = self . heap_allocate ( size, align) ?;
1616
+ self . write_memory ( addr, & v) ?;
1617
+ self . patch_addresses ( & patch_map, & memory_map. vtable , addr, ty, locals) ?;
1618
+ Ok ( Interval :: new ( addr, size) )
1603
1619
}
1604
1620
1605
1621
fn eval_place ( & mut self , p : & Place , locals : & Locals ) -> Result < Interval > {
0 commit comments