@@ -29,7 +29,7 @@ use crate::{
2929 infer:: PointerCast ,
3030 layout:: { Layout , LayoutError , RustcEnumVariantIdx } ,
3131 mapping:: from_chalk,
32- method_resolution:: is_dyn_method,
32+ method_resolution:: { is_dyn_method, lookup_impl_const } ,
3333 name, static_lifetime,
3434 traits:: FnTrait ,
3535 utils:: { detect_variant_from_bytes, ClosureSubst } ,
@@ -1571,35 +1571,51 @@ impl Evaluator<'_> {
15711571 let chalk_ir:: ConstValue :: Concrete ( c) = & konst. data ( Interner ) . value else {
15721572 not_supported ! ( "evaluating non concrete constant" ) ;
15731573 } ;
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) )
15811588 } ) ?;
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) ;
15911592 }
15921593 }
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" ) ;
16001595 }
16011596 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) )
16031619 }
16041620
16051621 fn eval_place ( & mut self , p : & Place , locals : & Locals ) -> Result < Interval > {
0 commit comments