@@ -27,7 +27,6 @@ pub use intrinsic::IntrinsicDef;
2727use rustc_abi:: {
2828 Align , FieldIdx , Integer , IntegerType , ReprFlags , ReprOptions , ScalableElt , VariantIdx ,
2929} ;
30- use rustc_ast:: expand:: typetree:: { FncTree , Kind , Type , TypeTree } ;
3130use rustc_ast:: node_id:: NodeMap ;
3231use rustc_ast:: { self as ast} ;
3332pub use rustc_ast_ir:: { Movability , Mutability , try_visit} ;
@@ -67,7 +66,7 @@ pub use rustc_type_ir::solve::{CandidatePreferenceMode, SizedTraitKind, VisibleF
6766pub use rustc_type_ir:: * ;
6867#[ allow( hidden_glob_reexports, unused_imports) ]
6968use rustc_type_ir:: { InferCtxtLike , Interner } ;
70- use tracing:: { debug, instrument, trace } ;
69+ use tracing:: { debug, instrument} ;
7170pub use vtable:: * ;
7271
7372pub use self :: closure:: {
@@ -145,6 +144,7 @@ pub mod print;
145144pub mod relate;
146145pub mod significant_drop_order;
147146pub mod trait_def;
147+ pub mod typetree;
148148pub mod util;
149149pub mod vtable;
150150
@@ -2389,228 +2389,3 @@ pub struct DestructuredAdtConst<'tcx> {
23892389 pub variant : VariantIdx ,
23902390 pub fields : & ' tcx [ ty:: Const < ' tcx > ] ,
23912391}
2392-
2393- /// Generate TypeTree information for autodiff.
2394- /// This function creates TypeTree metadata that describes the memory layout
2395- /// of function parameters and return types for Enzyme autodiff.
2396- pub fn fnc_typetrees < ' tcx > ( tcx : TyCtxt < ' tcx > , fn_ty : Ty < ' tcx > ) -> FncTree {
2397- // Check if TypeTrees are disabled via NoTT flag
2398- if tcx. sess . opts . unstable_opts . autodiff . contains ( & rustc_session:: config:: AutoDiff :: NoTT ) {
2399- return FncTree { args : vec ! [ ] , ret : TypeTree :: new ( ) } ;
2400- }
2401-
2402- // Check if this is actually a function type
2403- if !fn_ty. is_fn ( ) {
2404- return FncTree { args : vec ! [ ] , ret : TypeTree :: new ( ) } ;
2405- }
2406-
2407- // Get the function signature
2408- let fn_sig = fn_ty. fn_sig ( tcx) ;
2409- let sig = tcx. instantiate_bound_regions_with_erased ( fn_sig) ;
2410-
2411- // Create TypeTrees for each input parameter
2412- let mut args = vec ! [ ] ;
2413- for ty in sig. inputs ( ) . iter ( ) {
2414- let type_tree = typetree_from_ty ( tcx, * ty) ;
2415- args. push ( type_tree) ;
2416- }
2417-
2418- // Create TypeTree for return type
2419- let ret = typetree_from_ty ( tcx, sig. output ( ) ) ;
2420-
2421- FncTree { args, ret }
2422- }
2423-
2424- /// Generate TypeTree for a specific type.
2425- /// This function analyzes a Rust type and creates appropriate TypeTree metadata.
2426- pub fn typetree_from_ty < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> TypeTree {
2427- let mut visited = Vec :: new ( ) ;
2428- typetree_from_ty_inner ( tcx, ty, 0 , & mut visited)
2429- }
2430-
2431- /// Maximum recursion depth for TypeTree generation to prevent stack overflow
2432- /// from pathological deeply nested types. Combined with cycle detection.
2433- const MAX_TYPETREE_DEPTH : usize = 6 ;
2434-
2435- /// Internal recursive function for TypeTree generation with cycle detection and depth limiting.
2436- fn typetree_from_ty_inner < ' tcx > (
2437- tcx : TyCtxt < ' tcx > ,
2438- ty : Ty < ' tcx > ,
2439- depth : usize ,
2440- visited : & mut Vec < Ty < ' tcx > > ,
2441- ) -> TypeTree {
2442- if depth >= MAX_TYPETREE_DEPTH {
2443- trace ! ( "typetree depth limit {} reached for type: {}" , MAX_TYPETREE_DEPTH , ty) ;
2444- return TypeTree :: new ( ) ;
2445- }
2446-
2447- if visited. contains ( & ty) {
2448- return TypeTree :: new ( ) ;
2449- }
2450-
2451- visited. push ( ty) ;
2452- let result = typetree_from_ty_impl ( tcx, ty, depth, visited) ;
2453- visited. pop ( ) ;
2454- result
2455- }
2456-
2457- /// Implementation of TypeTree generation logic.
2458- fn typetree_from_ty_impl < ' tcx > (
2459- tcx : TyCtxt < ' tcx > ,
2460- ty : Ty < ' tcx > ,
2461- depth : usize ,
2462- visited : & mut Vec < Ty < ' tcx > > ,
2463- ) -> TypeTree {
2464- typetree_from_ty_impl_inner ( tcx, ty, depth, visited, false )
2465- }
2466-
2467- /// Internal implementation with context about whether this is for a reference target.
2468- fn typetree_from_ty_impl_inner < ' tcx > (
2469- tcx : TyCtxt < ' tcx > ,
2470- ty : Ty < ' tcx > ,
2471- depth : usize ,
2472- visited : & mut Vec < Ty < ' tcx > > ,
2473- is_reference_target : bool ,
2474- ) -> TypeTree {
2475- if ty. is_scalar ( ) {
2476- let ( kind, size) = if ty. is_integral ( ) || ty. is_char ( ) || ty. is_bool ( ) {
2477- ( Kind :: Integer , ty. primitive_size ( tcx) . bytes_usize ( ) )
2478- } else if ty. is_floating_point ( ) {
2479- match ty {
2480- x if x == tcx. types . f16 => ( Kind :: Half , 2 ) ,
2481- x if x == tcx. types . f32 => ( Kind :: Float , 4 ) ,
2482- x if x == tcx. types . f64 => ( Kind :: Double , 8 ) ,
2483- x if x == tcx. types . f128 => ( Kind :: F128 , 16 ) ,
2484- _ => ( Kind :: Integer , 0 ) ,
2485- }
2486- } else {
2487- ( Kind :: Integer , 0 )
2488- } ;
2489-
2490- // Use offset 0 for scalars that are direct targets of references (like &f64)
2491- // Use offset -1 for scalars used directly (like function return types)
2492- let offset = if is_reference_target && !ty. is_array ( ) { 0 } else { -1 } ;
2493- return TypeTree ( vec ! [ Type { offset, size, kind, child: TypeTree :: new( ) } ] ) ;
2494- }
2495-
2496- if ty. is_ref ( ) || ty. is_raw_ptr ( ) || ty. is_box ( ) {
2497- let Some ( inner_ty) = ty. builtin_deref ( true ) else {
2498- return TypeTree :: new ( ) ;
2499- } ;
2500-
2501- let child = typetree_from_ty_impl_inner ( tcx, inner_ty, depth + 1 , visited, true ) ;
2502- return TypeTree ( vec ! [ Type {
2503- offset: -1 ,
2504- size: tcx. data_layout. pointer_size( ) . bytes_usize( ) ,
2505- kind: Kind :: Pointer ,
2506- child,
2507- } ] ) ;
2508- }
2509-
2510- if ty. is_array ( ) {
2511- if let ty:: Array ( element_ty, len_const) = ty. kind ( ) {
2512- let len = len_const. try_to_target_usize ( tcx) . unwrap_or ( 0 ) ;
2513- if len == 0 {
2514- return TypeTree :: new ( ) ;
2515- }
2516- let element_tree =
2517- typetree_from_ty_impl_inner ( tcx, * element_ty, depth + 1 , visited, false ) ;
2518- let mut types = Vec :: new ( ) ;
2519- for elem_type in & element_tree. 0 {
2520- types. push ( Type {
2521- offset : -1 ,
2522- size : elem_type. size ,
2523- kind : elem_type. kind ,
2524- child : elem_type. child . clone ( ) ,
2525- } ) ;
2526- }
2527-
2528- return TypeTree ( types) ;
2529- }
2530- }
2531-
2532- if ty. is_slice ( ) {
2533- if let ty:: Slice ( element_ty) = ty. kind ( ) {
2534- let element_tree =
2535- typetree_from_ty_impl_inner ( tcx, * element_ty, depth + 1 , visited, false ) ;
2536- return element_tree;
2537- }
2538- }
2539-
2540- if let ty:: Tuple ( tuple_types) = ty. kind ( ) {
2541- if tuple_types. is_empty ( ) {
2542- return TypeTree :: new ( ) ;
2543- }
2544-
2545- let mut types = Vec :: new ( ) ;
2546- let mut current_offset = 0 ;
2547-
2548- for tuple_ty in tuple_types. iter ( ) {
2549- let element_tree =
2550- typetree_from_ty_impl_inner ( tcx, tuple_ty, depth + 1 , visited, false ) ;
2551-
2552- let element_layout = tcx
2553- . layout_of ( ty:: TypingEnv :: fully_monomorphized ( ) . as_query_input ( tuple_ty) )
2554- . ok ( )
2555- . map ( |layout| layout. size . bytes_usize ( ) )
2556- . unwrap_or ( 0 ) ;
2557-
2558- for elem_type in & element_tree. 0 {
2559- types. push ( Type {
2560- offset : if elem_type. offset == -1 {
2561- current_offset as isize
2562- } else {
2563- current_offset as isize + elem_type. offset
2564- } ,
2565- size : elem_type. size ,
2566- kind : elem_type. kind ,
2567- child : elem_type. child . clone ( ) ,
2568- } ) ;
2569- }
2570-
2571- current_offset += element_layout;
2572- }
2573-
2574- return TypeTree ( types) ;
2575- }
2576-
2577- if let ty:: Adt ( adt_def, args) = ty. kind ( ) {
2578- if adt_def. is_struct ( ) {
2579- let struct_layout =
2580- tcx. layout_of ( ty:: TypingEnv :: fully_monomorphized ( ) . as_query_input ( ty) ) ;
2581- if let Ok ( layout) = struct_layout {
2582- let mut types = Vec :: new ( ) ;
2583-
2584- for ( field_idx, field_def) in adt_def. all_fields ( ) . enumerate ( ) {
2585- let field_ty = field_def. ty ( tcx, args) ;
2586- let field_tree = typetree_from_ty_impl_inner (
2587- tcx,
2588- field_ty. skip_norm_wip ( ) ,
2589- depth + 1 ,
2590- visited,
2591- false ,
2592- ) ;
2593-
2594- let field_offset = layout. fields . offset ( field_idx) . bytes_usize ( ) ;
2595-
2596- for elem_type in & field_tree. 0 {
2597- types. push ( Type {
2598- offset : if elem_type. offset == -1 {
2599- field_offset as isize
2600- } else {
2601- field_offset as isize + elem_type. offset
2602- } ,
2603- size : elem_type. size ,
2604- kind : elem_type. kind ,
2605- child : elem_type. child . clone ( ) ,
2606- } ) ;
2607- }
2608- }
2609-
2610- return TypeTree ( types) ;
2611- }
2612- }
2613- }
2614-
2615- TypeTree :: new ( )
2616- }
0 commit comments