@@ -1799,7 +1799,7 @@ impl Evaluator<'_> {
17991799 match def {
18001800 CallableDefId :: FunctionId ( def) => {
18011801 if let Some ( _) = self . detect_fn_trait ( def) {
1802- self . exec_fn_trait ( & args, destination , locals, span) ?;
1802+ self . exec_fn_trait ( def , args, generic_args , locals, destination , span) ?;
18031803 return Ok ( ( ) ) ;
18041804 }
18051805 self . exec_fn_with_args ( def, args, generic_args, locals, destination, span) ?;
@@ -1921,9 +1921,11 @@ impl Evaluator<'_> {
19211921
19221922 fn exec_fn_trait (
19231923 & mut self ,
1924+ def : FunctionId ,
19241925 args : & [ IntervalAndTy ] ,
1925- destination : Interval ,
1926+ generic_args : Substitution ,
19261927 locals : & Locals < ' _ > ,
1928+ destination : Interval ,
19271929 span : MirSpan ,
19281930 ) -> Result < ( ) > {
19291931 let func = args. get ( 0 ) . ok_or ( MirEvalError :: TypeError ( "fn trait with no arg" ) ) ?;
@@ -1958,7 +1960,38 @@ impl Evaluator<'_> {
19581960 span,
19591961 ) ?;
19601962 }
1961- x => not_supported ! ( "Call FnTrait methods with type {x:?}" ) ,
1963+ _ => {
1964+ // try to execute the manual impl of `FnTrait` for structs (nightly feature used in std)
1965+ let arg0 = func;
1966+ let args = & args[ 1 ..] ;
1967+ let arg1 = {
1968+ let ty = TyKind :: Tuple (
1969+ args. len ( ) ,
1970+ Substitution :: from_iter ( Interner , args. iter ( ) . map ( |x| x. ty . clone ( ) ) ) ,
1971+ )
1972+ . intern ( Interner ) ;
1973+ let layout = self . layout ( & ty) ?;
1974+ let result = self . make_by_layout (
1975+ layout. size . bytes_usize ( ) ,
1976+ & layout,
1977+ None ,
1978+ args. iter ( ) . map ( |x| IntervalOrOwned :: Borrowed ( x. interval ) ) ,
1979+ ) ?;
1980+ // FIXME: there is some leak here
1981+ let size = layout. size . bytes_usize ( ) ;
1982+ let addr = self . heap_allocate ( size, layout. align . abi . bytes ( ) as usize ) ;
1983+ self . write_memory ( addr, & result) ?;
1984+ IntervalAndTy { interval : Interval { addr, size } , ty }
1985+ } ;
1986+ return self . exec_fn_with_args (
1987+ def,
1988+ & [ arg0. clone ( ) , arg1] ,
1989+ generic_args,
1990+ locals,
1991+ destination,
1992+ span,
1993+ ) ;
1994+ }
19621995 }
19631996 Ok ( ( ) )
19641997 }
0 commit comments