diff --git a/charon-hs/test/Test/Deserialize.hs b/charon-hs/test/Test/Deserialize.hs index 70c018121..d12a64a80 100644 --- a/charon-hs/test/Test/Deserialize.hs +++ b/charon-hs/test/Test/Deserialize.hs @@ -4,6 +4,7 @@ module Test.Deserialize (tests, getAllLlbcTests) where import Data.Aeson (eitherDecodeFileStrict, eitherDecodeStrict) import qualified Data.ByteString.Char8 as BS8 +import Data.List (isSuffixOf) import System.Directory (doesFileExist, listDirectory, doesDirectoryExist) import System.FilePath ((), takeExtension) import Control.Monad (filterM, when) @@ -107,34 +108,62 @@ createLlbcTest filepath = testCase filepath $ do let crate = llbcfileTranslated llbcFile -- Successfully deserialized the entire crate! -- We can validate that it has the expected structure - let typeDeclCount = length (translatedcrateTypeDecls crate) + let funDeclCount = length (translatedcrateFunDecls crate) + typeDeclCount = length (translatedcrateTypeDecls crate) globalDeclCount = length (translatedcrateGlobalDecls crate) traitDeclCount = length (translatedcrateTraitDecls crate) traitImplCount = length (translatedcrateTraitImpls crate) - -- The test passes if we successfully deserialized the TranslatedCrate - assertBool (concat - [ "Successfully deserialized LLBC file with charon version " - , llbcfileCharonVersion llbcFile - , ": crate '" - , translatedcrateCrateName crate - , "' with " - , show typeDeclCount, " type decls, " - , show globalDeclCount, " global decls, " - , show traitDeclCount, " trait decls, " - , show traitImplCount, " trait impls" - ]) True + -- For test_crate.llbc, validate exact counts + if "test_crate.llbc" `isSuffixOf` filepath + then do + -- Expected counts for test_crate.llbc + let expectedFunDecls = 2 + expectedGlobalDecls = 1 + expectedTypeDecls = 0 + expectedTraitDecls = 0 + expectedTraitImpls = 0 + + -- Assert each count matches the expected value + assertEqual "Number of FunDecls" expectedFunDecls funDeclCount + assertEqual "Number of GlobalDecls" expectedGlobalDecls globalDeclCount + assertEqual "Number of TypeDecls" expectedTypeDecls typeDeclCount + assertEqual "Number of TraitDecls" expectedTraitDecls traitDeclCount + assertEqual "Number of TraitImpls" expectedTraitImpls traitImplCount + else + -- For other files, just confirm successful deserialization with counts + assertBool (concat + [ "Successfully deserialized LLBC file with charon version " + , llbcfileCharonVersion llbcFile + , ": crate '" + , translatedcrateCrateName crate + , "' with " + , show funDeclCount, " fun decls, " + , show typeDeclCount, " type decls, " + , show globalDeclCount, " global decls, " + , show traitDeclCount, " trait decls, " + , show traitImplCount, " trait impls" + ]) True -- Export function to get all LLBC test cases getAllLlbcTests :: IO TestTree getAllLlbcTests = do + -- Check for LLBC files in the test data directory + let testDataDir = "test/data" + testDataExists <- doesDirectoryExist testDataDir + testDataFiles <- if testDataExists + then findLlbcFiles testDataDir + else return [] + + -- Check for LLBC files in the UI test directory let testDir = "../charon/tests/ui" dirExists <- doesDirectoryExist testDir - if not dirExists - then return $ testGroup "LLBC Files" [] - else do - llbcFiles <- findLlbcFiles testDir - let testCases = map createLlbcTest llbcFiles - return $ testGroup "All LLBC Files" testCases + uiTestFiles <- if dirExists + then findLlbcFiles testDir + else return [] + + let allFiles = testDataFiles ++ uiTestFiles + let testCases = map createLlbcTest allFiles + return $ testGroup "All LLBC Files" testCases diff --git a/charon-hs/test/data/test_crate.llbc b/charon-hs/test/data/test_crate.llbc index 02244246c..bbe3035fa 100644 --- a/charon-hs/test/data/test_crate.llbc +++ b/charon-hs/test/data/test_crate.llbc @@ -1 +1 @@ -{"charon_version":"0.1.140","translated":{"crate_name":"test_crate","options":{"ullbc":false,"lib":false,"bin":null,"mir_promoted":false,"mir_optimized":false,"mir":null,"input_file":null,"read_llbc":null,"dest_dir":null,"dest_file":null,"use_polonius":false,"skip_borrowck":false,"monomorphize":false,"monomorphize_mut":null,"extract_opaque_bodies":false,"translate_all_methods":false,"include":[],"opaque":[],"exclude":[],"remove_associated_types":[],"hide_marker_traits":false,"remove_adt_clauses":false,"hide_allocator":false,"remove_unused_self_clauses":false,"add_drop_bounds":false,"start_from":[],"no_cargo":false,"rustc_args":[],"cargo_args":[],"abort_on_error":false,"error_on_warnings":false,"no_serialize":false,"print_original_ullbc":false,"print_ullbc":false,"print_built_llbc":false,"print_llbc":false,"no_merge_goto_chains":false,"no_ops_to_function_calls":false,"raw_boxes":false,"preset":null},"target_information":{"target_pointer_size":8,"is_little_endian":true},"item_names":[{"key":{"TraitDecl":1},"value":[{"Ident":["core",0]},{"Ident":["marker",0]},{"Ident":["MetaSized",0]}]},{"key":{"TraitDecl":0},"value":[{"Ident":["core",0]},{"Ident":["marker",0]},{"Ident":["Sized",0]}]},{"key":{"Type":2},"value":[{"Ident":["core",0]},{"Ident":["marker",0]},{"Ident":["MetaSized",0]},{"Ident":["{vtable}",0]}]},{"key":{"Type":1},"value":[{"Ident":["test_crate",0]},{"Ident":["Option",0]}]},{"key":{"Fun":1},"value":[{"Ident":["test_crate",0]},{"Ident":["add",0]}]},{"key":{"Type":0},"value":[{"Ident":["test_crate",0]},{"Ident":["Point",0]}]}],"short_names":[{"key":{"TraitDecl":0},"value":[{"Ident":["Sized",0]}]},{"key":{"Type":1},"value":[{"Ident":["Option",0]}]},{"key":{"Type":2},"value":[{"Ident":["{vtable}",0]}]},{"key":{"Type":0},"value":[{"Ident":["Point",0]}]},{"key":{"TraitDecl":1},"value":[{"Ident":["MetaSized",0]}]},{"key":{"Fun":1},"value":[{"Ident":["add",0]}]}],"files":[{"name":{"Local":"lib.rs"},"crate_name":"test_crate","contents":"// Simple test crate for generating LLBC\npub fn add(a: i32, b: i32) -> i32 {\n a + b\n}\n\npub struct Point {\n pub x: i32,\n pub y: i32,\n}\n\npub enum Option {\n None,\n Some(T),\n}\n"},{"name":{"Local":"/rustc/library/core/src/marker.rs"},"crate_name":"core","contents":null},{"name":{"Local":"/rustc/library/core/src/lib.rs"},"crate_name":"core","contents":null}],"type_decls":[{"def_id":0,"item_meta":{"name":[{"Ident":["test_crate",0]},{"Ident":["Point",0]}],"span":{"data":{"file_id":0,"beg":{"line":6,"col":0},"end":{"line":9,"col":1}},"generated_from_span":null},"source_text":"pub struct Point {\n pub x: i32,\n pub y: i32,\n}","attr_info":{"attributes":[],"inline":null,"rename":null,"public":true},"is_local":true,"opacity":"Transparent","lang_item":null},"generics":{"regions":[],"types":[],"const_generics":[],"trait_clauses":[],"regions_outlive":[],"types_outlive":[],"trait_type_constraints":[]},"src":"TopLevel","kind":{"Struct":[{"span":{"data":{"file_id":0,"beg":{"line":7,"col":4},"end":{"line":7,"col":14}},"generated_from_span":null},"attr_info":{"attributes":[],"inline":null,"rename":null,"public":true},"name":"x","ty":{"Literal":{"Int":"I32"}}},{"span":{"data":{"file_id":0,"beg":{"line":8,"col":4},"end":{"line":8,"col":14}},"generated_from_span":null},"attr_info":{"attributes":[],"inline":null,"rename":null,"public":true},"name":"y","ty":{"Literal":{"Int":"I32"}}}]},"layout":{"size":8,"align":4,"discriminant_layout":null,"uninhabited":false,"variant_layouts":[{"field_offsets":[0,4],"uninhabited":false,"tag":null}]},"ptr_metadata":"None","repr":{"repr_algo":"Rust","align_modif":null,"transparent":false,"explicit_discr_type":false}},{"def_id":1,"item_meta":{"name":[{"Ident":["test_crate",0]},{"Ident":["Option",0]}],"span":{"data":{"file_id":0,"beg":{"line":11,"col":0},"end":{"line":14,"col":1}},"generated_from_span":null},"source_text":"pub enum Option {\n None,\n Some(T),\n}","attr_info":{"attributes":[],"inline":null,"rename":null,"public":true},"is_local":true,"opacity":"Transparent","lang_item":null},"generics":{"regions":[],"types":[{"index":0,"name":"T"}],"const_generics":[],"trait_clauses":[{"clause_id":0,"span":{"data":{"file_id":0,"beg":{"line":11,"col":16},"end":{"line":11,"col":17}},"generated_from_span":null},"origin":"WhereClauseOnType","trait_":{"regions":[],"skip_binder":{"id":0,"generics":{"regions":[],"types":[{"TypeVar":{"Free":0}}],"const_generics":[],"trait_refs":[]}}}}],"regions_outlive":[],"types_outlive":[],"trait_type_constraints":[]},"src":"TopLevel","kind":{"Enum":[{"span":{"data":{"file_id":0,"beg":{"line":12,"col":4},"end":{"line":12,"col":8}},"generated_from_span":null},"attr_info":{"attributes":[],"inline":null,"rename":null,"public":true},"name":"None","fields":[],"discriminant":{"Scalar":{"Signed":["Isize","0"]}}},{"span":{"data":{"file_id":0,"beg":{"line":13,"col":4},"end":{"line":13,"col":8}},"generated_from_span":null},"attr_info":{"attributes":[],"inline":null,"rename":null,"public":true},"name":"Some","fields":[{"span":{"data":{"file_id":0,"beg":{"line":13,"col":9},"end":{"line":13,"col":10}},"generated_from_span":null},"attr_info":{"attributes":[],"inline":null,"rename":null,"public":true},"name":null,"ty":{"TypeVar":{"Free":0}}}],"discriminant":{"Scalar":{"Signed":["Isize","1"]}}}]},"layout":null,"ptr_metadata":"None","repr":{"repr_algo":"Rust","align_modif":null,"transparent":false,"explicit_discr_type":false}},null],"fun_decls":[{"def_id":0,"item_meta":{"name":[{"Ident":["UNIT_METADATA",0]}],"span":{"data":{"file_id":0,"beg":{"line":0,"col":0},"end":{"line":0,"col":0}},"generated_from_span":null},"source_text":null,"attr_info":{"attributes":[],"inline":null,"rename":null,"public":false},"is_local":false,"opacity":"Foreign","lang_item":null},"signature":{"is_unsafe":false,"generics":{"regions":[],"types":[],"const_generics":[],"trait_clauses":[],"regions_outlive":[],"types_outlive":[],"trait_type_constraints":[]},"inputs":[],"output":{"Adt":{"id":"Tuple","generics":{"regions":[],"types":[],"const_generics":[],"trait_refs":[]}}}},"src":"TopLevel","is_global_initializer":0,"body":{"Ok":{"Structured":{"span":{"data":{"file_id":0,"beg":{"line":0,"col":0},"end":{"line":0,"col":0}},"generated_from_span":null},"locals":{"arg_count":0,"locals":[{"index":0,"name":null,"ty":{"Adt":{"id":"Tuple","generics":{"regions":[],"types":[],"const_generics":[],"trait_refs":[]}}}}]},"comments":[],"body":{"span":{"data":{"file_id":0,"beg":{"line":0,"col":0},"end":{"line":0,"col":0}},"generated_from_span":null},"statements":[{"span":{"data":{"file_id":0,"beg":{"line":0,"col":0},"end":{"line":0,"col":0}},"generated_from_span":null},"id":1,"kind":{"Assign":[{"kind":{"Local":0},"ty":{"Adt":{"id":"Tuple","generics":{"regions":[],"types":[],"const_generics":[],"trait_refs":[]}}}},{"Aggregate":[{"Adt":[{"id":"Tuple","generics":{"regions":[],"types":[],"const_generics":[],"trait_refs":[]}},null,null]},[]]}]},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":0,"col":0},"end":{"line":0,"col":0}},"generated_from_span":null},"id":0,"kind":"Return","comments_before":[]}]}}}}},{"def_id":1,"item_meta":{"name":[{"Ident":["test_crate",0]},{"Ident":["add",0]}],"span":{"data":{"file_id":0,"beg":{"line":2,"col":0},"end":{"line":4,"col":1}},"generated_from_span":null},"source_text":"pub fn add(a: i32, b: i32) -> i32 {\n a + b\n}","attr_info":{"attributes":[],"inline":null,"rename":null,"public":true},"is_local":true,"opacity":"Transparent","lang_item":null},"signature":{"is_unsafe":false,"generics":{"regions":[],"types":[],"const_generics":[],"trait_clauses":[],"regions_outlive":[],"types_outlive":[],"trait_type_constraints":[]},"inputs":[{"Literal":{"Int":"I32"}},{"Literal":{"Int":"I32"}}],"output":{"Literal":{"Int":"I32"}}},"src":"TopLevel","is_global_initializer":null,"body":{"Ok":{"Structured":{"span":{"data":{"file_id":0,"beg":{"line":2,"col":0},"end":{"line":4,"col":1}},"generated_from_span":null},"locals":{"arg_count":2,"locals":[{"index":0,"name":null,"ty":{"Literal":{"Int":"I32"}}},{"index":1,"name":"a","ty":{"Literal":{"Int":"I32"}}},{"index":2,"name":"b","ty":{"Literal":{"Int":"I32"}}},{"index":3,"name":null,"ty":{"Literal":{"Int":"I32"}}},{"index":4,"name":null,"ty":{"Literal":{"Int":"I32"}}},{"index":5,"name":null,"ty":{"Literal":{"Int":"I32"}}}]},"comments":[],"body":{"span":{"data":{"file_id":0,"beg":{"line":3,"col":4},"end":{"line":4,"col":1}},"generated_from_span":null},"statements":[{"span":{"data":{"file_id":0,"beg":{"line":3,"col":4},"end":{"line":3,"col":5}},"generated_from_span":null},"id":3,"kind":{"StorageLive":5},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":3,"col":4},"end":{"line":3,"col":5}},"generated_from_span":null},"id":4,"kind":{"StorageLive":3},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":3,"col":4},"end":{"line":3,"col":5}},"generated_from_span":null},"id":5,"kind":{"Assign":[{"kind":{"Local":3},"ty":{"Literal":{"Int":"I32"}}},{"Use":{"Copy":{"kind":{"Local":1},"ty":{"Literal":{"Int":"I32"}}}}}]},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":3,"col":8},"end":{"line":3,"col":9}},"generated_from_span":null},"id":6,"kind":{"StorageLive":4},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":3,"col":8},"end":{"line":3,"col":9}},"generated_from_span":null},"id":7,"kind":{"Assign":[{"kind":{"Local":4},"ty":{"Literal":{"Int":"I32"}}},{"Use":{"Copy":{"kind":{"Local":2},"ty":{"Literal":{"Int":"I32"}}}}}]},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":3,"col":4},"end":{"line":3,"col":9}},"generated_from_span":null},"id":8,"kind":{"Assign":[{"kind":{"Local":5},"ty":{"Literal":{"Int":"I32"}}},{"BinaryOp":[{"Add":"Panic"},{"Copy":{"kind":{"Local":3},"ty":{"Literal":{"Int":"I32"}}}},{"Copy":{"kind":{"Local":4},"ty":{"Literal":{"Int":"I32"}}}}]}]},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":3,"col":4},"end":{"line":3,"col":9}},"generated_from_span":null},"id":10,"kind":{"Assign":[{"kind":{"Local":0},"ty":{"Literal":{"Int":"I32"}}},{"Use":{"Move":{"kind":{"Local":5},"ty":{"Literal":{"Int":"I32"}}}}}]},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":3,"col":8},"end":{"line":3,"col":9}},"generated_from_span":null},"id":11,"kind":{"StorageDead":4},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":3,"col":8},"end":{"line":3,"col":9}},"generated_from_span":null},"id":12,"kind":{"StorageDead":3},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":4,"col":1},"end":{"line":4,"col":1}},"generated_from_span":null},"id":2,"kind":"Return","comments_before":[]}]}}}}}],"global_decls":[{"def_id":0,"item_meta":{"name":[{"Ident":["UNIT_METADATA",0]}],"span":{"data":{"file_id":0,"beg":{"line":0,"col":0},"end":{"line":0,"col":0}},"generated_from_span":null},"source_text":null,"attr_info":{"attributes":[],"inline":null,"rename":null,"public":false},"is_local":false,"opacity":"Foreign","lang_item":null},"generics":{"regions":[],"types":[],"const_generics":[],"trait_clauses":[],"regions_outlive":[],"types_outlive":[],"trait_type_constraints":[]},"ty":{"Adt":{"id":"Tuple","generics":{"regions":[],"types":[],"const_generics":[],"trait_refs":[]}}},"src":"TopLevel","global_kind":"NamedConst","init":0}],"trait_decls":[{"def_id":0,"item_meta":{"name":[{"Ident":["core",0]},{"Ident":["marker",0]},{"Ident":["Sized",0]}],"span":{"data":{"file_id":1,"beg":{"line":160,"col":0},"end":{"line":160,"col":26}},"generated_from_span":null},"source_text":null,"attr_info":{"attributes":[{"DocComment":" Types with a constant size known at compile time."},{"DocComment":""},{"DocComment":" All type parameters have an implicit bound of `Sized`. The special syntax"},{"DocComment":" `?Sized` can be used to remove this bound if it's not appropriate."},{"DocComment":""},{"DocComment":" ```"},{"DocComment":" # #![allow(dead_code)]"},{"DocComment":" struct Foo(T);"},{"DocComment":" struct Bar(T);"},{"DocComment":""},{"DocComment":" // struct FooUse(Foo<[i32]>); // error: Sized is not implemented for [i32]"},{"DocComment":" struct BarUse(Bar<[i32]>); // OK"},{"DocComment":" ```"},{"DocComment":""},{"DocComment":" The one exception is the implicit `Self` type of a trait. A trait does not"},{"DocComment":" have an implicit `Sized` bound as this is incompatible with [trait object]s"},{"DocComment":" where, by definition, the trait needs to work with all possible implementors,"},{"DocComment":" and thus could be any size."},{"DocComment":""},{"DocComment":" Although Rust will let you bind `Sized` to a trait, you won't"},{"DocComment":" be able to use it to form a trait object later:"},{"DocComment":""},{"DocComment":" ```"},{"DocComment":" # #![allow(unused_variables)]"},{"DocComment":" trait Foo { }"},{"DocComment":" trait Bar: Sized { }"},{"DocComment":""},{"DocComment":" struct Impl;"},{"DocComment":" impl Foo for Impl { }"},{"DocComment":" impl Bar for Impl { }"},{"DocComment":""},{"DocComment":" let x: &dyn Foo = &Impl; // OK"},{"DocComment":" // let y: &dyn Bar = &Impl; // error: the trait `Bar` cannot be made into an object"},{"DocComment":" ```"},{"DocComment":""},{"DocComment":" [trait object]: ../../book/ch17-02-trait-objects.html"},{"Unknown":{"path":"doc","args":"alias = \"?\", alias = \"?Sized\""}},{"Unknown":{"path":"diagnostic::on_unimplemented","args":"message =\n\"the size for values of type `{Self}` cannot be known at compilation time\",\nlabel = \"doesn't have a size known at compile-time\""}}],"inline":null,"rename":null,"public":true},"is_local":false,"opacity":"Foreign","lang_item":"sized"},"generics":{"regions":[],"types":[{"index":0,"name":"Self"}],"const_generics":[],"trait_clauses":[],"regions_outlive":[],"types_outlive":[],"trait_type_constraints":[]},"implied_clauses":[{"clause_id":0,"span":{"data":{"file_id":1,"beg":{"line":160,"col":17},"end":{"line":160,"col":26}},"generated_from_span":null},"origin":"WhereClauseOnTrait","trait_":{"regions":[],"skip_binder":{"id":1,"generics":{"regions":[],"types":[{"TypeVar":{"Free":0}}],"const_generics":[],"trait_refs":[]}}}}],"consts":[],"types":[],"methods":[],"vtable":null},{"def_id":1,"item_meta":{"name":[{"Ident":["core",0]},{"Ident":["marker",0]},{"Ident":["MetaSized",0]}],"span":{"data":{"file_id":1,"beg":{"line":178,"col":0},"end":{"line":178,"col":33}},"generated_from_span":null},"source_text":null,"attr_info":{"attributes":[{"DocComment":" Types with a size that can be determined from pointer metadata."},{"Unknown":{"path":"diagnostic::on_unimplemented","args":"message = \"the size for values of type `{Self}` cannot be known\", label =\n\"doesn't have a known size\""}}],"inline":null,"rename":null,"public":true},"is_local":false,"opacity":"Foreign","lang_item":"meta_sized"},"generics":{"regions":[],"types":[{"index":0,"name":"Self"}],"const_generics":[],"trait_clauses":[],"regions_outlive":[],"types_outlive":[],"trait_type_constraints":[]},"implied_clauses":[],"consts":[],"types":[],"methods":[],"vtable":{"id":{"Adt":2},"generics":{"regions":[],"types":[],"const_generics":[],"trait_refs":[]}}}],"trait_impls":[],"unit_metadata":{"id":0,"generics":{"regions":[],"types":[],"const_generics":[],"trait_refs":[]}},"ordered_decls":[{"TraitDecl":{"NonRec":1}},{"TraitDecl":{"NonRec":0}},{"Fun":{"NonRec":0}},{"Global":{"NonRec":0}},{"Fun":{"NonRec":1}},{"Type":{"NonRec":0}},{"Type":{"NonRec":1}}]}} \ No newline at end of file +{"charon_version":"0.1.143","translated":{"crate_name":"test_crate","options":{"ullbc":false,"lib":false,"bin":null,"mir_promoted":false,"mir_optimized":false,"mir":null,"input_file":null,"read_llbc":null,"dest_dir":null,"dest_file":"/tmp/test_crate.llbc","use_polonius":false,"skip_borrowck":false,"monomorphize":false,"monomorphize_mut":null,"extract_opaque_bodies":false,"translate_all_methods":false,"include":[],"opaque":[],"exclude":[],"remove_associated_types":[],"hide_marker_traits":false,"remove_adt_clauses":false,"hide_allocator":false,"remove_unused_self_clauses":false,"add_drop_bounds":false,"start_from":[],"no_cargo":false,"rustc_args":[],"cargo_args":[],"abort_on_error":false,"error_on_warnings":false,"no_serialize":false,"print_original_ullbc":false,"print_ullbc":false,"print_built_llbc":false,"print_llbc":false,"no_merge_goto_chains":false,"no_ops_to_function_calls":false,"raw_boxes":false,"preset":null,"desugar_drops":false},"target_information":{"target_pointer_size":8,"is_little_endian":true},"item_names":[{"key":{"Fun":1},"value":[{"Ident":["test_crate",0]},{"Ident":["add",0]}]}],"short_names":[{"key":{"Fun":1},"value":[{"Ident":["add",0]}]}],"files":[{"name":{"Local":"/tmp/test_crate.rs"},"crate_name":"test_crate","contents":"// Simple test crate for Haskell AST tests\npub fn add(a: i32, b: i32) -> i32 {\n a + b\n}\n"}],"type_decls":[],"fun_decls":[{"def_id":0,"item_meta":{"name":[{"Ident":["UNIT_METADATA",0]}],"span":{"data":{"file_id":0,"beg":{"line":0,"col":0},"end":{"line":0,"col":0}},"generated_from_span":null},"source_text":null,"attr_info":{"attributes":[],"inline":null,"rename":null,"public":false},"is_local":false,"opacity":"Foreign","lang_item":null},"signature":{"is_unsafe":false,"generics":{"regions":[],"types":[],"const_generics":[],"trait_clauses":[],"regions_outlive":[],"types_outlive":[],"trait_type_constraints":[]},"inputs":[],"output":{"Adt":{"id":"Tuple","generics":{"regions":[],"types":[],"const_generics":[],"trait_refs":[]}}}},"src":"TopLevel","is_global_initializer":0,"body":{"Structured":{"span":{"data":{"file_id":0,"beg":{"line":0,"col":0},"end":{"line":0,"col":0}},"generated_from_span":null},"locals":{"arg_count":0,"locals":[{"index":0,"name":null,"ty":{"Adt":{"id":"Tuple","generics":{"regions":[],"types":[],"const_generics":[],"trait_refs":[]}}}}]},"comments":[],"body":{"span":{"data":{"file_id":0,"beg":{"line":0,"col":0},"end":{"line":0,"col":0}},"generated_from_span":null},"statements":[{"span":{"data":{"file_id":0,"beg":{"line":0,"col":0},"end":{"line":0,"col":0}},"generated_from_span":null},"id":1,"kind":{"Assign":[{"kind":{"Local":0},"ty":{"Adt":{"id":"Tuple","generics":{"regions":[],"types":[],"const_generics":[],"trait_refs":[]}}}},{"Aggregate":[{"Adt":[{"id":"Tuple","generics":{"regions":[],"types":[],"const_generics":[],"trait_refs":[]}},null,null]},[]]}]},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":0,"col":0},"end":{"line":0,"col":0}},"generated_from_span":null},"id":0,"kind":"Return","comments_before":[]}]}}}},{"def_id":1,"item_meta":{"name":[{"Ident":["test_crate",0]},{"Ident":["add",0]}],"span":{"data":{"file_id":0,"beg":{"line":2,"col":0},"end":{"line":4,"col":1}},"generated_from_span":null},"source_text":"pub fn add(a: i32, b: i32) -> i32 {\n a + b\n}","attr_info":{"attributes":[],"inline":null,"rename":null,"public":true},"is_local":true,"opacity":"Transparent","lang_item":null},"signature":{"is_unsafe":false,"generics":{"regions":[],"types":[],"const_generics":[],"trait_clauses":[],"regions_outlive":[],"types_outlive":[],"trait_type_constraints":[]},"inputs":[{"Literal":{"Int":"I32"}},{"Literal":{"Int":"I32"}}],"output":{"Literal":{"Int":"I32"}}},"src":"TopLevel","is_global_initializer":null,"body":{"Structured":{"span":{"data":{"file_id":0,"beg":{"line":2,"col":0},"end":{"line":4,"col":1}},"generated_from_span":null},"locals":{"arg_count":2,"locals":[{"index":0,"name":null,"ty":{"Literal":{"Int":"I32"}}},{"index":1,"name":"a","ty":{"Literal":{"Int":"I32"}}},{"index":2,"name":"b","ty":{"Literal":{"Int":"I32"}}},{"index":3,"name":null,"ty":{"Literal":{"Int":"I32"}}},{"index":4,"name":null,"ty":{"Literal":{"Int":"I32"}}},{"index":5,"name":null,"ty":{"Literal":{"Int":"I32"}}}]},"comments":[],"body":{"span":{"data":{"file_id":0,"beg":{"line":3,"col":4},"end":{"line":4,"col":1}},"generated_from_span":null},"statements":[{"span":{"data":{"file_id":0,"beg":{"line":3,"col":4},"end":{"line":3,"col":5}},"generated_from_span":null},"id":3,"kind":{"StorageLive":5},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":3,"col":4},"end":{"line":3,"col":5}},"generated_from_span":null},"id":4,"kind":{"StorageLive":3},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":3,"col":4},"end":{"line":3,"col":5}},"generated_from_span":null},"id":5,"kind":{"Assign":[{"kind":{"Local":3},"ty":{"Literal":{"Int":"I32"}}},{"Use":{"Copy":{"kind":{"Local":1},"ty":{"Literal":{"Int":"I32"}}}}}]},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":3,"col":8},"end":{"line":3,"col":9}},"generated_from_span":null},"id":6,"kind":{"StorageLive":4},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":3,"col":8},"end":{"line":3,"col":9}},"generated_from_span":null},"id":7,"kind":{"Assign":[{"kind":{"Local":4},"ty":{"Literal":{"Int":"I32"}}},{"Use":{"Copy":{"kind":{"Local":2},"ty":{"Literal":{"Int":"I32"}}}}}]},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":3,"col":4},"end":{"line":3,"col":9}},"generated_from_span":null},"id":8,"kind":{"Assign":[{"kind":{"Local":5},"ty":{"Literal":{"Int":"I32"}}},{"BinaryOp":[{"Add":"Panic"},{"Copy":{"kind":{"Local":3},"ty":{"Literal":{"Int":"I32"}}}},{"Copy":{"kind":{"Local":4},"ty":{"Literal":{"Int":"I32"}}}}]}]},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":3,"col":4},"end":{"line":3,"col":9}},"generated_from_span":null},"id":10,"kind":{"Assign":[{"kind":{"Local":0},"ty":{"Literal":{"Int":"I32"}}},{"Use":{"Move":{"kind":{"Local":5},"ty":{"Literal":{"Int":"I32"}}}}}]},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":3,"col":8},"end":{"line":3,"col":9}},"generated_from_span":null},"id":11,"kind":{"StorageDead":4},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":3,"col":8},"end":{"line":3,"col":9}},"generated_from_span":null},"id":12,"kind":{"StorageDead":3},"comments_before":[]},{"span":{"data":{"file_id":0,"beg":{"line":4,"col":1},"end":{"line":4,"col":1}},"generated_from_span":null},"id":2,"kind":"Return","comments_before":[]}]}}}}],"global_decls":[{"def_id":0,"item_meta":{"name":[{"Ident":["UNIT_METADATA",0]}],"span":{"data":{"file_id":0,"beg":{"line":0,"col":0},"end":{"line":0,"col":0}},"generated_from_span":null},"source_text":null,"attr_info":{"attributes":[],"inline":null,"rename":null,"public":false},"is_local":false,"opacity":"Foreign","lang_item":null},"generics":{"regions":[],"types":[],"const_generics":[],"trait_clauses":[],"regions_outlive":[],"types_outlive":[],"trait_type_constraints":[]},"ty":{"Adt":{"id":"Tuple","generics":{"regions":[],"types":[],"const_generics":[],"trait_refs":[]}}},"src":"TopLevel","global_kind":"NamedConst","init":0}],"trait_decls":[],"trait_impls":[],"unit_metadata":{"id":0,"generics":{"regions":[],"types":[],"const_generics":[],"trait_refs":[]}},"ordered_decls":[{"Fun":{"NonRec":0}},{"Global":{"NonRec":0}},{"Fun":{"NonRec":1}}]}} \ No newline at end of file