From e7f4152c33e27357f1b2d93d053284330cfeba88 Mon Sep 17 00:00:00 2001 From: NGUYEN Date: Fri, 15 Nov 2024 08:36:11 -0800 Subject: [PATCH 01/22] add support for enum, struct, tuple in mod.rs, add some tests --- Cargo.lock | 12 + charon | 2 +- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 863 ++++++++++++++---- ...TestRNvCshcvyQEKZjUj4test4main.symtab.lean | 24 + tests/expected/llbc/basic0/expected | 2 +- tests/expected/llbc/basic0/test.rs | 2 +- ...TestRNvCshcvyQEKZjUj4test4main.symtab.lean | 25 + ...TestRNvCshcvyQEKZjUj4test4main.symtab.lean | 31 + tests/expected/llbc/enum_test/expected | 36 + tests/expected/llbc/enum_test/test.rs | 27 + tests/expected/llbc/projection_test/expected | 49 + tests/expected/llbc/projection_test/test.rs | 32 + ...TestRNvCshcvyQEKZjUj4test4main.symtab.lean | 29 + tests/expected/llbc/struct_test/expected | 27 + tests/expected/llbc/struct_test/test.rs | 20 + ...TestRNvCshcvyQEKZjUj4test4main.symtab.lean | 24 + tests/expected/llbc/tuple_test/expected | 28 + tests/expected/llbc/tuple_test/test.rs | 14 + tests/perf/s2n-quic | 2 +- 19 files changed, 1076 insertions(+), 173 deletions(-) create mode 100644 tests/expected/llbc/basic0/TestRNvCshcvyQEKZjUj4test4main.symtab.lean create mode 100644 tests/expected/llbc/basic1/TestRNvCshcvyQEKZjUj4test4main.symtab.lean create mode 100644 tests/expected/llbc/enum_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean create mode 100644 tests/expected/llbc/enum_test/expected create mode 100644 tests/expected/llbc/enum_test/test.rs create mode 100644 tests/expected/llbc/projection_test/expected create mode 100644 tests/expected/llbc/projection_test/test.rs create mode 100644 tests/expected/llbc/struct_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean create mode 100644 tests/expected/llbc/struct_test/expected create mode 100644 tests/expected/llbc/struct_test/test.rs create mode 100644 tests/expected/llbc/tuple_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean create mode 100644 tests/expected/llbc/tuple_test/expected create mode 100644 tests/expected/llbc/tuple_test/test.rs diff --git a/Cargo.lock b/Cargo.lock index a8436fe8dea2..1c1d3b6458e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -253,6 +253,7 @@ dependencies = [ "clap", "colored", "convert_case 0.6.0", + "derivative", "derive-visitor", "env_logger", "hashlink", @@ -496,6 +497,17 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive-visitor" version = "0.4.0" diff --git a/charon b/charon index 454078ebdb4a..2193aa00fd89 160000 --- a/charon +++ b/charon @@ -1 +1 @@ -Subproject commit 454078ebdb4a607e2b21dc115e1ca99b516e436f +Subproject commit 2193aa00fd89e991226ada10d8a8f66e0594f212 diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index 35e4d137229d..0d006456ea8a 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -7,56 +7,75 @@ //! unstructured low-level borrow calculus (ULLBC) use core::panic; +use std::any::Any; +//use std::ascii::Char; use std::path::PathBuf; +use charon_lib::ast::AggregateKind as CharonAggregateKind; use charon_lib::ast::CastKind as CharonCastKind; +use charon_lib::ast::FieldId as CharonFieldId; use charon_lib::ast::Place as CharonPlace; use charon_lib::ast::ProjectionElem as CharonProjectionElem; use charon_lib::ast::Rvalue as CharonRvalue; use charon_lib::ast::Span as CharonSpan; -use charon_lib::ast::meta::{AttrInfo, Loc, RawSpan}; +use charon_lib::ast::meta::{AttrInfo as CharonAttrInfo, Loc as CharonLoc, RawSpan as CharonRawSpan}; use charon_lib::ast::types::Ty as CharonTy; +use charon_lib::ast::types::TypeDeclId as CharonTypeDeclId; use charon_lib::ast::types::TyKind as CharonTyKind; -use charon_lib::ast::{AbortKind, Body as CharonBody, Var, VarId}; +use charon_lib::ast::TypeDecl as CharonTypeDecl; +use charon_lib::ast::TypeDeclKind as CharonTypeDeclKind; +use charon_lib::ast::Variant as CharonVariant; +use charon_lib::ast::Field as CharonField; +use charon_lib::ast::{AbortKind as CharonAbortKind, Body as CharonBody, Var as CharonVar, VarId as CharonVarId}; use charon_lib::ast::{ - AnyTransId, Assert, BodyId, BuiltinTy, Disambiguator, FileName, FunDecl, FunSig, GenericArgs, - GenericParams, IntegerTy, ItemKind, ItemMeta, ItemOpacity, Literal, LiteralTy, Name, Opaque, - PathElem, RawConstantExpr, RefKind, Region as CharonRegion, ScalarValue, TranslatedCrate, - TypeId, + AnyTransId as CharonAnyTransId, Assert as CharonAssert, BodyId as CharonBodyId, BuiltinTy as CharonBuiltinTy, + Disambiguator as CharonDisambiguator, FileName as CharonFileName, FunDecl as CharonFunDecl, FunSig as CharonFunSig, GenericArgs as CharonGenericArgs, + GenericParams as CharonGenericParams, IntegerTy as CharonIntegerTy, + ItemKind as CharonItemKind, ItemMeta as CharonItemMeta, ItemOpacity as CharonItemOpacity, + Literal as CharonLiteral, LiteralTy as CharonLiteralTy, Name as CharonName, Opaque as CharonOpaque, + PathElem as CharonPathElem, RawConstantExpr as CharonRawConstantExpr, RefKind as CharonRefKind, Region as CharonRegion, ScalarValue as CharonScalarValue, + TranslatedCrate as CharonTranslatedCrate, TypeId as CharonTypeId, RegionId as CharonRegionId, TypeVarId as CharonTypeVarId, UnOp as CharonUnOp, ConstGeneric as CharonConstGeneric, + ConstGenericVarId as CharonConstGenericVarId, FieldProjKind as CharonFieldProjKind, }; use charon_lib::ast::{ - BinOp as CharonBinOp, Call, FnOperand, FnPtr, FunDeclId, FunId, FunIdOrTraitMethodRef, - VariantId, + BinOp as CharonBinOp, Call as CharonCall, FnOperand as CharonFnOperand, FnPtr as CharonFnPtr, + FunDeclId as CharonFunDeclId, FunId as CharonFunId, FunIdOrTraitMethodRef as CharonFunIdOrTraitMethodRef, VariantId as CharonVariantId, }; use charon_lib::ast::{ - BorrowKind as CharonBorrowKind, ConstantExpr, Operand as CharonOperand, UnOp, + BorrowKind as CharonBorrowKind, ConstantExpr as CharonConstantExpr, Operand as CharonOperand, }; -use charon_lib::errors::Error; -use charon_lib::errors::ErrorCtx; -use charon_lib::ids::Vector; +use charon_lib::errors::Error as CharonError; +use charon_lib::errors::ErrorCtx as CharonErrorCtx; +use charon_lib::ids::Vector as CharonVector; use charon_lib::ullbc_ast::{ - BlockData, BlockId, BodyContents, ExprBody, RawStatement, RawTerminator, - Statement as CharonStatement, SwitchTargets as CharonSwitchTargets, + BlockData as CharonBlockData, BlockId as CharonBlockId, BodyContents as CharonBodyContents, ExprBody as CharonExprBody, + RawStatement as CharonRawStatement, RawTerminator as CharonRawTerminator, Statement as CharonStatement, SwitchTargets as CharonSwitchTargets, Terminator as CharonTerminator, }; use charon_lib::{error_assert, error_or_panic}; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::stable_hasher::HashStable; +use rustc_middle::ty::AdtKind as MirAdtKind; use rustc_middle::ty::TyCtxt; use rustc_smir::rustc_internal; +use stable_mir::ty::AdtDef; +use stable_mir::ty::AdtKind; use stable_mir::abi::PassMode; +use stable_mir::mir::AggregateKind; use stable_mir::mir::VarDebugInfoContents; use stable_mir::mir::mono::Instance; use stable_mir::mir::mono::InstanceDef; use stable_mir::mir::{ - BasicBlock, BinOp, Body, BorrowKind, CastKind, ConstOperand, Local, Mutability, Operand, Place, + BasicBlock, BinOp, UnOp, Body, BorrowKind, CastKind, ConstOperand, Local, Mutability, Operand, Place, ProjectionElem, Rvalue, Statement, StatementKind, SwitchTargets, Terminator, TerminatorKind, }; use stable_mir::ty::{ Allocation, ConstantKind, IndexedVal, IntTy, MirConst, Region, RegionKind, RigidTy, Span, Ty, - TyKind, UintTy, + TyKind, UintTy, TyConst, TyConstId, TraitDef, TyConstKind }; - +use stable_mir::ty::{GenericArgs, GenericArgKind}; use stable_mir::{CrateDef, DefId}; +use syn::token::Default; use tracing::{debug, trace}; /// A context for translating a single MIR function to ULLBC. @@ -64,9 +83,9 @@ use tracing::{debug, trace}; pub struct Context<'a, 'tcx> { tcx: TyCtxt<'tcx>, instance: Instance, - translated: &'a mut TranslatedCrate, - id_map: &'a mut FxHashMap, - errors: &'a mut ErrorCtx<'tcx>, + translated: &'a mut CharonTranslatedCrate, + id_map: &'a mut FxHashMap, + errors: &'a mut CharonErrorCtx<'tcx>, local_names: FxHashMap, } @@ -76,9 +95,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { pub fn new( tcx: TyCtxt<'tcx>, instance: Instance, - translated: &'a mut TranslatedCrate, - id_map: &'a mut FxHashMap, - errors: &'a mut ErrorCtx<'tcx>, + translated: &'a mut CharonTranslatedCrate, + id_map: &'a mut FxHashMap, + errors: &'a mut CharonErrorCtx<'tcx>, ) -> Self { let mut local_names = FxHashMap::default(); // populate names of locals @@ -128,21 +147,21 @@ impl<'a, 'tcx> Context<'a, 'tcx> { }; let fun_decl = - FunDecl { def_id: fid, item_meta, signature, kind: ItemKind::Regular, body: Ok(body) }; + CharonFunDecl { def_id: fid, item_meta, signature, kind: CharonItemKind::Regular, body: Ok(body) }; self.translated.fun_decls.set_slot(fid, fun_decl); Ok(()) } - /// Get or create a `FunDeclId` for the given function - fn register_fun_decl_id(&mut self, def_id: DefId) -> FunDeclId { + /// Get or create a `CharonFunDeclId` for the given function + fn register_fun_decl_id(&mut self, def_id: DefId) -> CharonFunDeclId { debug!("register_fun_decl_id: {:?}", def_id); let tid = match self.id_map.get(&def_id) { Some(tid) => *tid, None => { debug!("***Not found!"); - let tid = AnyTransId::Fun(self.translated.fun_decls.reserve_slot()); + let tid = CharonAnyTransId::Fun(self.translated.fun_decls.reserve_slot()); self.id_map.insert(def_id, tid); self.translated.all_ids.insert(tid); tid @@ -152,15 +171,154 @@ impl<'a, 'tcx> Context<'a, 'tcx> { tid.try_into().unwrap() } + fn find_fun_decl_id(&self, def_id: DefId) -> CharonFunDeclId { + debug!("register_fun_decl_id: {:?}", def_id); + let tid = *self.id_map.get(&def_id).unwrap(); + debug!("register_fun_decl_id: {:?}", self.id_map); + tid.try_into().unwrap() + } + + fn register_type_decl_id(&mut self, def_id: DefId) -> CharonTypeDeclId { + debug!("register_type_decl_id: {:?}", def_id); + let tid = match self.id_map.get(&def_id) { + Some(tid) => *tid, + None => { + debug!("***Not found!"); + let tid = CharonAnyTransId::Type(self.translated.type_decls.reserve_slot()); + self.id_map.insert(def_id, tid); + self.translated.all_ids.insert(tid); + tid + } + }; + debug!("register_type_decl_id: {:?}", self.id_map); + tid.try_into().unwrap() + } + + fn find_type_decl_id(&self, def_id: DefId) -> CharonTypeDeclId { + debug!("register_type_decl_id: {:?}", def_id); + let tid = *self.id_map.get(&def_id).unwrap(); + debug!("register_type_decl_id: {:?}", self.id_map); + tid.try_into().unwrap() + } + + fn get_discriminant(&mut self, discr_val: u128, ty: Ty) -> CharonScalarValue { + let ty = self.translate_ty(ty); + let int_ty = *ty.kind().as_literal().unwrap().as_integer().unwrap(); + CharonScalarValue::from_bits(int_ty, discr_val) + } + + + fn translate_adtdef(&mut self, adt_def: AdtDef) -> CharonTypeDeclId { + match adt_def.kind() { + AdtKind::Enum => { + let def_id = adt_def.def_id(); + let c_typedeclid = self.register_type_decl_id(def_id); + let mut c_variants: CharonVector = CharonVector::new(); + for var_def in adt_def.variants_iter(){ + let mut c_fields: CharonVector = CharonVector::new(); + for field_def in var_def.fields(){ + let c_field_ty = self.translate_ty(field_def.ty()); + let c_field_name = Some(field_def.name); + let c_span = self.translate_span(adt_def.span()); + let c_field = CharonField { + span : c_span, + attr_info : CharonAttrInfo { attributes: Vec::new(), inline: None, rename: None, public: true }, + name: c_field_name, + ty: c_field_ty, + }; + c_fields.push(c_field); + } + let var_name = var_def.name(); + let span = self.translate_span(adt_def.span()); + + let adtdef_internal = rustc_internal::internal(self.tcx, adt_def); + let variant_index_internal = rustc_internal::internal(self.tcx, var_def.idx); + let discr = adtdef_internal.discriminant_for_variant(self.tcx, variant_index_internal); + let discr_val = discr.val; + let discr_ty = rustc_internal::stable(discr.ty); + let c_discr = self.get_discriminant(discr_val, discr_ty); + + let c_variant = CharonVariant{ + span : span, + attr_info : CharonAttrInfo { attributes: Vec::new(), inline: None, rename: None, public: true }, + name : var_name, + fields : c_fields, + discriminant : c_discr, + }; + let c_varidx = c_variants.push(c_variant); + assert_eq!(c_varidx.index(), var_def.idx.to_index()); + } + let item_meta = self.translate_item_meta_adt(adt_def).unwrap(); + let typedecl = CharonTypeDecl { + def_id: c_typedeclid, + generics: CharonGenericParams::empty(), + kind: CharonTypeDeclKind::Enum(c_variants), + item_meta : item_meta, + }; + self.translated.type_decls.set_slot(c_typedeclid, typedecl); + c_typedeclid + } + AdtKind::Struct => { + let def_id = adt_def.def_id(); + let c_typedeclid = self.register_type_decl_id(def_id); + let mut c_fields: CharonVector = CharonVector::new(); + let only_variant = *adt_def.variants().first().unwrap(); + let fields = only_variant.fields(); + for field_def in fields{ + let c_field_ty = self.translate_ty(field_def.ty()); + let c_field_name = Some(field_def.name); + let c_span = self.translate_span(adt_def.span()); + let c_field = CharonField { + span : c_span, + attr_info : CharonAttrInfo { attributes: Vec::new(), inline: None, rename: None, public: true }, + name: c_field_name, + ty: c_field_ty, + }; + c_fields.push(c_field); + } + let item_meta = self.translate_item_meta_adt(adt_def).unwrap(); + let typedecl = CharonTypeDecl { + def_id: c_typedeclid, + generics: CharonGenericParams::empty(), + kind: CharonTypeDeclKind::Struct(c_fields), + item_meta : item_meta, + }; + self.translated.type_decls.set_slot(c_typedeclid, typedecl); + c_typedeclid + } + _ => todo!(), + } + } + /// Compute the meta information for a Rust item identified by its id. - fn translate_item_meta_from_rid(&mut self, instance: Instance) -> Result { + fn translate_item_meta_from_rid(&mut self, instance: Instance) -> Result { let span = self.translate_instance_span(instance); let name = self.def_to_name(instance.def)?; // TODO: populate the source text let source_text = None; // TODO: populate the attribute info let attr_info = - AttrInfo { attributes: Vec::new(), inline: None, rename: None, public: true }; + CharonAttrInfo { attributes: Vec::new(), inline: None, rename: None, public: true }; + + // Aeneas only translates items that are local to the top-level crate + // Since we want all reachable items (including those in external + // crates) to be translated, always set `is_local` to true + let is_local = true; + + // For now, assume all items are transparent + let opacity = CharonItemOpacity::Transparent; + + Ok(CharonItemMeta { span, source_text, attr_info, name, is_local, opacity }) + } + + fn translate_item_meta_adt(&mut self, adt: AdtDef) -> Result { + let span = self.translate_span(adt.span()); + let name = self.adtdef_to_name(adt)?; + // TODO: populate the source text + let source_text = None; + // TODO: populate the attribute info + let attr_info = + CharonAttrInfo { attributes: Vec::new(), inline: None, rename: None, public: true }; // Aeneas only translates items that are local to the top-level crate // Since we want all reachable items (including those in external @@ -168,15 +326,16 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let is_local = true; // For now, assume all items are transparent - let opacity = ItemOpacity::Transparent; + let opacity = CharonItemOpacity::Transparent; - Ok(ItemMeta { span, source_text, attr_info, name, is_local, opacity }) + Ok(CharonItemMeta { span, source_text, attr_info, name, is_local, opacity }) } + /// Retrieve an item name from a [DefId]. /// This function is adapted from Charon: /// https://github.com/AeneasVerif/charon/blob/53530427db2941ce784201e64086766504bc5642/charon/src/bin/charon-driver/translate/translate_ctx.rs#L344 - fn def_to_name(&mut self, def: InstanceDef) -> Result { + fn def_to_name(&mut self, def: InstanceDef) -> Result { let def_id = def.def_id(); trace!("{:?}", def_id); let tcx = self.tcx(); @@ -231,10 +390,10 @@ impl<'a, 'tcx> Context<'a, 'tcx> { // ``` // // The names we will generate for `foo` and `bar` are: - // `[Ident("test"), Ident("bla"), Ident("Foo"), Disambiguator(0), Ident("foo")]` - // `[Ident("test"), Ident("bla"), Ident("Foo"), Disambiguator(1), Ident("bar")]` + // `[Ident("test"), Ident("bla"), Ident("Foo"), CharonDisambiguator(0), Ident("foo")]` + // `[Ident("test"), Ident("bla"), Ident("Foo"), CharonDisambiguator(1), Ident("bar")]` let mut found_crate_name = false; - let mut name: Vec = Vec::new(); + let mut name: Vec = Vec::new(); let def_path = tcx.def_path(def_id); let crate_name = tcx.crate_name(def_path.krate).to_string(); @@ -256,17 +415,17 @@ impl<'a, 'tcx> Context<'a, 'tcx> { for cur_id in parents { let data = tcx.def_key(cur_id).disambiguated_data; // Match over the key data - let disambiguator = Disambiguator::new(data.disambiguator as usize); + let disambiguator = CharonDisambiguator::new(data.disambiguator as usize); use rustc_hir::definitions::DefPathData; match &data.data { DefPathData::TypeNs(symbol) => { error_assert!(self, span, data.disambiguator == 0); // Sanity check - name.push(PathElem::Ident(symbol.to_string(), disambiguator)); + name.push(CharonPathElem::Ident(symbol.to_string(), disambiguator)); } DefPathData::ValueNs(symbol) => { // I think `disambiguator != 0` only with names introduced by macros (though // not sure). - name.push(PathElem::Ident(symbol.to_string(), disambiguator)); + name.push(CharonPathElem::Ident(symbol.to_string(), disambiguator)); } DefPathData::CrateRoot => { // Sanity check @@ -275,7 +434,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { // This should be the beginning of the path error_assert!(self, span, name.is_empty()); found_crate_name = true; - name.push(PathElem::Ident(crate_name.clone(), disambiguator)); + name.push(CharonPathElem::Ident(crate_name.clone(), disambiguator)); } DefPathData::Impl => todo!(), DefPathData::OpaqueTy => { @@ -289,13 +448,13 @@ impl<'a, 'tcx> Context<'a, 'tcx> { // of an issue here, because for now we don't expose macros // in the AST, and only use macro names in [register], for // instance to filter opaque modules. - name.push(PathElem::Ident(symbol.to_string(), disambiguator)); + name.push(CharonPathElem::Ident(symbol.to_string(), disambiguator)); } DefPathData::Closure => { // TODO: this is not very satisfactory, but on the other hand // we should be able to extract closures in local let-bindings // (i.e., we shouldn't have to introduce top-level let-bindings). - name.push(PathElem::Ident("closure".to_string(), disambiguator)) + name.push(CharonPathElem::Ident("closure".to_string(), disambiguator)) } DefPathData::ForeignMod => { // Do nothing, functions in `extern` blocks are in the same namespace as the @@ -309,13 +468,103 @@ impl<'a, 'tcx> Context<'a, 'tcx> { // We always add the crate name if !found_crate_name { - name.push(PathElem::Ident(crate_name, Disambiguator::new(0))); + name.push(CharonPathElem::Ident(crate_name, CharonDisambiguator::new(0))); } trace!("{:?}", name); - Ok(Name { name }) + Ok(CharonName { name }) } + fn adtdef_to_name(&mut self, def: AdtDef) -> Result { + let def_id = def.def_id(); + trace!("{:?}", def_id); + let tcx = self.tcx(); + let span: CharonSpan = self.translate_span(def.span()); + let def_id = rustc_internal::internal(self.tcx(), def_id); + let mut found_crate_name = false; + let mut name: Vec = Vec::new(); + + let def_path = tcx.def_path(def_id); + let crate_name = tcx.crate_name(def_path.krate).to_string(); + + let parents: Vec<_> = { + let mut parents = vec![def_id]; + let mut cur_id = def_id; + while let Some(parent) = tcx.opt_parent(cur_id) { + parents.push(parent); + cur_id = parent; + } + parents.into_iter().rev().collect() + }; + + // Rk.: below we try to be as tight as possible with regards to sanity + // checks, to make sure we understand what happens with def paths, and + // fail whenever we get something which is even slightly outside what + // we expect. + for cur_id in parents { + let data = tcx.def_key(cur_id).disambiguated_data; + // Match over the key data + let disambiguator = CharonDisambiguator::new(data.disambiguator as usize); + use rustc_hir::definitions::DefPathData; + match &data.data { + DefPathData::TypeNs(symbol) => { + error_assert!(self, span, data.disambiguator == 0); // Sanity check + name.push(CharonPathElem::Ident(symbol.to_string(), disambiguator)); + } + DefPathData::ValueNs(symbol) => { + // I think `disambiguator != 0` only with names introduced by macros (though + // not sure). + name.push(CharonPathElem::Ident(symbol.to_string(), disambiguator)); + } + DefPathData::CrateRoot => { + // Sanity check + error_assert!(self, span, data.disambiguator == 0); + + // This should be the beginning of the path + error_assert!(self, span, name.is_empty()); + found_crate_name = true; + name.push(CharonPathElem::Ident(crate_name.clone(), disambiguator)); + } + DefPathData::Impl => todo!(), + DefPathData::OpaqueTy => { + // TODO: do nothing for now + } + DefPathData::MacroNs(symbol) => { + error_assert!(self, span, data.disambiguator == 0); // Sanity check + + // There may be namespace collisions between, say, function + // names and macros (not sure). However, this isn't much + // of an issue here, because for now we don't expose macros + // in the AST, and only use macro names in [register], for + // instance to filter opaque modules. + name.push(CharonPathElem::Ident(symbol.to_string(), disambiguator)); + } + DefPathData::Closure => { + // TODO: this is not very satisfactory, but on the other hand + // we should be able to extract closures in local let-bindings + // (i.e., we shouldn't have to introduce top-level let-bindings). + name.push(CharonPathElem::Ident("closure".to_string(), disambiguator)) + } + DefPathData::ForeignMod => { + // Do nothing, functions in `extern` blocks are in the same namespace as the + // block. + } + _ => { + error_or_panic!(self, span, format!("Unexpected DefPathData: {:?}", data)); + } + } + } + + // We always add the crate name + if !found_crate_name { + name.push(CharonPathElem::Ident(crate_name, CharonDisambiguator::new(0))); + } + + trace!("{:?}", name); + Ok(CharonName { name }) + } + + /// Compute the span information for the given instance fn translate_instance_span(&mut self, instance: Instance) -> CharonSpan { self.translate_span(instance.def.span()) @@ -323,7 +572,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { /// Compute the span information for MIR span fn translate_span(&mut self, span: Span) -> CharonSpan { - let filename = FileName::Local(PathBuf::from(span.get_filename())); + let filename = CharonFileName::Local(PathBuf::from(span.get_filename())); let file_id = match self.translated.file_to_id.get(&filename) { Some(file_id) => *file_id, None => { @@ -333,17 +582,32 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } }; let lineinfo = span.get_lines(); - let rspan = RawSpan { + let rspan = CharonRawSpan { + file_id, + beg: CharonLoc { line: lineinfo.start_line, col: lineinfo.start_col }, + end: CharonLoc { line: lineinfo.end_line, col: lineinfo.end_col }, + }; + + // TODO: populate `generated_from_span` info + CharonSpan { span: rspan, generated_from_span: None } + } + + fn translate_span_immut(&self, span: Span) -> CharonSpan { + let filename = CharonFileName::Local(PathBuf::from(span.get_filename())); + let file_id = *self.translated.file_to_id.get(&filename).unwrap(); + let lineinfo = span.get_lines(); + let rspan = CharonRawSpan { file_id, - beg: Loc { line: lineinfo.start_line, col: lineinfo.start_col }, - end: Loc { line: lineinfo.end_line, col: lineinfo.end_col }, + beg: CharonLoc { line: lineinfo.start_line, col: lineinfo.start_col }, + end: CharonLoc { line: lineinfo.end_line, col: lineinfo.end_col }, }; // TODO: populate `generated_from_span` info CharonSpan { span: rspan, generated_from_span: None } } + - fn translate_function_signature(&mut self) -> FunSig { + fn translate_function_signature(&mut self) -> CharonFunSig { let instance = self.instance; let fn_abi = instance.fn_abi().unwrap(); let requires_caller_location = self.requires_caller_location(instance); @@ -373,18 +637,18 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let ret_type = self.translate_ty(fn_abi.ret.ty); // TODO: populate the rest of the information (`is_unsafe`, `is_closure`, etc.) - FunSig { + CharonFunSig { is_unsafe: false, is_closure: false, closure_info: None, - generics: GenericParams::default(), + generics: CharonGenericParams::default(), parent_params_info: None, inputs: args, output: ret_type, } } - fn translate_function_body(&mut self) -> Result { + fn translate_function_body(&mut self) -> Result { let instance = self.instance; let mir_body = instance.body().unwrap(); let body_id = self.translated.bodies.reserve_slot(); @@ -397,10 +661,10 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let span = self.translate_span(mir_body.span); let arg_count = self.instance.fn_abi().unwrap().args.len(); let locals = self.translate_body_locals(&mir_body); - let body: BodyContents = + let body: CharonBodyContents = mir_body.blocks.iter().map(|bb| self.translate_block(bb)).collect(); - let body_expr = ExprBody { span, arg_count, locals, body, comments: Vec::new() }; + let body_expr = CharonExprBody { span, arg_count, locals, body, comments: Vec::new() }; CharonBody::Unstructured(body_expr) } @@ -409,54 +673,148 @@ impl<'a, 'tcx> Context<'a, 'tcx> { instance_internal.def.requires_caller_location(self.tcx()) } - fn translate_ty(&self, ty: Ty) -> CharonTy { +/* + fn generic_args_to_generic_params (&self, ga: GenericArgs) -> CharonGenericParams{ + let genvec = ga.0; + let mut c_regions: CharonVector = CharonVector::new(); + let mut c_types: CharonVector = CharonVector::new(); + let mut c_const_generics: CharonVector =CharonVector::new(); + //let mut trait_refs: CharonVector = CharonVector::new(); + for genkind in genvec.iter(){ + match *genkind{ + GenericArgKind::Lifetime(region) => { + let c_region = self.translate_region(region); + c_regions.push(c_region); + } + GenericArgKind::Type(ty) => { + let c_ty = self.translate_ty(ty); + c_types.push(c_ty); + } + GenericArgKind::Const(tc ) => { + let c_const_generic = self.tyconst_to_constgeneric(tc); + c_const_generics.push(c_const_generic); + } + } + } + CharonGenericParams{ + regions : c_regions, + types : c_types, + const_generics : c_const_generics, + trait_clauses : CharonVector::new(), + regions_outlive : Vec::new(), + types_outlive : Vec::new(), + trait_type_constraints : Vec::new(), + } + } +*/ + + fn translate_generic_args (&mut self, ga: GenericArgs) -> CharonGenericArgs{ + let genvec = ga.0; + let mut c_regions: CharonVector = CharonVector::new(); + let mut c_types: CharonVector = CharonVector::new(); + let mut c_const_generics: CharonVector =CharonVector::new(); + //let mut trait_refs: CharonVector = CharonVector::new(); + for genkind in genvec.iter(){ + let gk = genkind.clone(); + match gk{ + GenericArgKind::Lifetime(region) => { + let c_region = self.translate_region(region); + c_regions.push(c_region); + }, + GenericArgKind::Type(ty) => { + let c_ty = self.translate_ty(ty); + c_types.push(c_ty); + }, + GenericArgKind::Const(tc ) => { + let c_const_generic = self.tyconst_to_constgeneric(tc); + c_const_generics.push(c_const_generic); + } + } + } + CharonGenericArgs{ + regions : c_regions, + types : c_types, + const_generics : c_const_generics, + trait_refs : CharonVector::new(), + } + } + + fn translate_ty(&mut self, ty: Ty) -> CharonTy { match ty.kind() { TyKind::RigidTy(rigid_ty) => self.translate_rigid_ty(rigid_ty), _ => todo!(), } } - fn translate_rigid_ty(&self, rigid_ty: RigidTy) -> CharonTy { + fn tyconst_to_constgeneric(&self, tyconst: TyConst) -> CharonConstGeneric { + match tyconst.kind() { + TyConstKind::Value(ty, alloc) => { + let c_raw_constexpr = self.translate_allocation(alloc, *ty); + let c_const_generic = translate_constant_expr_to_const_generic(c_raw_constexpr).unwrap(); + c_const_generic + } + _ => todo!(), + } + } + + fn translate_rigid_ty(&mut self, rigid_ty: RigidTy) -> CharonTy { debug!("translate_rigid_ty: {rigid_ty:?}"); match rigid_ty { - RigidTy::Bool => CharonTy::new(CharonTyKind::Literal(LiteralTy::Bool)), - RigidTy::Char => CharonTy::new(CharonTyKind::Literal(LiteralTy::Char)), + RigidTy::Bool => CharonTy::new(CharonTyKind::Literal(CharonLiteralTy::Bool)), + RigidTy::Char => CharonTy::new(CharonTyKind::Literal(CharonLiteralTy::Char)), RigidTy::Int(it) => { - CharonTy::new(CharonTyKind::Literal(LiteralTy::Integer(translate_int_ty(it)))) + CharonTy::new(CharonTyKind::Literal(CharonLiteralTy::Integer(translate_int_ty(it)))) } RigidTy::Uint(uit) => { - CharonTy::new(CharonTyKind::Literal(LiteralTy::Integer(translate_uint_ty(uit)))) + CharonTy::new(CharonTyKind::Literal(CharonLiteralTy::Integer(translate_uint_ty(uit)))) } RigidTy::Never => CharonTy::new(CharonTyKind::Never), RigidTy::Str => CharonTy::new(CharonTyKind::Adt( - TypeId::Builtin(BuiltinTy::Str), + CharonTypeId::Builtin(CharonBuiltinTy::Str), // TODO: find out whether any of the information below should be // populated for strings - GenericArgs { - regions: Vector::new(), - types: Vector::new(), - const_generics: Vector::new(), - trait_refs: Vector::new(), + CharonGenericArgs { + regions: CharonVector::new(), + types: CharonVector::new(), + const_generics: CharonVector::new(), + trait_refs: CharonVector::new(), }, )), + RigidTy::Array(ty, tyconst) => { + let c_ty = self.translate_ty(ty); + let c_const_generic = self.tyconst_to_constgeneric(tyconst); + let mut c_types = CharonVector::new(); + let mut c_const_generics = CharonVector::new(); + c_types.push(c_ty); + c_const_generics.push(c_const_generic); + CharonTy::new(CharonTyKind::Adt( + CharonTypeId::Builtin(CharonBuiltinTy::Array), + CharonGenericArgs { + regions: CharonVector::new(), + types: c_types, + const_generics: c_const_generics, + trait_refs: CharonVector::new(), + } + )) + } RigidTy::Ref(region, ty, mutability) => CharonTy::new(CharonTyKind::Ref( self.translate_region(region), self.translate_ty(ty), match mutability { - Mutability::Mut => RefKind::Mut, - Mutability::Not => RefKind::Shared, + Mutability::Mut => CharonRefKind::Mut, + Mutability::Not => CharonRefKind::Shared, }, )), RigidTy::Tuple(ty) => { let types = ty.iter().map(|ty| self.translate_ty(*ty)).collect(); // TODO: find out if any of the information below is needed - let generic_args = GenericArgs { - regions: Vector::new(), + let generic_args = CharonGenericArgs { + regions: CharonVector::new(), types, - const_generics: Vector::new(), - trait_refs: Vector::new(), + const_generics: CharonVector::new(), + trait_refs: CharonVector::new(), }; - CharonTy::new(CharonTyKind::Adt(TypeId::Tuple, generic_args)) + CharonTy::new(CharonTyKind::Adt(CharonTypeId::Tuple, generic_args)) } RigidTy::FnDef(def_id, args) => { if !args.0.is_empty() { @@ -466,51 +824,60 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let inputs = sig.inputs().iter().map(|ty| self.translate_ty(*ty)).collect(); let output = self.translate_ty(sig.output()); // TODO: populate regions? - CharonTy::new(CharonTyKind::Arrow(Vector::new(), inputs, output)) + CharonTy::new(CharonTyKind::Arrow(CharonVector::new(), inputs, output)) } + RigidTy::Adt(adt_def, genarg ) => { + let def_id = adt_def.def_id(); + let c_typedeclid = self.register_type_decl_id(def_id); + if self.translated.type_decls.get(c_typedeclid).is_none() { + self.translate_adtdef(adt_def); + } + let c_generic_args = self.translate_generic_args(genarg); + CharonTy::new(CharonTyKind::Adt(CharonTypeId::Adt(c_typedeclid), c_generic_args)) + }, _ => todo!(), } } - fn translate_body_locals(&mut self, mir_body: &Body) -> Vector { + fn translate_body_locals(&mut self, mir_body: &Body) -> CharonVector { // Charon expects the locals in the following order: // - the local used for the return value (index 0) // - the input arguments // - the remaining locals, used for the intermediate computations - let mut locals = Vector::new(); + let mut locals = CharonVector::new(); mir_body.local_decls().for_each(|(local, local_decl)| { let ty = self.translate_ty(local_decl.ty); let name = self.local_names.get(&local); - locals.push_with(|index| Var { index, name: name.cloned(), ty }); + locals.push_with(|index| CharonVar { index, name: name.cloned(), ty }); }); locals } - fn translate_block(&mut self, bb: &BasicBlock) -> BlockData { + fn translate_block(&mut self, bb: &BasicBlock) -> CharonBlockData { let mut statements: Vec = bb.statements.iter().filter_map(|stmt| self.translate_statement(stmt)).collect(); let (statement, terminator) = self.translate_terminator(&bb.terminator); if let Some(statement) = statement { statements.push(statement); } - BlockData { statements, terminator } + CharonBlockData { statements, terminator } } fn translate_statement(&mut self, stmt: &Statement) -> Option { let content = match &stmt.kind { - StatementKind::Assign(place, rhs) => Some(RawStatement::Assign( + StatementKind::Assign(place, rhs) => Some(CharonRawStatement::Assign( self.translate_place(&place), self.translate_rvalue(&rhs), )), StatementKind::SetDiscriminant { place, variant_index } => { - Some(RawStatement::SetDiscriminant( + Some(CharonRawStatement::SetDiscriminant( self.translate_place(&place), - VariantId::from_usize(variant_index.to_index()), + CharonVariantId::from_usize(variant_index.to_index()), )) } StatementKind::StorageLive(_) => None, StatementKind::StorageDead(local) => { - Some(RawStatement::StorageDead(VarId::from_usize(*local))) + Some(CharonRawStatement::StorageDead(CharonVarId::from_usize(*local))) } StatementKind::Nop => None, _ => todo!(), @@ -528,21 +895,21 @@ impl<'a, 'tcx> Context<'a, 'tcx> { ) -> (Option, CharonTerminator) { let span = self.translate_span(terminator.span); let (statement, terminator) = match &terminator.kind { - TerminatorKind::Return => (None, RawTerminator::Return), + TerminatorKind::Return => (None, CharonRawTerminator::Return), TerminatorKind::Goto { target } => { - (None, RawTerminator::Goto { target: BlockId::from_usize(*target) }) + (None, CharonRawTerminator::Goto { target: CharonBlockId::from_usize(*target) }) } TerminatorKind::Unreachable => { - (None, RawTerminator::Abort(AbortKind::UndefinedBehavior)) + (None, CharonRawTerminator::Abort(CharonAbortKind::UndefinedBehavior)) } TerminatorKind::Drop { place, target, .. } => { - (Some(RawStatement::Drop(self.translate_place(&place))), RawTerminator::Goto { - target: BlockId::from_usize(*target), + (Some(CharonRawStatement::Drop(self.translate_place(&place))), CharonRawTerminator::Goto { + target: CharonBlockId::from_usize(*target), }) } TerminatorKind::SwitchInt { discr, targets } => { let (discr, targets) = self.translate_switch_targets(discr, targets); - (None, RawTerminator::Switch { discr, targets }) + (None, CharonRawTerminator::Switch { discr, targets }) } TerminatorKind::Call { func, args, destination, target, .. } => { debug!("translate_call: {func:?} {args:?} {destination:?} {target:?}"); @@ -552,14 +919,14 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let instance = Instance::resolve(def, &args).unwrap(); let def_id = instance.def.def_id(); let fid = self.register_fun_decl_id(def_id); - FnPtr { - func: FunIdOrTraitMethodRef::Fun(FunId::Regular(fid)), + CharonFnPtr { + func: CharonFunIdOrTraitMethodRef::Fun(CharonFunId::Regular(fid)), // TODO: populate generics? - generics: GenericArgs { - regions: Vector::new(), - types: Vector::new(), - const_generics: Vector::new(), - trait_refs: Vector::new(), + generics: CharonGenericArgs { + regions: CharonVector::new(), + types: CharonVector::new(), + const_generics: CharonVector::new(), + trait_refs: CharonVector::new(), }, } } @@ -569,22 +936,22 @@ impl<'a, 'tcx> Context<'a, 'tcx> { x ), }; - let func = FnOperand::Regular(fn_ptr); - let call = Call { + let func = CharonFnOperand::Regular(fn_ptr); + let call = CharonCall { func, args: args.iter().map(|arg| self.translate_operand(arg)).collect(), dest: self.translate_place(destination), }; - (Some(RawStatement::Call(call)), RawTerminator::Goto { - target: BlockId::from_usize(target.unwrap()), + (Some(CharonRawStatement::Call(call)), CharonRawTerminator::Goto { + target: CharonBlockId::from_usize(target.unwrap()), }) } TerminatorKind::Assert { cond, expected, msg: _, target, .. } => ( - Some(RawStatement::Assert(Assert { + Some(CharonRawStatement::Assert(CharonAssert { cond: self.translate_operand(cond), expected: *expected, })), - RawTerminator::Goto { target: BlockId::from_usize(*target) }, + CharonRawTerminator::Goto { target: CharonBlockId::from_usize(*target) }, ), _ => todo!(), }; @@ -594,14 +961,20 @@ impl<'a, 'tcx> Context<'a, 'tcx> { ) } - fn translate_place(&self, place: &Place) -> CharonPlace { - let projection = self.translate_projection(&place.projection); + fn translate_place(&mut self, place: &Place) -> CharonPlace { + let projection = self.translate_projection(place, &place.projection); let local = place.local; - let var_id = VarId::from_usize(local); + let var_id = CharonVarId::from_usize(local); CharonPlace { var_id, projection } } - fn translate_rvalue(&self, rvalue: &Rvalue) -> CharonRvalue { + fn place_ty (&self, place: &Place) -> Ty { + let body = self.instance.body().unwrap(); + let ty = body.local_decl(place.local).unwrap().ty; + ty + } + + fn translate_rvalue(&mut self, rvalue: &Rvalue) -> CharonRvalue { trace!("translate_rvalue: {rvalue:?}"); match rvalue { Rvalue::Use(operand) => CharonRvalue::Use(self.translate_operand(operand)), @@ -616,7 +989,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { None, ), Rvalue::Cast(kind, operand, ty) => CharonRvalue::UnaryOp( - UnOp::Cast(self.translate_cast(*kind, operand, *ty)), + CharonUnOp::Cast(self.translate_cast(*kind, operand, *ty)), self.translate_operand(operand), ), Rvalue::BinaryOp(bin_op, lhs, rhs) => CharonRvalue::BinaryOp( @@ -624,10 +997,67 @@ impl<'a, 'tcx> Context<'a, 'tcx> { self.translate_operand(lhs), self.translate_operand(rhs), ), - Rvalue::CheckedBinaryOp(_, _, _) => todo!(), - Rvalue::UnaryOp(_, _) => todo!(), - Rvalue::Discriminant(_) => todo!(), - Rvalue::Aggregate(_, _) => todo!(), + //TODO: recheck + Rvalue::CheckedBinaryOp(bin_op, lhs, rhs) => CharonRvalue::BinaryOp( + translate_bin_op(*bin_op), + self.translate_operand(lhs), + self.translate_operand(rhs), + ), + Rvalue::UnaryOp(op, operand) => CharonRvalue::UnaryOp(translate_un_op(*op), self.translate_operand(operand)), + Rvalue::Discriminant(place) => { + let c_place = self.translate_place(place); + let ty = self.place_ty(place); + let c_ty = self.translate_ty(ty); + match c_ty.kind() { + CharonTyKind::Adt(CharonTypeId::Adt(c_typedeclid), _) => CharonRvalue::Discriminant(c_place, *c_typedeclid), + _ => todo!() + } + }, + + Rvalue::Aggregate(agg_kind, operands) => { + let c_operands = (*operands).iter().map(|operand| self.translate_operand(operand)).collect(); + let akind = agg_kind.clone(); + match akind { + AggregateKind::Adt(adt_def, variant_id , gen_args , user_anot , field_id ) => { + let adt_kind = adt_def.kind(); + match adt_kind { + AdtKind::Enum => { + let def_id = adt_def.def_id(); + let c_typedeclid: CharonTypeDeclId = self.find_type_decl_id(def_id); + let c_type_id = CharonTypeId::Adt(c_typedeclid); + let c_variant_id = Some(CharonVariantId::from_usize(variant_id.to_index())); + let c_field_id = match field_id { + Some(fid) => Some (CharonFieldId::from_usize(fid)), + None => None, + }; + let c_generic_args = CharonGenericArgs::empty(); + let c_agg_kind = CharonAggregateKind::Adt(c_type_id, c_variant_id, c_field_id, c_generic_args); + CharonRvalue::Aggregate(c_agg_kind, c_operands) + }, + AdtKind::Struct => { + let def_id = adt_def.def_id(); + let c_typedeclid: CharonTypeDeclId = self.find_type_decl_id(def_id); + let c_type_id = CharonTypeId::Adt(c_typedeclid); + let c_variant_id = None; + let c_field_id = None; + let c_generic_args = CharonGenericArgs::empty(); + let c_agg_kind = CharonAggregateKind::Adt(c_type_id, c_variant_id, c_field_id, c_generic_args); + CharonRvalue::Aggregate(c_agg_kind, c_operands) + }, + _ =>todo!() + } + }, + AggregateKind::Tuple => CharonRvalue::Aggregate(CharonAggregateKind::Adt(CharonTypeId::Tuple, None, None, CharonGenericArgs::empty()), c_operands), + AggregateKind::Array(ty)=> { + let c_ty = self.translate_ty(ty); + let cg = CharonConstGeneric::Value(CharonLiteral::Scalar(CharonScalarValue::Usize(c_operands.len() as u64,))); + CharonRvalue::Aggregate(CharonAggregateKind::Array(c_ty, cg), c_operands) + } + _ => todo!(), + } + }, + + Rvalue::ShallowInitBox(_, _) => todo!(), Rvalue::CopyForDeref(_) => todo!(), Rvalue::ThreadLocalRef(_) => todo!(), @@ -635,7 +1065,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } - fn translate_operand(&self, operand: &Operand) -> CharonOperand { + fn translate_operand(&mut self, operand: &Operand) -> CharonOperand { trace!("translate_operand: {operand:?}"); match operand { Operand::Constant(constant) => CharonOperand::Const(self.translate_constant(constant)), @@ -644,13 +1074,13 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } - fn translate_constant(&self, constant: &ConstOperand) -> ConstantExpr { + fn translate_constant(&mut self, constant: &ConstOperand) -> CharonConstantExpr { trace!("translate_constant: {constant:?}"); let value = self.translate_constant_value(&constant.const_); - ConstantExpr { value, ty: self.translate_ty(constant.ty()) } + CharonConstantExpr { value, ty: self.translate_ty(constant.ty()) } } - fn translate_constant_value(&self, constant: &MirConst) -> RawConstantExpr { + fn translate_constant_value(&self, constant: &MirConst) -> CharonRawConstantExpr { trace!("translate_constant_value: {constant:?}"); match constant.kind() { ConstantKind::Allocated(alloc) => self.translate_allocation(alloc, constant.ty()), @@ -661,39 +1091,39 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } - fn translate_allocation(&self, alloc: &Allocation, ty: Ty) -> RawConstantExpr { + fn translate_allocation(&self, alloc: &Allocation, ty: Ty) -> CharonRawConstantExpr { match ty.kind() { TyKind::RigidTy(RigidTy::Int(it)) => { let value = alloc.read_int().unwrap(); let scalar_value = match it { - IntTy::I8 => ScalarValue::I8(value as i8), - IntTy::I16 => ScalarValue::I16(value as i16), - IntTy::I32 => ScalarValue::I32(value as i32), - IntTy::I64 => ScalarValue::I64(value as i64), - IntTy::I128 => ScalarValue::I128(value), - IntTy::Isize => ScalarValue::Isize(value as i64), + IntTy::I8 => CharonScalarValue::I8(value as i8), + IntTy::I16 => CharonScalarValue::I16(value as i16), + IntTy::I32 => CharonScalarValue::I32(value as i32), + IntTy::I64 => CharonScalarValue::I64(value as i64), + IntTy::I128 => CharonScalarValue::I128(value), + IntTy::Isize => CharonScalarValue::Isize(value as i64), }; - RawConstantExpr::Literal(Literal::Scalar(scalar_value)) + CharonRawConstantExpr::Literal(CharonLiteral::Scalar(scalar_value)) } TyKind::RigidTy(RigidTy::Uint(uit)) => { let value = alloc.read_uint().unwrap(); let scalar_value = match uit { - UintTy::U8 => ScalarValue::U8(value as u8), - UintTy::U16 => ScalarValue::U16(value as u16), - UintTy::U32 => ScalarValue::U32(value as u32), - UintTy::U64 => ScalarValue::U64(value as u64), - UintTy::U128 => ScalarValue::U128(value), - UintTy::Usize => ScalarValue::Usize(value as u64), + UintTy::U8 => CharonScalarValue::U8(value as u8), + UintTy::U16 => CharonScalarValue::U16(value as u16), + UintTy::U32 => CharonScalarValue::U32(value as u32), + UintTy::U64 => CharonScalarValue::U64(value as u64), + UintTy::U128 => CharonScalarValue::U128(value), + UintTy::Usize => CharonScalarValue::Usize(value as u64), }; - RawConstantExpr::Literal(Literal::Scalar(scalar_value)) + CharonRawConstantExpr::Literal(CharonLiteral::Scalar(scalar_value)) } TyKind::RigidTy(RigidTy::Bool) => { let value = alloc.read_bool().unwrap(); - RawConstantExpr::Literal(Literal::Bool(value)) + CharonRawConstantExpr::Literal(CharonLiteral::Bool(value)) } TyKind::RigidTy(RigidTy::Char) => { let value = char::from_u32(alloc.read_uint().unwrap() as u32); - RawConstantExpr::Literal(Literal::Char(value.unwrap())) + CharonRawConstantExpr::Literal(CharonLiteral::Char(value.unwrap())) } _ => todo!(), } @@ -704,7 +1134,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } fn translate_switch_targets( - &self, + &mut self, discr: &Operand, targets: &SwitchTargets, ) -> (CharonOperand, CharonSwitchTargets) { @@ -719,47 +1149,116 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let (value, bb) = targets.branches().last().unwrap(); let (then_bb, else_bb) = if value == 0 { (targets.otherwise(), bb) } else { (bb, targets.otherwise()) }; - CharonSwitchTargets::If(BlockId::from_usize(then_bb), BlockId::from_usize(else_bb)) + CharonSwitchTargets::If(CharonBlockId::from_usize(then_bb), CharonBlockId::from_usize(else_bb)) } else { - let CharonTyKind::Literal(LiteralTy::Integer(int_ty)) = charon_ty.kind() else { + let CharonTyKind::Literal(CharonLiteralTy::Integer(int_ty)) = charon_ty.kind() else { panic!("Expected integer type for switch discriminant"); }; let branches = targets .branches() .map(|(value, bb)| { let scalar_val = match int_ty { - IntegerTy::I8 => ScalarValue::I8(value as i8), - IntegerTy::I16 => ScalarValue::I16(value as i16), - IntegerTy::I32 => ScalarValue::I32(value as i32), - IntegerTy::I64 => ScalarValue::I64(value as i64), - IntegerTy::I128 => ScalarValue::I128(value as i128), - IntegerTy::Isize => ScalarValue::Isize(value as i64), - IntegerTy::U8 => ScalarValue::U8(value as u8), - IntegerTy::U16 => ScalarValue::U16(value as u16), - IntegerTy::U32 => ScalarValue::U32(value as u32), - IntegerTy::U64 => ScalarValue::U64(value as u64), - IntegerTy::U128 => ScalarValue::U128(value), - IntegerTy::Usize => ScalarValue::Usize(value as u64), + CharonIntegerTy::I8 => CharonScalarValue::I8(value as i8), + CharonIntegerTy::I16 => CharonScalarValue::I16(value as i16), + CharonIntegerTy::I32 => CharonScalarValue::I32(value as i32), + CharonIntegerTy::I64 => CharonScalarValue::I64(value as i64), + CharonIntegerTy::I128 => CharonScalarValue::I128(value as i128), + CharonIntegerTy::Isize => CharonScalarValue::Isize(value as i64), + CharonIntegerTy::U8 => CharonScalarValue::U8(value as u8), + CharonIntegerTy::U16 => CharonScalarValue::U16(value as u16), + CharonIntegerTy::U32 => CharonScalarValue::U32(value as u32), + CharonIntegerTy::U64 => CharonScalarValue::U64(value as u64), + CharonIntegerTy::U128 => CharonScalarValue::U128(value), + CharonIntegerTy::Usize => CharonScalarValue::Usize(value as u64), }; - (scalar_val, BlockId::from_usize(bb)) + (scalar_val, CharonBlockId::from_usize(bb)) }) .collect(); - let otherwise = BlockId::from_usize(targets.otherwise()); + let otherwise = CharonBlockId::from_usize(targets.otherwise()); CharonSwitchTargets::SwitchInt(*int_ty, branches, otherwise) }; (discr, switch_targets) } - fn translate_projection(&self, projection: &[ProjectionElem]) -> Vec { - projection.iter().map(|elem| self.translate_projection_elem(elem)).collect() + fn translate_projection(&mut self, place: &Place, projection: &[ProjectionElem]) -> Vec { + let c_place_ty = self.translate_ty(self.place_ty(place)); + let mut c_provec = Vec::new(); + let mut current_ty = c_place_ty.clone(); + let mut current_var: usize = 0; + for prj in projection.iter() { + match prj { + ProjectionElem::Deref => c_provec.push(CharonProjectionElem::Deref), + ProjectionElem::Field(fid, ty) => { + let c_fieldid = CharonFieldId::from_usize(*fid); + let c_variantid = CharonVariantId::from_usize(current_var); + match current_ty.kind() { + CharonTyKind::Adt(CharonTypeId::Adt(tdid), _) => + { + let adttype = self.translated.type_decls.get(*tdid).unwrap(); + match adttype.kind { + CharonTypeDeclKind::Struct(_) => + { + let c_fprj = CharonFieldProjKind::Adt(*tdid, None); + c_provec.push(CharonProjectionElem::Field(c_fprj, c_fieldid)); + let current_ty = ty.clone(); + } + CharonTypeDeclKind::Enum(_) => + { + let c_fprj = CharonFieldProjKind::Adt(*tdid, Some(c_variantid)); + c_provec.push(CharonProjectionElem::Field(c_fprj, c_fieldid)); + let current_ty = ty.clone(); + } + _ => (),} + } + CharonTyKind::Adt(CharonTypeId::Tuple, genargs) => + { + let c_fprj = CharonFieldProjKind::Tuple((*genargs).types.len()); + c_provec.push(CharonProjectionElem::Field(c_fprj, c_fieldid)); + let current_ty = ty.clone(); + } + _ => () + } + } + ProjectionElem::Downcast(varid) => + { + let current_var = varid.to_index(); + } + + _ => continue, + } + } + c_provec } - - fn translate_projection_elem(&self, projection_elem: &ProjectionElem) -> CharonProjectionElem { +/* + fn translate_projection_elem(&mut self, place: &Place, projection_elem: &ProjectionElem) -> CharonProjectionElem { match projection_elem { ProjectionElem::Deref => CharonProjectionElem::Deref, + /* + ProjectionElem::Downcast(varid) => { + let c_varid = CharonVariantId::from_usize((*varid).to_index()); + let c_place_ty = self.translate_ty(self.place_ty(place)); + let c_typedeclid = *match c_place_ty.kind() { + CharonTyKind::Adt(CharonTypeId::Adt(tdid), _) => tdid, + _ => todo!() + }; + let c_fprj = CharonFieldProjKind::Adt(c_typedeclid, Some(c_varid)); + let c_fieldid = CharonFieldId::from_usize(0); + CharonProjectionElem::Field(c_fprj,c_fieldid) + },*/ + ProjectionElem::Field(fid, ty, ) =>{ + let c_fieldid = CharonFieldId::from_usize(*fid); + let c_place_ty = self.translate_ty(self.place_ty(place)); + let c_fprj = match c_place_ty.kind() { + CharonTyKind::Adt(CharonTypeId::Adt(tdid), _) => CharonFieldProjKind::Adt(*tdid, None), + CharonTyKind::Adt(CharonTypeId::Tuple, genargs) => CharonFieldProjKind::Tuple((*genargs).types.len()), + _ => todo!() + }; + CharonProjectionElem::Field(c_fprj, c_fieldid) + } _ => todo!(), } } +*/ fn translate_region(&self, region: Region) -> CharonRegion { match region.kind { @@ -772,35 +1271,38 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } -fn translate_int_ty(int_ty: IntTy) -> IntegerTy { +fn translate_int_ty(int_ty: IntTy) -> CharonIntegerTy { match int_ty { - IntTy::I8 => IntegerTy::I8, - IntTy::I16 => IntegerTy::I16, - IntTy::I32 => IntegerTy::I32, - IntTy::I64 => IntegerTy::I64, - IntTy::I128 => IntegerTy::I128, + IntTy::I8 => CharonIntegerTy::I8, + IntTy::I16 => CharonIntegerTy::I16, + IntTy::I32 => CharonIntegerTy::I32, + IntTy::I64 => CharonIntegerTy::I64, + IntTy::I128 => CharonIntegerTy::I128, // TODO: assumes 64-bit platform - IntTy::Isize => IntegerTy::I64, + IntTy::Isize => CharonIntegerTy::I64, } } -fn translate_uint_ty(uint_ty: UintTy) -> IntegerTy { +fn translate_uint_ty(uint_ty: UintTy) -> CharonIntegerTy { match uint_ty { - UintTy::U8 => IntegerTy::U8, - UintTy::U16 => IntegerTy::U16, - UintTy::U32 => IntegerTy::U32, - UintTy::U64 => IntegerTy::U64, - UintTy::U128 => IntegerTy::U128, + UintTy::U8 => CharonIntegerTy::U8, + UintTy::U16 => CharonIntegerTy::U16, + UintTy::U32 => CharonIntegerTy::U32, + UintTy::U64 => CharonIntegerTy::U64, + UintTy::U128 => CharonIntegerTy::U128, // TODO: assumes 64-bit platform - UintTy::Usize => IntegerTy::U64, + UintTy::Usize => CharonIntegerTy::U64, } } fn translate_bin_op(bin_op: BinOp) -> CharonBinOp { match bin_op { - BinOp::Add | BinOp::AddUnchecked => CharonBinOp::Add, - BinOp::Sub | BinOp::SubUnchecked => CharonBinOp::Sub, - BinOp::Mul | BinOp::MulUnchecked => CharonBinOp::Mul, + BinOp::AddUnchecked => CharonBinOp::Add, + BinOp::Add => CharonBinOp::CheckedAdd, + BinOp::SubUnchecked => CharonBinOp::Sub, + BinOp::Sub => CharonBinOp::CheckedSub, + BinOp::MulUnchecked => CharonBinOp::Mul, + BinOp::Mul => CharonBinOp::CheckedMul, BinOp::Div => CharonBinOp::Div, BinOp::Rem => CharonBinOp::Rem, BinOp::BitXor => CharonBinOp::BitXor, @@ -819,6 +1321,18 @@ fn translate_bin_op(bin_op: BinOp) -> CharonBinOp { } } + + +fn translate_un_op(un_op: UnOp) -> CharonUnOp { + match un_op { + UnOp::Not => CharonUnOp::Not, + UnOp::Neg => CharonUnOp::Neg, + UnOp::PtrMetadata => todo!() + } + +} + + fn translate_borrow_kind(kind: &BorrowKind) -> CharonBorrowKind { match kind { BorrowKind::Shared => CharonBorrowKind::Shared, @@ -826,3 +1340,14 @@ fn translate_borrow_kind(kind: &BorrowKind) -> CharonBorrowKind { BorrowKind::Fake(_kind) => todo!(), } } + +fn translate_constant_expr_to_const_generic( + value: CharonRawConstantExpr, +) -> Result { + match value { + CharonRawConstantExpr::Literal(v) => Ok(CharonConstGeneric::Value(v)), + CharonRawConstantExpr::Var(v) => Ok(CharonConstGeneric::Var(v)), + _ => todo!() + } + } + diff --git a/tests/expected/llbc/basic0/TestRNvCshcvyQEKZjUj4test4main.symtab.lean b/tests/expected/llbc/basic0/TestRNvCshcvyQEKZjUj4test4main.symtab.lean new file mode 100644 index 000000000000..bcb9aabce301 --- /dev/null +++ b/tests/expected/llbc/basic0/TestRNvCshcvyQEKZjUj4test4main.symtab.lean @@ -0,0 +1,24 @@ +-- THIS FILE WAS AUTOMATICALLY GENERATED BY AENEAS +-- [test] +import Base +open Primitives +set_option linter.dupNamespace false +set_option linter.hashCommand false +set_option linter.unusedVariables false + +namespace test + +/- [test::tuple_fn]: + Source: 'test.rs', lines 38:1-38:33 -/ +def tuple_fn (t : (I32 × I32)) : Result I32 := + let (i, i1) := t + i + i1 + +/- [test::main]: + Source: 'test.rs', lines 43:1-43:10 -/ +def main : Result Unit := + do + let _ ← tuple_fn (1#i32, 2#i32) + Result.ok () + +end test diff --git a/tests/expected/llbc/basic0/expected b/tests/expected/llbc/basic0/expected index 45d073737f3b..bc35dff45272 100644 --- a/tests/expected/llbc/basic0/expected +++ b/tests/expected/llbc/basic0/expected @@ -5,4 +5,4 @@ fn test::is_zero(@1: i32) -> bool\ @0 := copy (i@1) == const (0 : i32)\ return\ -} +} \ No newline at end of file diff --git a/tests/expected/llbc/basic0/test.rs b/tests/expected/llbc/basic0/test.rs index 410cf1848d44..cbd1e0a3a253 100644 --- a/tests/expected/llbc/basic0/test.rs +++ b/tests/expected/llbc/basic0/test.rs @@ -12,4 +12,4 @@ fn is_zero(i: i32) -> bool { #[kani::proof] fn main() { let _ = is_zero(0); -} +} \ No newline at end of file diff --git a/tests/expected/llbc/basic1/TestRNvCshcvyQEKZjUj4test4main.symtab.lean b/tests/expected/llbc/basic1/TestRNvCshcvyQEKZjUj4test4main.symtab.lean new file mode 100644 index 000000000000..e9731570d6b4 --- /dev/null +++ b/tests/expected/llbc/basic1/TestRNvCshcvyQEKZjUj4test4main.symtab.lean @@ -0,0 +1,25 @@ +-- THIS FILE WAS AUTOMATICALLY GENERATED BY AENEAS +-- [test] +import Base +open Primitives +set_option linter.dupNamespace false +set_option linter.hashCommand false +set_option linter.unusedVariables false + +namespace test + +/- [test::select]: + Source: 'test.rs', lines 8:1-8:42 -/ +def select (s : Bool) (x : I32) (y : I32) : Result I32 := + if s + then Result.ok x + else Result.ok y + +/- [test::main]: + Source: 'test.rs', lines 13:1-13:10 -/ +def main : Result Unit := + do + let _ ← select true 3#i32 7#i32 + Result.ok () + +end test diff --git a/tests/expected/llbc/enum_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean b/tests/expected/llbc/enum_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean new file mode 100644 index 000000000000..9460d45ece3b --- /dev/null +++ b/tests/expected/llbc/enum_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean @@ -0,0 +1,31 @@ +-- THIS FILE WAS AUTOMATICALLY GENERATED BY AENEAS +-- [test] +import Base +open Primitives +set_option linter.dupNamespace false +set_option linter.hashCommand false +set_option linter.unusedVariables false + +namespace test + +/- [test::MyEnum] + Source: 'test.rs', lines 8:1-8:12 -/ +inductive MyEnum := +| A : I32 → MyEnum +| B : MyEnum + +/- [test::enum_match]: + Source: 'test.rs', lines 14:1-14:32 -/ +def enum_match (e : MyEnum) : Result I32 := + match e with + | MyEnum.A i => Result.ok i + | MyEnum.B => Result.ok 0#i32 + +/- [test::main]: + Source: 'test.rs', lines 24:1-24:10 -/ +def main : Result Unit := + do + let _ ← enum_match (MyEnum.A 1#i32) + Result.ok () + +end test diff --git a/tests/expected/llbc/enum_test/expected b/tests/expected/llbc/enum_test/expected new file mode 100644 index 000000000000..7b61e8d75ef4 --- /dev/null +++ b/tests/expected/llbc/enum_test/expected @@ -0,0 +1,36 @@ +enum test::MyEnum = +| A(0: i32) +| B() + + +fn test::enum_match(@1: @Adt0) -> i32 +{ + let @0: i32; // return + let e@1: @Adt0; // arg #1 + let i@2: i32; // local + + match e@1 { + 0 => { + i@2 := copy ((e@1 as variant @0).0) + @0 := copy (i@2) + drop i@2 + }, + 1 => { + @0 := const (0 : i32) + }, + } + return +} + +fn test::main() +{ + let @0: (); // return + let e@1: @Adt0; // local + let i@2: i32; // local + + e@1 := test::MyEnum::A { 0: const (1 : i32) } + i@2 := @Fun0(move (e@1)) + drop i@2 + @0 := () + return +} \ No newline at end of file diff --git a/tests/expected/llbc/enum_test/test.rs b/tests/expected/llbc/enum_test/test.rs new file mode 100644 index 000000000000..c271275fa9c0 --- /dev/null +++ b/tests/expected/llbc/enum_test/test.rs @@ -0,0 +1,27 @@ +// Copyright Kani Contributors +// SPDX-License-Identifier: Apache-2.0 OR MIT +// kani-flags: -Zlean --print-llbc + +//! This test checks that Kani's LLBC backend handles simple enum + + +enum MyEnum { + A(i32), + B, +} + + +fn enum_match(e: MyEnum) -> i32 { + match e { + MyEnum::A(i) => i , + MyEnum::B => 0 , + } +} + + + +#[kani::proof] +fn main() { + let e = MyEnum::A(1); + let i = enum_match(e); +} diff --git a/tests/expected/llbc/projection_test/expected b/tests/expected/llbc/projection_test/expected new file mode 100644 index 000000000000..3ce8819a8b21 --- /dev/null +++ b/tests/expected/llbc/projection_test/expected @@ -0,0 +1,49 @@ +struct test::MyStruct = +{ + a: i32, + b: i32, +} + +enum test::MyEnum = +| A(0: @Adt1, 1: i32) +| B() + + +fn test::enum_match(@1: @Adt0) -> i32 +{ + let @0: i32; // return + let e@1: @Adt0; // arg #1 + let s@2: @Adt1; // local + let i@3: i32; // local + let @4: i32; // anonymous local + + match e@1 { + 0 => { + s@2 := move ((e@1 as variant @0).0) + i@3 := copy ((e@1 as variant @0).1) + @4 := copy ((s@2).a) + @0 := copy (@4) + copy (i@3) + drop @4 + drop s@2 + }, + 1 => { + @0 := const (0 : i32) + }, + } + return +} + +fn test::main() +{ + let @0: (); // return + let s@1: @Adt1; // local + let e@2: @Adt0; // local + let i@3: i32; // local + + s@1 := @Adt1 { a: const (1 : i32), b: const (2 : i32) } + e@2 := test::MyEnum::A { 0: move (s@1), 1: const (1 : i32) } + i@3 := @Fun0(move (e@2)) + drop i@3 + @0 := () + return +} \ No newline at end of file diff --git a/tests/expected/llbc/projection_test/test.rs b/tests/expected/llbc/projection_test/test.rs new file mode 100644 index 000000000000..22440d7a9986 --- /dev/null +++ b/tests/expected/llbc/projection_test/test.rs @@ -0,0 +1,32 @@ +// Copyright Kani Contributors +// SPDX-License-Identifier: Apache-2.0 OR MIT +// kani-flags: -Zlean --print-llbc + +//! This test checks that Kani's LLBC backend handles simple projection + +struct MyStruct { + a: i32, + b: i32, +} + +enum MyEnum { + A(MyStruct, i32), + B, +} + + +fn enum_match(e: MyEnum) -> i32 { + match e { + MyEnum::A(s, i) => s.a + i, + MyEnum::B => 0 , + } +} + + + +#[kani::proof] +fn main() { + let s = MyStruct { a: 1, b: 2 }; + let e = MyEnum::A(s,1); + let i = enum_match(e); +} diff --git a/tests/expected/llbc/struct_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean b/tests/expected/llbc/struct_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean new file mode 100644 index 000000000000..3be8da62cf28 --- /dev/null +++ b/tests/expected/llbc/struct_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean @@ -0,0 +1,29 @@ +-- THIS FILE WAS AUTOMATICALLY GENERATED BY AENEAS +-- [test] +import Base +open Primitives +set_option linter.dupNamespace false +set_option linter.hashCommand false +set_option linter.unusedVariables false + +namespace test + +/- [test::MyStruct] + Source: 'test.rs', lines 7:1-7:16 -/ +structure MyStruct where + a : I32 + b : Bool + +/- [test::struct_project]: + Source: 'test.rs', lines 12:1-12:38 -/ +def struct_project (s : MyStruct) : Result I32 := + Result.ok s.a + +/- [test::main]: + Source: 'test.rs', lines 17:1-17:10 -/ +def main : Result Unit := + do + let _ ← struct_project { a := 1#i32, b := true } + Result.ok () + +end test diff --git a/tests/expected/llbc/struct_test/expected b/tests/expected/llbc/struct_test/expected new file mode 100644 index 000000000000..58c90867c732 --- /dev/null +++ b/tests/expected/llbc/struct_test/expected @@ -0,0 +1,27 @@ +struct test::MyStruct = +{ + a: i32, + b: bool, +} + +fn test::struct_project(@1: @Adt0) -> i32 +{ + let @0: i32; // return + let s@1: @Adt0; // arg #1 + + @0 := copy ((s@1).a) + return +} + +fn test::main() +{ + let @0: (); // return + let s@1: @Adt0; // local + let a@2: i32; // local + + s@1 := @Adt0 { a: const (1 : i32), b: const (true) } + a@2 := @Fun0(move (s@1)) + drop a@2 + @0 := () + return +} \ No newline at end of file diff --git a/tests/expected/llbc/struct_test/test.rs b/tests/expected/llbc/struct_test/test.rs new file mode 100644 index 000000000000..14c9bac45258 --- /dev/null +++ b/tests/expected/llbc/struct_test/test.rs @@ -0,0 +1,20 @@ +// Copyright Kani Contributors +// SPDX-License-Identifier: Apache-2.0 OR MIT +// kani-flags: -Zlean --print-llbc + +//! This test checks that Kani's LLBC backend handles simple struct + +struct MyStruct{ + a: i32, + b: bool, +} + +fn struct_project(s: MyStruct) -> i32 { + s.a +} + +#[kani::proof] +fn main() { + let s = MyStruct { a: 1, b: true }; + let a = struct_project(s); +} diff --git a/tests/expected/llbc/tuple_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean b/tests/expected/llbc/tuple_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean new file mode 100644 index 000000000000..0c1c30720a6e --- /dev/null +++ b/tests/expected/llbc/tuple_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean @@ -0,0 +1,24 @@ +-- THIS FILE WAS AUTOMATICALLY GENERATED BY AENEAS +-- [test] +import Base +open Primitives +set_option linter.dupNamespace false +set_option linter.hashCommand false +set_option linter.unusedVariables false + +namespace test + +/- [test::tuple_add]: + Source: 'test.rs', lines 7:1-7:36 -/ +def tuple_add (t : (I32 × I32)) : Result I32 := + let (i, i1) := t + i + i1 + +/- [test::main]: + Source: 'test.rs', lines 12:1-12:10 -/ +def main : Result Unit := + do + let _ ← tuple_add (1#i32, 2#i32) + Result.ok () + +end test diff --git a/tests/expected/llbc/tuple_test/expected b/tests/expected/llbc/tuple_test/expected new file mode 100644 index 000000000000..2459a98f7021 --- /dev/null +++ b/tests/expected/llbc/tuple_test/expected @@ -0,0 +1,28 @@ +fn test::tuple_add(@1: (i32, i32)) -> i32 +{ + let @0: i32; // return + let t@1: (i32, i32); // arg #1 + let @2: i32; // anonymous local + let @3: i32; // anonymous local + + @2 := copy ((t@1).0) + @3 := copy ((t@1).1) + @0 := copy (@2) + copy (@3) + drop @3 + drop @2 + return +} + +fn test::main() +{ + let @0: (); // return + let s@1: i32; // local + let @2: (i32, i32); // anonymous local + + @2 := (const (1 : i32), const (2 : i32)) + s@1 := @Fun0(move (@2)) + drop @2 + drop s@1 + @0 := () + return +} \ No newline at end of file diff --git a/tests/expected/llbc/tuple_test/test.rs b/tests/expected/llbc/tuple_test/test.rs new file mode 100644 index 000000000000..4a2a2cc87141 --- /dev/null +++ b/tests/expected/llbc/tuple_test/test.rs @@ -0,0 +1,14 @@ +// Copyright Kani Contributors +// SPDX-License-Identifier: Apache-2.0 OR MIT +// kani-flags: -Zlean --print-llbc + +//! This test checks that Kani's LLBC backend handles simple tuple + +fn tuple_add (t: (i32, i32)) -> i32 { + t.0 + t.1 +} + +#[kani::proof] +fn main() { + let s = tuple_add((1, 2)); +} diff --git a/tests/perf/s2n-quic b/tests/perf/s2n-quic index cb41b35a9bc0..65d55a48ae49 160000 --- a/tests/perf/s2n-quic +++ b/tests/perf/s2n-quic @@ -1 +1 @@ -Subproject commit cb41b35a9bc0412435b70b5038df0681a881e414 +Subproject commit 65d55a48ae4916c2a0c4ab9a90631668ba8ea23f From 0937022931484f8e7a5740db7bfdccb13b354572 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Fri, 15 Nov 2024 11:08:09 -0800 Subject: [PATCH 02/22] revert changes --- Cargo.lock | 12 ------------ charon | 2 +- tests/perf/s2n-quic | 2 +- 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c1d3b6458e0..a8436fe8dea2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -253,7 +253,6 @@ dependencies = [ "clap", "colored", "convert_case 0.6.0", - "derivative", "derive-visitor", "env_logger", "hashlink", @@ -497,17 +496,6 @@ dependencies = [ "powerfmt", ] -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "derive-visitor" version = "0.4.0" diff --git a/charon b/charon index 2193aa00fd89..454078ebdb4a 160000 --- a/charon +++ b/charon @@ -1 +1 @@ -Subproject commit 2193aa00fd89e991226ada10d8a8f66e0594f212 +Subproject commit 454078ebdb4a607e2b21dc115e1ca99b516e436f diff --git a/tests/perf/s2n-quic b/tests/perf/s2n-quic index 65d55a48ae49..cb41b35a9bc0 160000 --- a/tests/perf/s2n-quic +++ b/tests/perf/s2n-quic @@ -1 +1 @@ -Subproject commit 65d55a48ae4916c2a0c4ab9a90631668ba8ea23f +Subproject commit cb41b35a9bc0412435b70b5038df0681a881e414 From bb789a784e47c5817146c32f8ba9d60a8c1e70aa Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Fri, 15 Nov 2024 11:10:25 -0800 Subject: [PATCH 03/22] format code --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 471 ++++++++++-------- tests/expected/llbc/basic0/test.rs | 2 +- tests/expected/llbc/enum_test/test.rs | 8 +- tests/expected/llbc/projection_test/test.rs | 7 +- tests/expected/llbc/struct_test/test.rs | 2 +- tests/expected/llbc/tuple_test/test.rs | 2 +- 6 files changed, 271 insertions(+), 221 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index 0d006456ea8a..021cea6444eb 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -13,44 +13,54 @@ use std::path::PathBuf; use charon_lib::ast::AggregateKind as CharonAggregateKind; use charon_lib::ast::CastKind as CharonCastKind; +use charon_lib::ast::Field as CharonField; use charon_lib::ast::FieldId as CharonFieldId; use charon_lib::ast::Place as CharonPlace; use charon_lib::ast::ProjectionElem as CharonProjectionElem; use charon_lib::ast::Rvalue as CharonRvalue; use charon_lib::ast::Span as CharonSpan; -use charon_lib::ast::meta::{AttrInfo as CharonAttrInfo, Loc as CharonLoc, RawSpan as CharonRawSpan}; -use charon_lib::ast::types::Ty as CharonTy; -use charon_lib::ast::types::TypeDeclId as CharonTypeDeclId; -use charon_lib::ast::types::TyKind as CharonTyKind; use charon_lib::ast::TypeDecl as CharonTypeDecl; use charon_lib::ast::TypeDeclKind as CharonTypeDeclKind; use charon_lib::ast::Variant as CharonVariant; -use charon_lib::ast::Field as CharonField; -use charon_lib::ast::{AbortKind as CharonAbortKind, Body as CharonBody, Var as CharonVar, VarId as CharonVarId}; +use charon_lib::ast::meta::{ + AttrInfo as CharonAttrInfo, Loc as CharonLoc, RawSpan as CharonRawSpan, +}; +use charon_lib::ast::types::Ty as CharonTy; +use charon_lib::ast::types::TyKind as CharonTyKind; +use charon_lib::ast::types::TypeDeclId as CharonTypeDeclId; +use charon_lib::ast::{ + AbortKind as CharonAbortKind, Body as CharonBody, Var as CharonVar, VarId as CharonVarId, +}; use charon_lib::ast::{ - AnyTransId as CharonAnyTransId, Assert as CharonAssert, BodyId as CharonBodyId, BuiltinTy as CharonBuiltinTy, - Disambiguator as CharonDisambiguator, FileName as CharonFileName, FunDecl as CharonFunDecl, FunSig as CharonFunSig, GenericArgs as CharonGenericArgs, - GenericParams as CharonGenericParams, IntegerTy as CharonIntegerTy, - ItemKind as CharonItemKind, ItemMeta as CharonItemMeta, ItemOpacity as CharonItemOpacity, - Literal as CharonLiteral, LiteralTy as CharonLiteralTy, Name as CharonName, Opaque as CharonOpaque, - PathElem as CharonPathElem, RawConstantExpr as CharonRawConstantExpr, RefKind as CharonRefKind, Region as CharonRegion, ScalarValue as CharonScalarValue, - TranslatedCrate as CharonTranslatedCrate, TypeId as CharonTypeId, RegionId as CharonRegionId, TypeVarId as CharonTypeVarId, UnOp as CharonUnOp, ConstGeneric as CharonConstGeneric, - ConstGenericVarId as CharonConstGenericVarId, FieldProjKind as CharonFieldProjKind, + AnyTransId as CharonAnyTransId, Assert as CharonAssert, BodyId as CharonBodyId, + BuiltinTy as CharonBuiltinTy, ConstGeneric as CharonConstGeneric, + ConstGenericVarId as CharonConstGenericVarId, Disambiguator as CharonDisambiguator, + FieldProjKind as CharonFieldProjKind, FileName as CharonFileName, FunDecl as CharonFunDecl, + FunSig as CharonFunSig, GenericArgs as CharonGenericArgs, GenericParams as CharonGenericParams, + IntegerTy as CharonIntegerTy, ItemKind as CharonItemKind, ItemMeta as CharonItemMeta, + ItemOpacity as CharonItemOpacity, Literal as CharonLiteral, LiteralTy as CharonLiteralTy, + Name as CharonName, Opaque as CharonOpaque, PathElem as CharonPathElem, + RawConstantExpr as CharonRawConstantExpr, RefKind as CharonRefKind, Region as CharonRegion, + RegionId as CharonRegionId, ScalarValue as CharonScalarValue, + TranslatedCrate as CharonTranslatedCrate, TypeId as CharonTypeId, TypeVarId as CharonTypeVarId, + UnOp as CharonUnOp, }; use charon_lib::ast::{ - BinOp as CharonBinOp, Call as CharonCall, FnOperand as CharonFnOperand, FnPtr as CharonFnPtr, - FunDeclId as CharonFunDeclId, FunId as CharonFunId, FunIdOrTraitMethodRef as CharonFunIdOrTraitMethodRef, VariantId as CharonVariantId, + BinOp as CharonBinOp, Call as CharonCall, FnOperand as CharonFnOperand, FnPtr as CharonFnPtr, + FunDeclId as CharonFunDeclId, FunId as CharonFunId, + FunIdOrTraitMethodRef as CharonFunIdOrTraitMethodRef, VariantId as CharonVariantId, }; use charon_lib::ast::{ - BorrowKind as CharonBorrowKind, ConstantExpr as CharonConstantExpr, Operand as CharonOperand, + BorrowKind as CharonBorrowKind, ConstantExpr as CharonConstantExpr, Operand as CharonOperand, }; use charon_lib::errors::Error as CharonError; use charon_lib::errors::ErrorCtx as CharonErrorCtx; use charon_lib::ids::Vector as CharonVector; use charon_lib::ullbc_ast::{ - BlockData as CharonBlockData, BlockId as CharonBlockId, BodyContents as CharonBodyContents, ExprBody as CharonExprBody, - RawStatement as CharonRawStatement, RawTerminator as CharonRawTerminator, Statement as CharonStatement, SwitchTargets as CharonSwitchTargets, - Terminator as CharonTerminator, + BlockData as CharonBlockData, BlockId as CharonBlockId, BodyContents as CharonBodyContents, + ExprBody as CharonExprBody, RawStatement as CharonRawStatement, + RawTerminator as CharonRawTerminator, Statement as CharonStatement, + SwitchTargets as CharonSwitchTargets, Terminator as CharonTerminator, }; use charon_lib::{error_assert, error_or_panic}; use rustc_data_structures::fx::FxHashMap; @@ -58,22 +68,23 @@ use rustc_data_structures::stable_hasher::HashStable; use rustc_middle::ty::AdtKind as MirAdtKind; use rustc_middle::ty::TyCtxt; use rustc_smir::rustc_internal; -use stable_mir::ty::AdtDef; -use stable_mir::ty::AdtKind; use stable_mir::abi::PassMode; use stable_mir::mir::AggregateKind; use stable_mir::mir::VarDebugInfoContents; use stable_mir::mir::mono::Instance; use stable_mir::mir::mono::InstanceDef; use stable_mir::mir::{ - BasicBlock, BinOp, UnOp, Body, BorrowKind, CastKind, ConstOperand, Local, Mutability, Operand, Place, + BasicBlock, BinOp, Body, BorrowKind, CastKind, ConstOperand, Local, Mutability, Operand, Place, ProjectionElem, Rvalue, Statement, StatementKind, SwitchTargets, Terminator, TerminatorKind, + UnOp, }; +use stable_mir::ty::AdtDef; +use stable_mir::ty::AdtKind; use stable_mir::ty::{ - Allocation, ConstantKind, IndexedVal, IntTy, MirConst, Region, RegionKind, RigidTy, Span, Ty, - TyKind, UintTy, TyConst, TyConstId, TraitDef, TyConstKind + Allocation, ConstantKind, IndexedVal, IntTy, MirConst, Region, RegionKind, RigidTy, Span, + TraitDef, Ty, TyConst, TyConstId, TyConstKind, TyKind, UintTy, }; -use stable_mir::ty::{GenericArgs, GenericArgKind}; +use stable_mir::ty::{GenericArgKind, GenericArgs}; use stable_mir::{CrateDef, DefId}; use syn::token::Default; use tracing::{debug, trace}; @@ -146,8 +157,13 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } }; - let fun_decl = - CharonFunDecl { def_id: fid, item_meta, signature, kind: CharonItemKind::Regular, body: Ok(body) }; + let fun_decl = CharonFunDecl { + def_id: fid, + item_meta, + signature, + kind: CharonItemKind::Regular, + body: Ok(body), + }; self.translated.fun_decls.set_slot(fid, fun_decl); @@ -173,7 +189,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { fn find_fun_decl_id(&self, def_id: DefId) -> CharonFunDeclId { debug!("register_fun_decl_id: {:?}", def_id); - let tid = *self.id_map.get(&def_id).unwrap(); + let tid = *self.id_map.get(&def_id).unwrap(); debug!("register_fun_decl_id: {:?}", self.id_map); tid.try_into().unwrap() } @@ -192,11 +208,11 @@ impl<'a, 'tcx> Context<'a, 'tcx> { }; debug!("register_type_decl_id: {:?}", self.id_map); tid.try_into().unwrap() - } + } fn find_type_decl_id(&self, def_id: DefId) -> CharonTypeDeclId { debug!("register_type_decl_id: {:?}", def_id); - let tid = *self.id_map.get(&def_id).unwrap(); + let tid = *self.id_map.get(&def_id).unwrap(); debug!("register_type_decl_id: {:?}", self.id_map); tid.try_into().unwrap() } @@ -207,70 +223,87 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonScalarValue::from_bits(int_ty, discr_val) } - fn translate_adtdef(&mut self, adt_def: AdtDef) -> CharonTypeDeclId { match adt_def.kind() { AdtKind::Enum => { - let def_id = adt_def.def_id(); + let def_id = adt_def.def_id(); let c_typedeclid = self.register_type_decl_id(def_id); - let mut c_variants: CharonVector = CharonVector::new(); - for var_def in adt_def.variants_iter(){ - let mut c_fields: CharonVector = CharonVector::new(); - for field_def in var_def.fields(){ + let mut c_variants: CharonVector = + CharonVector::new(); + for var_def in adt_def.variants_iter() { + let mut c_fields: CharonVector = + CharonVector::new(); + for field_def in var_def.fields() { let c_field_ty = self.translate_ty(field_def.ty()); let c_field_name = Some(field_def.name); let c_span = self.translate_span(adt_def.span()); let c_field = CharonField { - span : c_span, - attr_info : CharonAttrInfo { attributes: Vec::new(), inline: None, rename: None, public: true }, + span: c_span, + attr_info: CharonAttrInfo { + attributes: Vec::new(), + inline: None, + rename: None, + public: true, + }, name: c_field_name, ty: c_field_ty, }; c_fields.push(c_field); } let var_name = var_def.name(); - let span = self.translate_span(adt_def.span()); + let span = self.translate_span(adt_def.span()); let adtdef_internal = rustc_internal::internal(self.tcx, adt_def); let variant_index_internal = rustc_internal::internal(self.tcx, var_def.idx); - let discr = adtdef_internal.discriminant_for_variant(self.tcx, variant_index_internal); + let discr = + adtdef_internal.discriminant_for_variant(self.tcx, variant_index_internal); let discr_val = discr.val; let discr_ty = rustc_internal::stable(discr.ty); let c_discr = self.get_discriminant(discr_val, discr_ty); - let c_variant = CharonVariant{ - span : span, - attr_info : CharonAttrInfo { attributes: Vec::new(), inline: None, rename: None, public: true }, - name : var_name, - fields : c_fields, - discriminant : c_discr, + let c_variant = CharonVariant { + span: span, + attr_info: CharonAttrInfo { + attributes: Vec::new(), + inline: None, + rename: None, + public: true, + }, + name: var_name, + fields: c_fields, + discriminant: c_discr, }; let c_varidx = c_variants.push(c_variant); assert_eq!(c_varidx.index(), var_def.idx.to_index()); - } + } let item_meta = self.translate_item_meta_adt(adt_def).unwrap(); let typedecl = CharonTypeDecl { def_id: c_typedeclid, generics: CharonGenericParams::empty(), kind: CharonTypeDeclKind::Enum(c_variants), - item_meta : item_meta, + item_meta: item_meta, }; self.translated.type_decls.set_slot(c_typedeclid, typedecl); c_typedeclid } AdtKind::Struct => { - let def_id = adt_def.def_id(); + let def_id = adt_def.def_id(); let c_typedeclid = self.register_type_decl_id(def_id); let mut c_fields: CharonVector = CharonVector::new(); let only_variant = *adt_def.variants().first().unwrap(); let fields = only_variant.fields(); - for field_def in fields{ + for field_def in fields { let c_field_ty = self.translate_ty(field_def.ty()); let c_field_name = Some(field_def.name); let c_span = self.translate_span(adt_def.span()); let c_field = CharonField { - span : c_span, - attr_info : CharonAttrInfo { attributes: Vec::new(), inline: None, rename: None, public: true }, + span: c_span, + attr_info: CharonAttrInfo { + attributes: Vec::new(), + inline: None, + rename: None, + public: true, + }, name: c_field_name, ty: c_field_ty, }; @@ -281,17 +314,20 @@ impl<'a, 'tcx> Context<'a, 'tcx> { def_id: c_typedeclid, generics: CharonGenericParams::empty(), kind: CharonTypeDeclKind::Struct(c_fields), - item_meta : item_meta, + item_meta: item_meta, }; self.translated.type_decls.set_slot(c_typedeclid, typedecl); c_typedeclid } - _ => todo!(), + _ => todo!(), } } /// Compute the meta information for a Rust item identified by its id. - fn translate_item_meta_from_rid(&mut self, instance: Instance) -> Result { + fn translate_item_meta_from_rid( + &mut self, + instance: Instance, + ) -> Result { let span = self.translate_instance_span(instance); let name = self.def_to_name(instance.def)?; // TODO: populate the source text @@ -331,7 +367,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { Ok(CharonItemMeta { span, source_text, attr_info, name, is_local, opacity }) } - /// Retrieve an item name from a [DefId]. /// This function is adapted from Charon: /// https://github.com/AeneasVerif/charon/blob/53530427db2941ce784201e64086766504bc5642/charon/src/bin/charon-driver/translate/translate_ctx.rs#L344 @@ -564,7 +599,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { Ok(CharonName { name }) } - /// Compute the span information for the given instance fn translate_instance_span(&mut self, instance: Instance) -> CharonSpan { self.translate_span(instance.def.span()) @@ -605,7 +639,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { // TODO: populate `generated_from_span` info CharonSpan { span: rspan, generated_from_span: None } } - fn translate_function_signature(&mut self) -> CharonFunSig { let instance = self.instance; @@ -673,71 +706,72 @@ impl<'a, 'tcx> Context<'a, 'tcx> { instance_internal.def.requires_caller_location(self.tcx()) } -/* - fn generic_args_to_generic_params (&self, ga: GenericArgs) -> CharonGenericParams{ - let genvec = ga.0; - let mut c_regions: CharonVector = CharonVector::new(); - let mut c_types: CharonVector = CharonVector::new(); - let mut c_const_generics: CharonVector =CharonVector::new(); - //let mut trait_refs: CharonVector = CharonVector::new(); - for genkind in genvec.iter(){ - match *genkind{ - GenericArgKind::Lifetime(region) => { - let c_region = self.translate_region(region); - c_regions.push(c_region); - } - GenericArgKind::Type(ty) => { - let c_ty = self.translate_ty(ty); - c_types.push(c_ty); - } - GenericArgKind::Const(tc ) => { - let c_const_generic = self.tyconst_to_constgeneric(tc); - c_const_generics.push(c_const_generic); - } - } - } - CharonGenericParams{ - regions : c_regions, - types : c_types, - const_generics : c_const_generics, - trait_clauses : CharonVector::new(), - regions_outlive : Vec::new(), - types_outlive : Vec::new(), - trait_type_constraints : Vec::new(), - } - } -*/ - - fn translate_generic_args (&mut self, ga: GenericArgs) -> CharonGenericArgs{ + /* + fn generic_args_to_generic_params (&self, ga: GenericArgs) -> CharonGenericParams{ let genvec = ga.0; let mut c_regions: CharonVector = CharonVector::new(); let mut c_types: CharonVector = CharonVector::new(); let mut c_const_generics: CharonVector =CharonVector::new(); //let mut trait_refs: CharonVector = CharonVector::new(); for genkind in genvec.iter(){ - let gk = genkind.clone(); - match gk{ + match *genkind{ GenericArgKind::Lifetime(region) => { let c_region = self.translate_region(region); c_regions.push(c_region); - }, + } GenericArgKind::Type(ty) => { let c_ty = self.translate_ty(ty); c_types.push(c_ty); - }, + } GenericArgKind::Const(tc ) => { - let c_const_generic = self.tyconst_to_constgeneric(tc); + let c_const_generic = self.tyconst_to_constgeneric(tc); c_const_generics.push(c_const_generic); } } } - CharonGenericArgs{ + CharonGenericParams{ regions : c_regions, types : c_types, const_generics : c_const_generics, - trait_refs : CharonVector::new(), + trait_clauses : CharonVector::new(), + regions_outlive : Vec::new(), + types_outlive : Vec::new(), + trait_type_constraints : Vec::new(), + } + } + */ + + fn translate_generic_args(&mut self, ga: GenericArgs) -> CharonGenericArgs { + let genvec = ga.0; + let mut c_regions: CharonVector = CharonVector::new(); + let mut c_types: CharonVector = CharonVector::new(); + let mut c_const_generics: CharonVector = + CharonVector::new(); + //let mut trait_refs: CharonVector = CharonVector::new(); + for genkind in genvec.iter() { + let gk = genkind.clone(); + match gk { + GenericArgKind::Lifetime(region) => { + let c_region = self.translate_region(region); + c_regions.push(c_region); + } + GenericArgKind::Type(ty) => { + let c_ty = self.translate_ty(ty); + c_types.push(c_ty); + } + GenericArgKind::Const(tc) => { + let c_const_generic = self.tyconst_to_constgeneric(tc); + c_const_generics.push(c_const_generic); + } } } + CharonGenericArgs { + regions: c_regions, + types: c_types, + const_generics: c_const_generics, + trait_refs: CharonVector::new(), + } + } fn translate_ty(&mut self, ty: Ty) -> CharonTy { match ty.kind() { @@ -750,7 +784,8 @@ impl<'a, 'tcx> Context<'a, 'tcx> { match tyconst.kind() { TyConstKind::Value(ty, alloc) => { let c_raw_constexpr = self.translate_allocation(alloc, *ty); - let c_const_generic = translate_constant_expr_to_const_generic(c_raw_constexpr).unwrap(); + let c_const_generic = + translate_constant_expr_to_const_generic(c_raw_constexpr).unwrap(); c_const_generic } _ => todo!(), @@ -765,9 +800,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { RigidTy::Int(it) => { CharonTy::new(CharonTyKind::Literal(CharonLiteralTy::Integer(translate_int_ty(it)))) } - RigidTy::Uint(uit) => { - CharonTy::new(CharonTyKind::Literal(CharonLiteralTy::Integer(translate_uint_ty(uit)))) - } + RigidTy::Uint(uit) => CharonTy::new(CharonTyKind::Literal(CharonLiteralTy::Integer( + translate_uint_ty(uit), + ))), RigidTy::Never => CharonTy::new(CharonTyKind::Never), RigidTy::Str => CharonTy::new(CharonTyKind::Adt( CharonTypeId::Builtin(CharonBuiltinTy::Str), @@ -794,7 +829,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { types: c_types, const_generics: c_const_generics, trait_refs: CharonVector::new(), - } + }, )) } RigidTy::Ref(region, ty, mutability) => CharonTy::new(CharonTyKind::Ref( @@ -826,15 +861,15 @@ impl<'a, 'tcx> Context<'a, 'tcx> { // TODO: populate regions? CharonTy::new(CharonTyKind::Arrow(CharonVector::new(), inputs, output)) } - RigidTy::Adt(adt_def, genarg ) => { - let def_id = adt_def.def_id(); + RigidTy::Adt(adt_def, genarg) => { + let def_id = adt_def.def_id(); let c_typedeclid = self.register_type_decl_id(def_id); if self.translated.type_decls.get(c_typedeclid).is_none() { self.translate_adtdef(adt_def); } let c_generic_args = self.translate_generic_args(genarg); CharonTy::new(CharonTyKind::Adt(CharonTypeId::Adt(c_typedeclid), c_generic_args)) - }, + } _ => todo!(), } } @@ -902,11 +937,10 @@ impl<'a, 'tcx> Context<'a, 'tcx> { TerminatorKind::Unreachable => { (None, CharonRawTerminator::Abort(CharonAbortKind::UndefinedBehavior)) } - TerminatorKind::Drop { place, target, .. } => { - (Some(CharonRawStatement::Drop(self.translate_place(&place))), CharonRawTerminator::Goto { - target: CharonBlockId::from_usize(*target), - }) - } + TerminatorKind::Drop { place, target, .. } => ( + Some(CharonRawStatement::Drop(self.translate_place(&place))), + CharonRawTerminator::Goto { target: CharonBlockId::from_usize(*target) }, + ), TerminatorKind::SwitchInt { discr, targets } => { let (discr, targets) = self.translate_switch_targets(discr, targets); (None, CharonRawTerminator::Switch { discr, targets }) @@ -968,7 +1002,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonPlace { var_id, projection } } - fn place_ty (&self, place: &Place) -> Ty { + fn place_ty(&self, place: &Place) -> Ty { let body = self.instance.body().unwrap(); let ty = body.local_decl(place.local).unwrap().ty; ty @@ -1003,61 +1037,86 @@ impl<'a, 'tcx> Context<'a, 'tcx> { self.translate_operand(lhs), self.translate_operand(rhs), ), - Rvalue::UnaryOp(op, operand) => CharonRvalue::UnaryOp(translate_un_op(*op), self.translate_operand(operand)), + Rvalue::UnaryOp(op, operand) => { + CharonRvalue::UnaryOp(translate_un_op(*op), self.translate_operand(operand)) + } Rvalue::Discriminant(place) => { let c_place = self.translate_place(place); let ty = self.place_ty(place); let c_ty = self.translate_ty(ty); match c_ty.kind() { - CharonTyKind::Adt(CharonTypeId::Adt(c_typedeclid), _) => CharonRvalue::Discriminant(c_place, *c_typedeclid), - _ => todo!() - } - }, + CharonTyKind::Adt(CharonTypeId::Adt(c_typedeclid), _) => { + CharonRvalue::Discriminant(c_place, *c_typedeclid) + } + _ => todo!(), + } + } Rvalue::Aggregate(agg_kind, operands) => { - let c_operands = (*operands).iter().map(|operand| self.translate_operand(operand)).collect(); + let c_operands = + (*operands).iter().map(|operand| self.translate_operand(operand)).collect(); let akind = agg_kind.clone(); match akind { - AggregateKind::Adt(adt_def, variant_id , gen_args , user_anot , field_id ) => { + AggregateKind::Adt(adt_def, variant_id, gen_args, user_anot, field_id) => { let adt_kind = adt_def.kind(); match adt_kind { AdtKind::Enum => { - let def_id = adt_def.def_id(); + let def_id = adt_def.def_id(); let c_typedeclid: CharonTypeDeclId = self.find_type_decl_id(def_id); let c_type_id = CharonTypeId::Adt(c_typedeclid); - let c_variant_id = Some(CharonVariantId::from_usize(variant_id.to_index())); + let c_variant_id = + Some(CharonVariantId::from_usize(variant_id.to_index())); let c_field_id = match field_id { - Some(fid) => Some (CharonFieldId::from_usize(fid)), + Some(fid) => Some(CharonFieldId::from_usize(fid)), None => None, - }; + }; let c_generic_args = CharonGenericArgs::empty(); - let c_agg_kind = CharonAggregateKind::Adt(c_type_id, c_variant_id, c_field_id, c_generic_args); + let c_agg_kind = CharonAggregateKind::Adt( + c_type_id, + c_variant_id, + c_field_id, + c_generic_args, + ); CharonRvalue::Aggregate(c_agg_kind, c_operands) - }, + } AdtKind::Struct => { let def_id = adt_def.def_id(); let c_typedeclid: CharonTypeDeclId = self.find_type_decl_id(def_id); let c_type_id = CharonTypeId::Adt(c_typedeclid); - let c_variant_id = None; + let c_variant_id = None; let c_field_id = None; let c_generic_args = CharonGenericArgs::empty(); - let c_agg_kind = CharonAggregateKind::Adt(c_type_id, c_variant_id, c_field_id, c_generic_args); + let c_agg_kind = CharonAggregateKind::Adt( + c_type_id, + c_variant_id, + c_field_id, + c_generic_args, + ); CharonRvalue::Aggregate(c_agg_kind, c_operands) - }, - _ =>todo!() + } + _ => todo!(), } - }, - AggregateKind::Tuple => CharonRvalue::Aggregate(CharonAggregateKind::Adt(CharonTypeId::Tuple, None, None, CharonGenericArgs::empty()), c_operands), - AggregateKind::Array(ty)=> { + } + AggregateKind::Tuple => CharonRvalue::Aggregate( + CharonAggregateKind::Adt( + CharonTypeId::Tuple, + None, + None, + CharonGenericArgs::empty(), + ), + c_operands, + ), + AggregateKind::Array(ty) => { let c_ty = self.translate_ty(ty); - let cg = CharonConstGeneric::Value(CharonLiteral::Scalar(CharonScalarValue::Usize(c_operands.len() as u64,))); + let cg = CharonConstGeneric::Value(CharonLiteral::Scalar( + CharonScalarValue::Usize(c_operands.len() as u64), + )); CharonRvalue::Aggregate(CharonAggregateKind::Array(c_ty, cg), c_operands) } _ => todo!(), - } - }, + } + } - Rvalue::ShallowInitBox(_, _) => todo!(), Rvalue::CopyForDeref(_) => todo!(), Rvalue::ThreadLocalRef(_) => todo!(), @@ -1149,7 +1208,10 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let (value, bb) = targets.branches().last().unwrap(); let (then_bb, else_bb) = if value == 0 { (targets.otherwise(), bb) } else { (bb, targets.otherwise()) }; - CharonSwitchTargets::If(CharonBlockId::from_usize(then_bb), CharonBlockId::from_usize(else_bb)) + CharonSwitchTargets::If( + CharonBlockId::from_usize(then_bb), + CharonBlockId::from_usize(else_bb), + ) } else { let CharonTyKind::Literal(CharonLiteralTy::Integer(int_ty)) = charon_ty.kind() else { panic!("Expected integer type for switch discriminant"); @@ -1180,85 +1242,85 @@ impl<'a, 'tcx> Context<'a, 'tcx> { (discr, switch_targets) } - fn translate_projection(&mut self, place: &Place, projection: &[ProjectionElem]) -> Vec { + fn translate_projection( + &mut self, + place: &Place, + projection: &[ProjectionElem], + ) -> Vec { let c_place_ty = self.translate_ty(self.place_ty(place)); let mut c_provec = Vec::new(); let mut current_ty = c_place_ty.clone(); let mut current_var: usize = 0; - for prj in projection.iter() { + for prj in projection.iter() { match prj { ProjectionElem::Deref => c_provec.push(CharonProjectionElem::Deref), ProjectionElem::Field(fid, ty) => { let c_fieldid = CharonFieldId::from_usize(*fid); let c_variantid = CharonVariantId::from_usize(current_var); match current_ty.kind() { - CharonTyKind::Adt(CharonTypeId::Adt(tdid), _) => - { + CharonTyKind::Adt(CharonTypeId::Adt(tdid), _) => { let adttype = self.translated.type_decls.get(*tdid).unwrap(); match adttype.kind { - CharonTypeDeclKind::Struct(_) => - { - let c_fprj = CharonFieldProjKind::Adt(*tdid, None); - c_provec.push(CharonProjectionElem::Field(c_fprj, c_fieldid)); - let current_ty = ty.clone(); - } - CharonTypeDeclKind::Enum(_) => - { - let c_fprj = CharonFieldProjKind::Adt(*tdid, Some(c_variantid)); - c_provec.push(CharonProjectionElem::Field(c_fprj, c_fieldid)); - let current_ty = ty.clone(); - } - _ => (),} - } - CharonTyKind::Adt(CharonTypeId::Tuple, genargs) => - { - let c_fprj = CharonFieldProjKind::Tuple((*genargs).types.len()); - c_provec.push(CharonProjectionElem::Field(c_fprj, c_fieldid)); - let current_ty = ty.clone(); + CharonTypeDeclKind::Struct(_) => { + let c_fprj = CharonFieldProjKind::Adt(*tdid, None); + c_provec.push(CharonProjectionElem::Field(c_fprj, c_fieldid)); + let current_ty = ty.clone(); + } + CharonTypeDeclKind::Enum(_) => { + let c_fprj = CharonFieldProjKind::Adt(*tdid, Some(c_variantid)); + c_provec.push(CharonProjectionElem::Field(c_fprj, c_fieldid)); + let current_ty = ty.clone(); + } + _ => (), } - _ => () } - } - ProjectionElem::Downcast(varid) => - { - let current_var = varid.to_index(); + CharonTyKind::Adt(CharonTypeId::Tuple, genargs) => { + let c_fprj = CharonFieldProjKind::Tuple((*genargs).types.len()); + c_provec.push(CharonProjectionElem::Field(c_fprj, c_fieldid)); + let current_ty = ty.clone(); + } + _ => (), } - - _ => continue, } + ProjectionElem::Downcast(varid) => { + let current_var = varid.to_index(); + } + + _ => continue, + } } c_provec } -/* - fn translate_projection_elem(&mut self, place: &Place, projection_elem: &ProjectionElem) -> CharonProjectionElem { - match projection_elem { - ProjectionElem::Deref => CharonProjectionElem::Deref, - /* - ProjectionElem::Downcast(varid) => { - let c_varid = CharonVariantId::from_usize((*varid).to_index()); - let c_place_ty = self.translate_ty(self.place_ty(place)); - let c_typedeclid = *match c_place_ty.kind() { - CharonTyKind::Adt(CharonTypeId::Adt(tdid), _) => tdid, - _ => todo!() - }; - let c_fprj = CharonFieldProjKind::Adt(c_typedeclid, Some(c_varid)); - let c_fieldid = CharonFieldId::from_usize(0); - CharonProjectionElem::Field(c_fprj,c_fieldid) - },*/ - ProjectionElem::Field(fid, ty, ) =>{ - let c_fieldid = CharonFieldId::from_usize(*fid); - let c_place_ty = self.translate_ty(self.place_ty(place)); - let c_fprj = match c_place_ty.kind() { - CharonTyKind::Adt(CharonTypeId::Adt(tdid), _) => CharonFieldProjKind::Adt(*tdid, None), - CharonTyKind::Adt(CharonTypeId::Tuple, genargs) => CharonFieldProjKind::Tuple((*genargs).types.len()), - _ => todo!() - }; - CharonProjectionElem::Field(c_fprj, c_fieldid) + /* + fn translate_projection_elem(&mut self, place: &Place, projection_elem: &ProjectionElem) -> CharonProjectionElem { + match projection_elem { + ProjectionElem::Deref => CharonProjectionElem::Deref, + /* + ProjectionElem::Downcast(varid) => { + let c_varid = CharonVariantId::from_usize((*varid).to_index()); + let c_place_ty = self.translate_ty(self.place_ty(place)); + let c_typedeclid = *match c_place_ty.kind() { + CharonTyKind::Adt(CharonTypeId::Adt(tdid), _) => tdid, + _ => todo!() + }; + let c_fprj = CharonFieldProjKind::Adt(c_typedeclid, Some(c_varid)); + let c_fieldid = CharonFieldId::from_usize(0); + CharonProjectionElem::Field(c_fprj,c_fieldid) + },*/ + ProjectionElem::Field(fid, ty, ) =>{ + let c_fieldid = CharonFieldId::from_usize(*fid); + let c_place_ty = self.translate_ty(self.place_ty(place)); + let c_fprj = match c_place_ty.kind() { + CharonTyKind::Adt(CharonTypeId::Adt(tdid), _) => CharonFieldProjKind::Adt(*tdid, None), + CharonTyKind::Adt(CharonTypeId::Tuple, genargs) => CharonFieldProjKind::Tuple((*genargs).types.len()), + _ => todo!() + }; + CharonProjectionElem::Field(c_fprj, c_fieldid) + } + _ => todo!(), } - _ => todo!(), } - } -*/ + */ fn translate_region(&self, region: Region) -> CharonRegion { match region.kind { @@ -1321,18 +1383,14 @@ fn translate_bin_op(bin_op: BinOp) -> CharonBinOp { } } - - fn translate_un_op(un_op: UnOp) -> CharonUnOp { match un_op { UnOp::Not => CharonUnOp::Not, UnOp::Neg => CharonUnOp::Neg, - UnOp::PtrMetadata => todo!() + UnOp::PtrMetadata => todo!(), } - } - fn translate_borrow_kind(kind: &BorrowKind) -> CharonBorrowKind { match kind { BorrowKind::Shared => CharonBorrowKind::Shared, @@ -1347,7 +1405,6 @@ fn translate_constant_expr_to_const_generic( match value { CharonRawConstantExpr::Literal(v) => Ok(CharonConstGeneric::Value(v)), CharonRawConstantExpr::Var(v) => Ok(CharonConstGeneric::Var(v)), - _ => todo!() - } + _ => todo!(), } - +} diff --git a/tests/expected/llbc/basic0/test.rs b/tests/expected/llbc/basic0/test.rs index cbd1e0a3a253..410cf1848d44 100644 --- a/tests/expected/llbc/basic0/test.rs +++ b/tests/expected/llbc/basic0/test.rs @@ -12,4 +12,4 @@ fn is_zero(i: i32) -> bool { #[kani::proof] fn main() { let _ = is_zero(0); -} \ No newline at end of file +} diff --git a/tests/expected/llbc/enum_test/test.rs b/tests/expected/llbc/enum_test/test.rs index c271275fa9c0..ee5c75e4b780 100644 --- a/tests/expected/llbc/enum_test/test.rs +++ b/tests/expected/llbc/enum_test/test.rs @@ -4,22 +4,18 @@ //! This test checks that Kani's LLBC backend handles simple enum - enum MyEnum { A(i32), B, } - fn enum_match(e: MyEnum) -> i32 { match e { - MyEnum::A(i) => i , - MyEnum::B => 0 , + MyEnum::A(i) => i, + MyEnum::B => 0, } } - - #[kani::proof] fn main() { let e = MyEnum::A(1); diff --git a/tests/expected/llbc/projection_test/test.rs b/tests/expected/llbc/projection_test/test.rs index 22440d7a9986..79b9382e34d2 100644 --- a/tests/expected/llbc/projection_test/test.rs +++ b/tests/expected/llbc/projection_test/test.rs @@ -14,19 +14,16 @@ enum MyEnum { B, } - fn enum_match(e: MyEnum) -> i32 { match e { MyEnum::A(s, i) => s.a + i, - MyEnum::B => 0 , + MyEnum::B => 0, } } - - #[kani::proof] fn main() { let s = MyStruct { a: 1, b: 2 }; - let e = MyEnum::A(s,1); + let e = MyEnum::A(s, 1); let i = enum_match(e); } diff --git a/tests/expected/llbc/struct_test/test.rs b/tests/expected/llbc/struct_test/test.rs index 14c9bac45258..f9365de1888e 100644 --- a/tests/expected/llbc/struct_test/test.rs +++ b/tests/expected/llbc/struct_test/test.rs @@ -4,7 +4,7 @@ //! This test checks that Kani's LLBC backend handles simple struct -struct MyStruct{ +struct MyStruct { a: i32, b: bool, } diff --git a/tests/expected/llbc/tuple_test/test.rs b/tests/expected/llbc/tuple_test/test.rs index 4a2a2cc87141..16b054a02cc7 100644 --- a/tests/expected/llbc/tuple_test/test.rs +++ b/tests/expected/llbc/tuple_test/test.rs @@ -4,7 +4,7 @@ //! This test checks that Kani's LLBC backend handles simple tuple -fn tuple_add (t: (i32, i32)) -> i32 { +fn tuple_add(t: (i32, i32)) -> i32 { t.0 + t.1 } From cebeff5f6175f7fd9d13acb20d4951da75eff3e7 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Fri, 15 Nov 2024 11:52:43 -0800 Subject: [PATCH 04/22] edit according to clippy suggestions --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 47 ++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index 021cea6444eb..13e6eb4fbaf9 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -7,7 +7,7 @@ //! unstructured low-level borrow calculus (ULLBC) use core::panic; -use std::any::Any; +//use std::any::Any; //use std::ascii::Char; use std::path::PathBuf; @@ -64,8 +64,8 @@ use charon_lib::ullbc_ast::{ }; use charon_lib::{error_assert, error_or_panic}; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::stable_hasher::HashStable; -use rustc_middle::ty::AdtKind as MirAdtKind; +//use rustc_data_structures::stable_hasher::HashStable; +//use rustc_middle::ty::AdtKind as MirAdtKind; use rustc_middle::ty::TyCtxt; use rustc_smir::rustc_internal; use stable_mir::abi::PassMode; @@ -82,11 +82,11 @@ use stable_mir::ty::AdtDef; use stable_mir::ty::AdtKind; use stable_mir::ty::{ Allocation, ConstantKind, IndexedVal, IntTy, MirConst, Region, RegionKind, RigidTy, Span, - TraitDef, Ty, TyConst, TyConstId, TyConstKind, TyKind, UintTy, + Ty, TyConst, TyConstKind, TyKind, UintTy, }; use stable_mir::ty::{GenericArgKind, GenericArgs}; use stable_mir::{CrateDef, DefId}; -use syn::token::Default; +//use syn::token::Default; use tracing::{debug, trace}; /// A context for translating a single MIR function to ULLBC. @@ -187,12 +187,14 @@ impl<'a, 'tcx> Context<'a, 'tcx> { tid.try_into().unwrap() } + /* fn find_fun_decl_id(&self, def_id: DefId) -> CharonFunDeclId { debug!("register_fun_decl_id: {:?}", def_id); let tid = *self.id_map.get(&def_id).unwrap(); debug!("register_fun_decl_id: {:?}", self.id_map); tid.try_into().unwrap() } + */ fn register_type_decl_id(&mut self, def_id: DefId) -> CharonTypeDeclId { debug!("register_type_decl_id: {:?}", def_id); @@ -262,7 +264,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let c_discr = self.get_discriminant(discr_val, discr_ty); let c_variant = CharonVariant { - span: span, + span, attr_info: CharonAttrInfo { attributes: Vec::new(), inline: None, @@ -281,7 +283,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { def_id: c_typedeclid, generics: CharonGenericParams::empty(), kind: CharonTypeDeclKind::Enum(c_variants), - item_meta: item_meta, + item_meta, }; self.translated.type_decls.set_slot(c_typedeclid, typedecl); c_typedeclid @@ -314,7 +316,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { def_id: c_typedeclid, generics: CharonGenericParams::empty(), kind: CharonTypeDeclKind::Struct(c_fields), - item_meta: item_meta, + item_meta, }; self.translated.type_decls.set_slot(c_typedeclid, typedecl); c_typedeclid @@ -626,6 +628,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonSpan { span: rspan, generated_from_span: None } } +/* fn translate_span_immut(&self, span: Span) -> CharonSpan { let filename = CharonFileName::Local(PathBuf::from(span.get_filename())); let file_id = *self.translated.file_to_id.get(&filename).unwrap(); @@ -639,6 +642,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { // TODO: populate `generated_from_span` info CharonSpan { span: rspan, generated_from_span: None } } +*/ fn translate_function_signature(&mut self) -> CharonFunSig { let instance = self.instance; @@ -784,9 +788,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { match tyconst.kind() { TyConstKind::Value(ty, alloc) => { let c_raw_constexpr = self.translate_allocation(alloc, *ty); - let c_const_generic = - translate_constant_expr_to_const_generic(c_raw_constexpr).unwrap(); - c_const_generic + //let c_const_generic = + //translate_constant_expr_to_const_generic(c_raw_constexpr).unwrap(); + translate_constant_expr_to_const_generic(c_raw_constexpr).unwrap() } _ => todo!(), } @@ -1057,7 +1061,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { (*operands).iter().map(|operand| self.translate_operand(operand)).collect(); let akind = agg_kind.clone(); match akind { - AggregateKind::Adt(adt_def, variant_id, gen_args, user_anot, field_id) => { + AggregateKind::Adt(adt_def, variant_id, _gen_args, _user_anot, field_id) => { let adt_kind = adt_def.kind(); match adt_kind { AdtKind::Enum => { @@ -1066,10 +1070,11 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let c_type_id = CharonTypeId::Adt(c_typedeclid); let c_variant_id = Some(CharonVariantId::from_usize(variant_id.to_index())); - let c_field_id = match field_id { - Some(fid) => Some(CharonFieldId::from_usize(fid)), - None => None, - }; + //let c_field_id = match field_id { + // Some(fid) => Some(CharonFieldId::from_usize(fid)), + // None => None, + //}; + let c_field_id = field_id.map(CharonFieldId::from_usize); let c_generic_args = CharonGenericArgs::empty(); let c_agg_kind = CharonAggregateKind::Adt( c_type_id, @@ -1264,26 +1269,26 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonTypeDeclKind::Struct(_) => { let c_fprj = CharonFieldProjKind::Adt(*tdid, None); c_provec.push(CharonProjectionElem::Field(c_fprj, c_fieldid)); - let current_ty = ty.clone(); + current_ty = self.translate_ty(*ty); } CharonTypeDeclKind::Enum(_) => { let c_fprj = CharonFieldProjKind::Adt(*tdid, Some(c_variantid)); c_provec.push(CharonProjectionElem::Field(c_fprj, c_fieldid)); - let current_ty = ty.clone(); + current_ty = self.translate_ty(*ty); } _ => (), } } CharonTyKind::Adt(CharonTypeId::Tuple, genargs) => { - let c_fprj = CharonFieldProjKind::Tuple((*genargs).types.len()); + let c_fprj = CharonFieldProjKind::Tuple(genargs.types.len()); c_provec.push(CharonProjectionElem::Field(c_fprj, c_fieldid)); - let current_ty = ty.clone(); + current_ty = self.translate_ty(*ty); } _ => (), } } ProjectionElem::Downcast(varid) => { - let current_var = varid.to_index(); + current_var = varid.to_index(); } _ => continue, From 694f7acbf027a8580ffb6f316b6c191512ac5bda Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 18 Nov 2024 10:40:35 -0800 Subject: [PATCH 05/22] add new line at the send of basic0/expected, remove comments in mod.rs --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 1 - ...TestRNvCshcvyQEKZjUj4test4main.symtab.lean | 24 --------------- tests/expected/llbc/basic0/expected | 2 +- ...TestRNvCshcvyQEKZjUj4test4main.symtab.lean | 25 ---------------- ...TestRNvCshcvyQEKZjUj4test4main.symtab.lean | 29 ------------------- ...TestRNvCshcvyQEKZjUj4test4main.symtab.lean | 24 --------------- 6 files changed, 1 insertion(+), 104 deletions(-) delete mode 100644 tests/expected/llbc/basic0/TestRNvCshcvyQEKZjUj4test4main.symtab.lean delete mode 100644 tests/expected/llbc/basic1/TestRNvCshcvyQEKZjUj4test4main.symtab.lean delete mode 100644 tests/expected/llbc/struct_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean delete mode 100644 tests/expected/llbc/tuple_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index 13e6eb4fbaf9..fbcb0e4ec829 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -7,7 +7,6 @@ //! unstructured low-level borrow calculus (ULLBC) use core::panic; -//use std::any::Any; //use std::ascii::Char; use std::path::PathBuf; diff --git a/tests/expected/llbc/basic0/TestRNvCshcvyQEKZjUj4test4main.symtab.lean b/tests/expected/llbc/basic0/TestRNvCshcvyQEKZjUj4test4main.symtab.lean deleted file mode 100644 index bcb9aabce301..000000000000 --- a/tests/expected/llbc/basic0/TestRNvCshcvyQEKZjUj4test4main.symtab.lean +++ /dev/null @@ -1,24 +0,0 @@ --- THIS FILE WAS AUTOMATICALLY GENERATED BY AENEAS --- [test] -import Base -open Primitives -set_option linter.dupNamespace false -set_option linter.hashCommand false -set_option linter.unusedVariables false - -namespace test - -/- [test::tuple_fn]: - Source: 'test.rs', lines 38:1-38:33 -/ -def tuple_fn (t : (I32 × I32)) : Result I32 := - let (i, i1) := t - i + i1 - -/- [test::main]: - Source: 'test.rs', lines 43:1-43:10 -/ -def main : Result Unit := - do - let _ ← tuple_fn (1#i32, 2#i32) - Result.ok () - -end test diff --git a/tests/expected/llbc/basic0/expected b/tests/expected/llbc/basic0/expected index bc35dff45272..45d073737f3b 100644 --- a/tests/expected/llbc/basic0/expected +++ b/tests/expected/llbc/basic0/expected @@ -5,4 +5,4 @@ fn test::is_zero(@1: i32) -> bool\ @0 := copy (i@1) == const (0 : i32)\ return\ -} \ No newline at end of file +} diff --git a/tests/expected/llbc/basic1/TestRNvCshcvyQEKZjUj4test4main.symtab.lean b/tests/expected/llbc/basic1/TestRNvCshcvyQEKZjUj4test4main.symtab.lean deleted file mode 100644 index e9731570d6b4..000000000000 --- a/tests/expected/llbc/basic1/TestRNvCshcvyQEKZjUj4test4main.symtab.lean +++ /dev/null @@ -1,25 +0,0 @@ --- THIS FILE WAS AUTOMATICALLY GENERATED BY AENEAS --- [test] -import Base -open Primitives -set_option linter.dupNamespace false -set_option linter.hashCommand false -set_option linter.unusedVariables false - -namespace test - -/- [test::select]: - Source: 'test.rs', lines 8:1-8:42 -/ -def select (s : Bool) (x : I32) (y : I32) : Result I32 := - if s - then Result.ok x - else Result.ok y - -/- [test::main]: - Source: 'test.rs', lines 13:1-13:10 -/ -def main : Result Unit := - do - let _ ← select true 3#i32 7#i32 - Result.ok () - -end test diff --git a/tests/expected/llbc/struct_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean b/tests/expected/llbc/struct_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean deleted file mode 100644 index 3be8da62cf28..000000000000 --- a/tests/expected/llbc/struct_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean +++ /dev/null @@ -1,29 +0,0 @@ --- THIS FILE WAS AUTOMATICALLY GENERATED BY AENEAS --- [test] -import Base -open Primitives -set_option linter.dupNamespace false -set_option linter.hashCommand false -set_option linter.unusedVariables false - -namespace test - -/- [test::MyStruct] - Source: 'test.rs', lines 7:1-7:16 -/ -structure MyStruct where - a : I32 - b : Bool - -/- [test::struct_project]: - Source: 'test.rs', lines 12:1-12:38 -/ -def struct_project (s : MyStruct) : Result I32 := - Result.ok s.a - -/- [test::main]: - Source: 'test.rs', lines 17:1-17:10 -/ -def main : Result Unit := - do - let _ ← struct_project { a := 1#i32, b := true } - Result.ok () - -end test diff --git a/tests/expected/llbc/tuple_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean b/tests/expected/llbc/tuple_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean deleted file mode 100644 index 0c1c30720a6e..000000000000 --- a/tests/expected/llbc/tuple_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean +++ /dev/null @@ -1,24 +0,0 @@ --- THIS FILE WAS AUTOMATICALLY GENERATED BY AENEAS --- [test] -import Base -open Primitives -set_option linter.dupNamespace false -set_option linter.hashCommand false -set_option linter.unusedVariables false - -namespace test - -/- [test::tuple_add]: - Source: 'test.rs', lines 7:1-7:36 -/ -def tuple_add (t : (I32 × I32)) : Result I32 := - let (i, i1) := t - i + i1 - -/- [test::main]: - Source: 'test.rs', lines 12:1-12:10 -/ -def main : Result Unit := - do - let _ ← tuple_add (1#i32, 2#i32) - Result.ok () - -end test From 6998703382ef5c14f8bf229575ce5ee6730e4c80 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 18 Nov 2024 10:49:55 -0800 Subject: [PATCH 06/22] remove more commented functions --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 96 +------------------ 1 file changed, 1 insertion(+), 95 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index fbcb0e4ec829..ada66212bef0 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -63,8 +63,6 @@ use charon_lib::ullbc_ast::{ }; use charon_lib::{error_assert, error_or_panic}; use rustc_data_structures::fx::FxHashMap; -//use rustc_data_structures::stable_hasher::HashStable; -//use rustc_middle::ty::AdtKind as MirAdtKind; use rustc_middle::ty::TyCtxt; use rustc_smir::rustc_internal; use stable_mir::abi::PassMode; @@ -85,7 +83,6 @@ use stable_mir::ty::{ }; use stable_mir::ty::{GenericArgKind, GenericArgs}; use stable_mir::{CrateDef, DefId}; -//use syn::token::Default; use tracing::{debug, trace}; /// A context for translating a single MIR function to ULLBC. @@ -186,14 +183,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { tid.try_into().unwrap() } - /* - fn find_fun_decl_id(&self, def_id: DefId) -> CharonFunDeclId { - debug!("register_fun_decl_id: {:?}", def_id); - let tid = *self.id_map.get(&def_id).unwrap(); - debug!("register_fun_decl_id: {:?}", self.id_map); - tid.try_into().unwrap() - } - */ fn register_type_decl_id(&mut self, def_id: DefId) -> CharonTypeDeclId { debug!("register_type_decl_id: {:?}", def_id); @@ -627,21 +616,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonSpan { span: rspan, generated_from_span: None } } -/* - fn translate_span_immut(&self, span: Span) -> CharonSpan { - let filename = CharonFileName::Local(PathBuf::from(span.get_filename())); - let file_id = *self.translated.file_to_id.get(&filename).unwrap(); - let lineinfo = span.get_lines(); - let rspan = CharonRawSpan { - file_id, - beg: CharonLoc { line: lineinfo.start_line, col: lineinfo.start_col }, - end: CharonLoc { line: lineinfo.end_line, col: lineinfo.end_col }, - }; - - // TODO: populate `generated_from_span` info - CharonSpan { span: rspan, generated_from_span: None } - } -*/ fn translate_function_signature(&mut self) -> CharonFunSig { let instance = self.instance; @@ -709,41 +683,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { instance_internal.def.requires_caller_location(self.tcx()) } - /* - fn generic_args_to_generic_params (&self, ga: GenericArgs) -> CharonGenericParams{ - let genvec = ga.0; - let mut c_regions: CharonVector = CharonVector::new(); - let mut c_types: CharonVector = CharonVector::new(); - let mut c_const_generics: CharonVector =CharonVector::new(); - //let mut trait_refs: CharonVector = CharonVector::new(); - for genkind in genvec.iter(){ - match *genkind{ - GenericArgKind::Lifetime(region) => { - let c_region = self.translate_region(region); - c_regions.push(c_region); - } - GenericArgKind::Type(ty) => { - let c_ty = self.translate_ty(ty); - c_types.push(c_ty); - } - GenericArgKind::Const(tc ) => { - let c_const_generic = self.tyconst_to_constgeneric(tc); - c_const_generics.push(c_const_generic); - } - } - } - CharonGenericParams{ - regions : c_regions, - types : c_types, - const_generics : c_const_generics, - trait_clauses : CharonVector::new(), - regions_outlive : Vec::new(), - types_outlive : Vec::new(), - trait_type_constraints : Vec::new(), - } - } - */ - fn translate_generic_args(&mut self, ga: GenericArgs) -> CharonGenericArgs { let genvec = ga.0; let mut c_regions: CharonVector = CharonVector::new(); @@ -1069,10 +1008,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let c_type_id = CharonTypeId::Adt(c_typedeclid); let c_variant_id = Some(CharonVariantId::from_usize(variant_id.to_index())); - //let c_field_id = match field_id { - // Some(fid) => Some(CharonFieldId::from_usize(fid)), - // None => None, - //}; let c_field_id = field_id.map(CharonFieldId::from_usize); let c_generic_args = CharonGenericArgs::empty(); let c_agg_kind = CharonAggregateKind::Adt( @@ -1295,36 +1230,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } c_provec } - /* - fn translate_projection_elem(&mut self, place: &Place, projection_elem: &ProjectionElem) -> CharonProjectionElem { - match projection_elem { - ProjectionElem::Deref => CharonProjectionElem::Deref, - /* - ProjectionElem::Downcast(varid) => { - let c_varid = CharonVariantId::from_usize((*varid).to_index()); - let c_place_ty = self.translate_ty(self.place_ty(place)); - let c_typedeclid = *match c_place_ty.kind() { - CharonTyKind::Adt(CharonTypeId::Adt(tdid), _) => tdid, - _ => todo!() - }; - let c_fprj = CharonFieldProjKind::Adt(c_typedeclid, Some(c_varid)); - let c_fieldid = CharonFieldId::from_usize(0); - CharonProjectionElem::Field(c_fprj,c_fieldid) - },*/ - ProjectionElem::Field(fid, ty, ) =>{ - let c_fieldid = CharonFieldId::from_usize(*fid); - let c_place_ty = self.translate_ty(self.place_ty(place)); - let c_fprj = match c_place_ty.kind() { - CharonTyKind::Adt(CharonTypeId::Adt(tdid), _) => CharonFieldProjKind::Adt(*tdid, None), - CharonTyKind::Adt(CharonTypeId::Tuple, genargs) => CharonFieldProjKind::Tuple((*genargs).types.len()), - _ => todo!() - }; - CharonProjectionElem::Field(c_fprj, c_fieldid) - } - _ => todo!(), - } - } - */ + fn translate_region(&self, region: Region) -> CharonRegion { match region.kind { From 75dcb09bbe0f29f044e0a47070b040e4ebc5aba9 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 18 Nov 2024 11:32:11 -0800 Subject: [PATCH 07/22] format code --- .../src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index ada66212bef0..d9dce7216193 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -78,8 +78,8 @@ use stable_mir::mir::{ use stable_mir::ty::AdtDef; use stable_mir::ty::AdtKind; use stable_mir::ty::{ - Allocation, ConstantKind, IndexedVal, IntTy, MirConst, Region, RegionKind, RigidTy, Span, - Ty, TyConst, TyConstKind, TyKind, UintTy, + Allocation, ConstantKind, IndexedVal, IntTy, MirConst, Region, RegionKind, RigidTy, Span, Ty, + TyConst, TyConstKind, TyKind, UintTy, }; use stable_mir::ty::{GenericArgKind, GenericArgs}; use stable_mir::{CrateDef, DefId}; @@ -183,7 +183,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { tid.try_into().unwrap() } - fn register_type_decl_id(&mut self, def_id: DefId) -> CharonTypeDeclId { debug!("register_type_decl_id: {:?}", def_id); let tid = match self.id_map.get(&def_id) { @@ -616,7 +615,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonSpan { span: rspan, generated_from_span: None } } - fn translate_function_signature(&mut self) -> CharonFunSig { let instance = self.instance; let fn_abi = instance.fn_abi().unwrap(); @@ -727,7 +725,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { TyConstKind::Value(ty, alloc) => { let c_raw_constexpr = self.translate_allocation(alloc, *ty); //let c_const_generic = - //translate_constant_expr_to_const_generic(c_raw_constexpr).unwrap(); + //translate_constant_expr_to_const_generic(c_raw_constexpr).unwrap(); translate_constant_expr_to_const_generic(c_raw_constexpr).unwrap() } _ => todo!(), @@ -1231,7 +1229,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { c_provec } - fn translate_region(&self, region: Region) -> CharonRegion { match region.kind { RegionKind::ReStatic => CharonRegion::Static, From 7ac77f34e13494458740087deb3786aa1fb406d9 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 18 Nov 2024 13:19:45 -0800 Subject: [PATCH 08/22] add end lines to expected files for the 4 test cases --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 1 + ...TestRNvCshcvyQEKZjUj4test4main.symtab.lean | 31 ------------------- tests/expected/llbc/enum_test/expected | 2 +- tests/expected/llbc/projection_test/expected | 2 +- tests/expected/llbc/struct_test/expected | 2 +- tests/expected/llbc/tuple_test/expected | 2 +- tests/perf/s2n-quic | 2 +- 7 files changed, 6 insertions(+), 36 deletions(-) delete mode 100644 tests/expected/llbc/enum_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index d9dce7216193..6966b8cbd333 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -199,6 +199,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { tid.try_into().unwrap() } + // similar to register_type_decl_id, but not adding new def_id, used for cases where the def_id has been registered, or in functions that take immut &self fn find_type_decl_id(&self, def_id: DefId) -> CharonTypeDeclId { debug!("register_type_decl_id: {:?}", def_id); let tid = *self.id_map.get(&def_id).unwrap(); diff --git a/tests/expected/llbc/enum_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean b/tests/expected/llbc/enum_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean deleted file mode 100644 index 9460d45ece3b..000000000000 --- a/tests/expected/llbc/enum_test/TestRNvCshcvyQEKZjUj4test4main.symtab.lean +++ /dev/null @@ -1,31 +0,0 @@ --- THIS FILE WAS AUTOMATICALLY GENERATED BY AENEAS --- [test] -import Base -open Primitives -set_option linter.dupNamespace false -set_option linter.hashCommand false -set_option linter.unusedVariables false - -namespace test - -/- [test::MyEnum] - Source: 'test.rs', lines 8:1-8:12 -/ -inductive MyEnum := -| A : I32 → MyEnum -| B : MyEnum - -/- [test::enum_match]: - Source: 'test.rs', lines 14:1-14:32 -/ -def enum_match (e : MyEnum) : Result I32 := - match e with - | MyEnum.A i => Result.ok i - | MyEnum.B => Result.ok 0#i32 - -/- [test::main]: - Source: 'test.rs', lines 24:1-24:10 -/ -def main : Result Unit := - do - let _ ← enum_match (MyEnum.A 1#i32) - Result.ok () - -end test diff --git a/tests/expected/llbc/enum_test/expected b/tests/expected/llbc/enum_test/expected index 7b61e8d75ef4..6c86139a52e8 100644 --- a/tests/expected/llbc/enum_test/expected +++ b/tests/expected/llbc/enum_test/expected @@ -33,4 +33,4 @@ fn test::main() drop i@2 @0 := () return -} \ No newline at end of file +} diff --git a/tests/expected/llbc/projection_test/expected b/tests/expected/llbc/projection_test/expected index 3ce8819a8b21..f159dbef658f 100644 --- a/tests/expected/llbc/projection_test/expected +++ b/tests/expected/llbc/projection_test/expected @@ -46,4 +46,4 @@ fn test::main() drop i@3 @0 := () return -} \ No newline at end of file +} diff --git a/tests/expected/llbc/struct_test/expected b/tests/expected/llbc/struct_test/expected index 58c90867c732..256c930d434a 100644 --- a/tests/expected/llbc/struct_test/expected +++ b/tests/expected/llbc/struct_test/expected @@ -24,4 +24,4 @@ fn test::main() drop a@2 @0 := () return -} \ No newline at end of file +} diff --git a/tests/expected/llbc/tuple_test/expected b/tests/expected/llbc/tuple_test/expected index 2459a98f7021..d6fa6330ca88 100644 --- a/tests/expected/llbc/tuple_test/expected +++ b/tests/expected/llbc/tuple_test/expected @@ -25,4 +25,4 @@ fn test::main() drop s@1 @0 := () return -} \ No newline at end of file +} diff --git a/tests/perf/s2n-quic b/tests/perf/s2n-quic index 4c3ba69e3d71..cb41b35a9bc0 160000 --- a/tests/perf/s2n-quic +++ b/tests/perf/s2n-quic @@ -1 +1 @@ -Subproject commit 4c3ba69e3d71d0a2d7aaf58a4be3dd3c6bceb96b +Subproject commit cb41b35a9bc0412435b70b5038df0681a881e414 From 4d40b53210a0c70e3110c9140ee00ff80459719c Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 18 Nov 2024 13:37:06 -0800 Subject: [PATCH 09/22] remove comments --- kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index 6966b8cbd333..71ef5f50dbef 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -7,7 +7,6 @@ //! unstructured low-level borrow calculus (ULLBC) use core::panic; -//use std::ascii::Char; use std::path::PathBuf; use charon_lib::ast::AggregateKind as CharonAggregateKind; @@ -688,7 +687,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let mut c_types: CharonVector = CharonVector::new(); let mut c_const_generics: CharonVector = CharonVector::new(); - //let mut trait_refs: CharonVector = CharonVector::new(); for genkind in genvec.iter() { let gk = genkind.clone(); match gk { @@ -725,8 +723,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { match tyconst.kind() { TyConstKind::Value(ty, alloc) => { let c_raw_constexpr = self.translate_allocation(alloc, *ty); - //let c_const_generic = - //translate_constant_expr_to_const_generic(c_raw_constexpr).unwrap(); translate_constant_expr_to_const_generic(c_raw_constexpr).unwrap() } _ => todo!(), From 797723376bba463f2fb4582b7d5e9b61acb74a71 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 18 Nov 2024 13:52:12 -0800 Subject: [PATCH 10/22] update s2n-quic --- tests/perf/s2n-quic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/perf/s2n-quic b/tests/perf/s2n-quic index cb41b35a9bc0..4c3ba69e3d71 160000 --- a/tests/perf/s2n-quic +++ b/tests/perf/s2n-quic @@ -1 +1 @@ -Subproject commit cb41b35a9bc0412435b70b5038df0681a881e414 +Subproject commit 4c3ba69e3d71d0a2d7aaf58a4be3dd3c6bceb96b From 28395c5c4f52386c78913834a646afd7a5f9dbc7 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 18 Nov 2024 15:21:44 -0800 Subject: [PATCH 11/22] re-run kani and fix the expected file --- tests/expected/llbc/enum_test/expected | 2 +- tests/expected/llbc/projection_test/expected | 77 ++++++++++++++------ tests/expected/llbc/projection_test/test.rs | 17 ++++- tests/expected/llbc/struct_test/expected | 2 +- tests/expected/llbc/tuple_test/expected | 2 +- 5 files changed, 72 insertions(+), 28 deletions(-) diff --git a/tests/expected/llbc/enum_test/expected b/tests/expected/llbc/enum_test/expected index 6c86139a52e8..549a3bfdeca1 100644 --- a/tests/expected/llbc/enum_test/expected +++ b/tests/expected/llbc/enum_test/expected @@ -29,7 +29,7 @@ fn test::main() let i@2: i32; // local e@1 := test::MyEnum::A { 0: const (1 : i32) } - i@2 := @Fun0(move (e@1)) + i@2 := @Fun1(move (e@1)) drop i@2 @0 := () return diff --git a/tests/expected/llbc/projection_test/expected b/tests/expected/llbc/projection_test/expected index f159dbef658f..0fb9ece76bc6 100644 --- a/tests/expected/llbc/projection_test/expected +++ b/tests/expected/llbc/projection_test/expected @@ -4,30 +4,60 @@ struct test::MyStruct = b: i32, } -enum test::MyEnum = -| A(0: @Adt1, 1: i32) +enum test::MyEnum0 = +| A(0: @Adt0, 1: i32) | B() -fn test::enum_match(@1: @Adt0) -> i32 +enum test::MyEnum = +| A(0: @Adt0, 1: @Adt2) +| B(0: (i32, i32)) + + +fn test::enum_match(@1: @Adt1) -> i32 { let @0: i32; // return - let e@1: @Adt0; // arg #1 - let s@2: @Adt1; // local - let i@3: i32; // local - let @4: i32; // anonymous local + let e@1: @Adt1; // arg #1 + let s@2: @Adt0; // local + let e0@3: @Adt2; // local + let s1@4: @Adt0; // local + let b@5: i32; // local + let @6: i32; // anonymous local + let @7: i32; // anonymous local + let @8: i32; // anonymous local + let a@9: i32; // local + let b@10: i32; // local match e@1 { 0 => { s@2 := move ((e@1 as variant @0).0) - i@3 := copy ((e@1 as variant @0).1) - @4 := copy ((s@2).a) - @0 := copy (@4) + copy (i@3) - drop @4 - drop s@2 + e0@3 := move ((e@1 as variant @0).1) + match e0@3 { + 0 => { + s1@4 := move ((e0@3 as variant @0).0) + b@5 := copy ((e0@3 as variant @0).1) + @6 := copy ((s1@4).a) + @0 := copy (@6) + copy (b@5) + drop @6 + drop s1@4 + drop e0@3 + drop s@2 + }, + 1 => { + @7 := copy ((s@2).a) + @8 := copy ((s@2).b) + @0 := copy (@7) + copy (@8) + drop @8 + drop @7 + drop e0@3 + drop s@2 + }, + } }, 1 => { - @0 := const (0 : i32) + a@9 := copy (((e@1 as variant @1).0).0) + b@10 := copy (((e@1 as variant @1).0).1) + @0 := copy (a@9) + copy (b@10) }, } return @@ -36,14 +66,19 @@ fn test::enum_match(@1: @Adt0) -> i32 fn test::main() { let @0: (); // return - let s@1: @Adt1; // local - let e@2: @Adt0; // local - let i@3: i32; // local - - s@1 := @Adt1 { a: const (1 : i32), b: const (2 : i32) } - e@2 := test::MyEnum::A { 0: move (s@1), 1: const (1 : i32) } - i@3 := @Fun0(move (e@2)) - drop i@3 + let s@1: @Adt0; // local + let s0@2: @Adt0; // local + let e@3: @Adt1; // local + let @4: @Adt2; // anonymous local + let i@5: i32; // local + + s@1 := @Adt0 { a: const (1 : i32), b: const (2 : i32) } + s0@2 := @Adt0 { a: const (1 : i32), b: const (2 : i32) } + @4 := test::MyEnum0::A { 0: move (s0@2), 1: const (1 : i32) } + e@3 := test::MyEnum::A { 0: move (s@1), 1: move (@4) } + drop @4 + i@5 := @Fun1(move (e@3)) + drop i@5 @0 := () return } diff --git a/tests/expected/llbc/projection_test/test.rs b/tests/expected/llbc/projection_test/test.rs index 79b9382e34d2..04aef43a0926 100644 --- a/tests/expected/llbc/projection_test/test.rs +++ b/tests/expected/llbc/projection_test/test.rs @@ -9,21 +9,30 @@ struct MyStruct { b: i32, } -enum MyEnum { +enum MyEnum0 { A(MyStruct, i32), B, } +enum MyEnum { + A(MyStruct, MyEnum0), + B((i32, i32)), +} + fn enum_match(e: MyEnum) -> i32 { match e { - MyEnum::A(s, i) => s.a + i, - MyEnum::B => 0, + MyEnum::A(s, e0) => match e0 { + MyEnum0::A(s1, b) => s1.a + b, + MyEnum0::B => s.a + s.b, + }, + MyEnum::B((a, b)) => a + b, } } #[kani::proof] fn main() { let s = MyStruct { a: 1, b: 2 }; - let e = MyEnum::A(s, 1); + let s0 = MyStruct { a: 1, b: 2 }; + let e = MyEnum::A(s, MyEnum0::A(s0, 1)); let i = enum_match(e); } diff --git a/tests/expected/llbc/struct_test/expected b/tests/expected/llbc/struct_test/expected index 256c930d434a..e686cfaed0bc 100644 --- a/tests/expected/llbc/struct_test/expected +++ b/tests/expected/llbc/struct_test/expected @@ -20,7 +20,7 @@ fn test::main() let a@2: i32; // local s@1 := @Adt0 { a: const (1 : i32), b: const (true) } - a@2 := @Fun0(move (s@1)) + a@2 := @Fun1(move (s@1)) drop a@2 @0 := () return diff --git a/tests/expected/llbc/tuple_test/expected b/tests/expected/llbc/tuple_test/expected index d6fa6330ca88..1475d136b7cc 100644 --- a/tests/expected/llbc/tuple_test/expected +++ b/tests/expected/llbc/tuple_test/expected @@ -20,7 +20,7 @@ fn test::main() let @2: (i32, i32); // anonymous local @2 := (const (1 : i32), const (2 : i32)) - s@1 := @Fun0(move (@2)) + s@1 := @Fun1(move (@2)) drop @2 drop s@1 @0 := () From 2d2f6ce6ef92ac6ed5f9d5c26d779e934eac6c52 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Tue, 19 Nov 2024 10:48:14 -0800 Subject: [PATCH 12/22] change function namne find_type_decl_id to get_type_decl_id --- .../src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index 71ef5f50dbef..d69eb327a007 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -199,7 +199,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } // similar to register_type_decl_id, but not adding new def_id, used for cases where the def_id has been registered, or in functions that take immut &self - fn find_type_decl_id(&self, def_id: DefId) -> CharonTypeDeclId { + fn get_type_decl_id(&self, def_id: DefId) -> CharonTypeDeclId { debug!("register_type_decl_id: {:?}", def_id); let tid = *self.id_map.get(&def_id).unwrap(); debug!("register_type_decl_id: {:?}", self.id_map); @@ -715,7 +715,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { fn translate_ty(&mut self, ty: Ty) -> CharonTy { match ty.kind() { TyKind::RigidTy(rigid_ty) => self.translate_rigid_ty(rigid_ty), - _ => todo!(), + x => unreachable!("Not yet implemented translation for TyKind: {:?}", x), } } @@ -902,10 +902,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } TyKind::RigidTy(RigidTy::FnPtr(..)) => todo!(), - x => unreachable!( - "Function call where the function was of unexpected type: {:?}", - x - ), + x => unreachable!("Function call where the function was of unexpected type: {:?}",x), }; let func = CharonFnOperand::Regular(fn_ptr); let call = CharonCall { From c7298183d4d8bf92340a7446ba1b0c4897c37740 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Tue, 19 Nov 2024 10:55:02 -0800 Subject: [PATCH 13/22] change function namne find_type_decl_id to get_type_decl_id --- kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index d69eb327a007..3cf4823bc8b1 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -996,7 +996,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { match adt_kind { AdtKind::Enum => { let def_id = adt_def.def_id(); - let c_typedeclid: CharonTypeDeclId = self.find_type_decl_id(def_id); + let c_typedeclid: CharonTypeDeclId = self.get_type_decl_id(def_id); let c_type_id = CharonTypeId::Adt(c_typedeclid); let c_variant_id = Some(CharonVariantId::from_usize(variant_id.to_index())); @@ -1012,7 +1012,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } AdtKind::Struct => { let def_id = adt_def.def_id(); - let c_typedeclid: CharonTypeDeclId = self.find_type_decl_id(def_id); + let c_typedeclid: CharonTypeDeclId = self.get_type_decl_id(def_id); let c_type_id = CharonTypeId::Adt(c_typedeclid); let c_variant_id = None; let c_field_id = None; From dbd721564955eb54e2ddadd228ce6d12ff110a43 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Wed, 20 Nov 2024 11:29:19 -0800 Subject: [PATCH 14/22] added the translation for generic params, fixed the formatting --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 110 ++++++++++++++---- 1 file changed, 89 insertions(+), 21 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index 3cf4823bc8b1..c73584f280e3 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -32,16 +32,17 @@ use charon_lib::ast::{ use charon_lib::ast::{ AnyTransId as CharonAnyTransId, Assert as CharonAssert, BodyId as CharonBodyId, BuiltinTy as CharonBuiltinTy, ConstGeneric as CharonConstGeneric, - ConstGenericVarId as CharonConstGenericVarId, Disambiguator as CharonDisambiguator, - FieldProjKind as CharonFieldProjKind, FileName as CharonFileName, FunDecl as CharonFunDecl, - FunSig as CharonFunSig, GenericArgs as CharonGenericArgs, GenericParams as CharonGenericParams, + ConstGenericVar as CharonConstGenericVar, ConstGenericVarId as CharonConstGenericVarId, + Disambiguator as CharonDisambiguator, FieldProjKind as CharonFieldProjKind, + FileName as CharonFileName, FunDecl as CharonFunDecl, FunSig as CharonFunSig, + GenericArgs as CharonGenericArgs, GenericParams as CharonGenericParams, IntegerTy as CharonIntegerTy, ItemKind as CharonItemKind, ItemMeta as CharonItemMeta, ItemOpacity as CharonItemOpacity, Literal as CharonLiteral, LiteralTy as CharonLiteralTy, Name as CharonName, Opaque as CharonOpaque, PathElem as CharonPathElem, RawConstantExpr as CharonRawConstantExpr, RefKind as CharonRefKind, Region as CharonRegion, - RegionId as CharonRegionId, ScalarValue as CharonScalarValue, - TranslatedCrate as CharonTranslatedCrate, TypeId as CharonTypeId, TypeVarId as CharonTypeVarId, - UnOp as CharonUnOp, + RegionId as CharonRegionId, RegionVar as CharonRegionVar, ScalarValue as CharonScalarValue, + TranslatedCrate as CharonTranslatedCrate, TypeId as CharonTypeId, TypeVar as CharonTypeVar, + TypeVarId as CharonTypeVarId, UnOp as CharonUnOp, }; use charon_lib::ast::{ BinOp as CharonBinOp, Call as CharonCall, FnOperand as CharonFnOperand, FnPtr as CharonFnPtr, @@ -212,7 +213,68 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonScalarValue::from_bits(int_ty, discr_val) } - fn translate_adtdef(&mut self, adt_def: AdtDef) -> CharonTypeDeclId { + fn generic_params_from_adtdef(&self, adtdef: AdtDef) -> CharonGenericParams { + let genvec = match adtdef.ty().kind() { + TyKind::RigidTy(RigidTy::Adt(_, genarg)) => genarg.0, + _ => panic!("generic_params_from_adtdef: not an adtdef"), + }; + let mut c_regions: CharonVector = CharonVector::new(); + let mut c_types: CharonVector = CharonVector::new(); + let mut c_const_generics: CharonVector = + CharonVector::new(); + for genkind in genvec.iter() { + let gk = genkind.clone(); + match gk { + GenericArgKind::Lifetime(region) => match region.kind { + RegionKind::ReEarlyParam(epr) => { + let c_region = CharonRegionVar { + index: CharonRegionId::from_usize(epr.index as usize), + name: Some(epr.name), + }; + c_regions.push(c_region); + } + _ => panic!("generic_params_from_adtdef: not an early bound region"), + }, + GenericArgKind::Type(ty) => match ty.kind() { + TyKind::Param(paramty) => { + let c_typevar = CharonTypeVar { + index: CharonTypeVarId::from_usize(paramty.index as usize), + name: paramty.name, + }; + c_types.push(c_typevar); + } + _ => panic!("generic_params_from_adtdef: not a param type"), + }, + GenericArgKind::Const(tc) => { + match tc.kind() { + TyConstKind::Param(paramtc) => { + let lit_ty = CharonLiteralTy::Integer(CharonIntegerTy::I32); //TO BE CHECKED + let c_constgeneric = CharonConstGenericVar { + index: CharonConstGenericVarId::from_usize(paramtc.index as usize), + name: paramtc.name.clone(), + ty: lit_ty, + }; + c_const_generics.push(c_constgeneric); + } + _ => panic!("generic_params_from_adtdef: not a param const"), + } + } + } + } + CharonGenericParams { + regions: c_regions, + types: c_types, + const_generics: c_const_generics, + trait_clauses: CharonVector::new(), + regions_outlive: Vec::new(), + types_outlive: Vec::new(), + trait_type_constraints: Vec::new(), + } + } + + fn translate_adtdef(&mut self, adt_def: AdtDef) -> CharonTypeDecl { + let c_genparam = self.generic_params_from_adtdef(adt_def); + let item_meta = self.translate_item_meta_adt(adt_def).unwrap(); match adt_def.kind() { AdtKind::Enum => { let def_id = adt_def.def_id(); @@ -265,15 +327,14 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let c_varidx = c_variants.push(c_variant); assert_eq!(c_varidx.index(), var_def.idx.to_index()); } - let item_meta = self.translate_item_meta_adt(adt_def).unwrap(); let typedecl = CharonTypeDecl { def_id: c_typedeclid, - generics: CharonGenericParams::empty(), + generics: c_genparam, kind: CharonTypeDeclKind::Enum(c_variants), item_meta, }; - self.translated.type_decls.set_slot(c_typedeclid, typedecl); - c_typedeclid + self.translated.type_decls.set_slot(c_typedeclid, typedecl.clone()); + typedecl } AdtKind::Struct => { let def_id = adt_def.def_id(); @@ -298,15 +359,14 @@ impl<'a, 'tcx> Context<'a, 'tcx> { }; c_fields.push(c_field); } - let item_meta = self.translate_item_meta_adt(adt_def).unwrap(); let typedecl = CharonTypeDecl { def_id: c_typedeclid, - generics: CharonGenericParams::empty(), + generics: c_genparam, kind: CharonTypeDeclKind::Struct(c_fields), item_meta, }; - self.translated.type_decls.set_slot(c_typedeclid, typedecl); - c_typedeclid + self.translated.type_decls.set_slot(c_typedeclid, typedecl.clone()); + typedecl } _ => todo!(), } @@ -460,7 +520,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { found_crate_name = true; name.push(CharonPathElem::Ident(crate_name.clone(), disambiguator)); } - DefPathData::Impl => todo!(), + DefPathData::Impl => {} //will check DefPathData::OpaqueTy => { // TODO: do nothing for now } @@ -715,6 +775,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { fn translate_ty(&mut self, ty: Ty) -> CharonTy { match ty.kind() { TyKind::RigidTy(rigid_ty) => self.translate_rigid_ty(rigid_ty), + TyKind::Param(paramty) => CharonTy::new(CharonTyKind::TypeVar( + CharonTypeVarId::from_usize(paramty.index as usize), + )), x => unreachable!("Not yet implemented translation for TyKind: {:?}", x), } } @@ -902,7 +965,10 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } TyKind::RigidTy(RigidTy::FnPtr(..)) => todo!(), - x => unreachable!("Function call where the function was of unexpected type: {:?}",x), + x => unreachable!( + "Function call where the function was of unexpected type: {:?}", + x + ), }; let func = CharonFnOperand::Regular(fn_ptr); let call = CharonCall { @@ -991,7 +1057,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { (*operands).iter().map(|operand| self.translate_operand(operand)).collect(); let akind = agg_kind.clone(); match akind { - AggregateKind::Adt(adt_def, variant_id, _gen_args, _user_anot, field_id) => { + AggregateKind::Adt(adt_def, variant_id, genarg, _user_anot, field_id) => { let adt_kind = adt_def.kind(); match adt_kind { AdtKind::Enum => { @@ -1001,7 +1067,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let c_variant_id = Some(CharonVariantId::from_usize(variant_id.to_index())); let c_field_id = field_id.map(CharonFieldId::from_usize); - let c_generic_args = CharonGenericArgs::empty(); + let c_generic_args = self.translate_generic_args(genarg); let c_agg_kind = CharonAggregateKind::Adt( c_type_id, c_variant_id, @@ -1016,7 +1082,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let c_type_id = CharonTypeId::Adt(c_typedeclid); let c_variant_id = None; let c_field_id = None; - let c_generic_args = CharonGenericArgs::empty(); + let c_generic_args = self.translate_generic_args(genarg); let c_agg_kind = CharonAggregateKind::Adt( c_type_id, c_variant_id, @@ -1229,7 +1295,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { RegionKind::ReErased => CharonRegion::Erased, RegionKind::ReEarlyParam(_) | RegionKind::ReBound(_, _) - | RegionKind::RePlaceholder(_) => todo!(), + | RegionKind::RePlaceholder(_) => { + unreachable!("Not yet implemented RegionKind: {:?}", region.kind) + } } } } From 997db129b47bf92708215fb6b1738a4e1cdbc246 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Wed, 20 Nov 2024 13:15:38 -0800 Subject: [PATCH 15/22] comment change --- kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index c73584f280e3..e2da5e980e90 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -248,7 +248,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { GenericArgKind::Const(tc) => { match tc.kind() { TyConstKind::Param(paramtc) => { - let lit_ty = CharonLiteralTy::Integer(CharonIntegerTy::I32); //TO BE CHECKED + let lit_ty = CharonLiteralTy::Integer(CharonIntegerTy::I32); //TO BE CHECKED, PARAMENV let c_constgeneric = CharonConstGenericVar { index: CharonConstGenericVarId::from_usize(paramtc.index as usize), name: paramtc.name.clone(), From 3ec593d17d7bf2f450f72039c99e1b8ad29aca3f Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Wed, 20 Nov 2024 14:02:38 -0800 Subject: [PATCH 16/22] fixed the expected testes --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 18 ++++++++++++-- tests/expected/llbc/enum_test/expected | 2 +- tests/expected/llbc/projection_test/expected | 24 +++++++++---------- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index e2da5e980e90..4876e64df541 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -213,7 +213,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonScalarValue::from_bits(int_ty, discr_val) } - fn generic_params_from_adtdef(&self, adtdef: AdtDef) -> CharonGenericParams { + fn generic_params_from_adtdef(&mut self, adtdef: AdtDef) -> CharonGenericParams { let genvec = match adtdef.ty().kind() { TyKind::RigidTy(RigidTy::Adt(_, genarg)) => genarg.0, _ => panic!("generic_params_from_adtdef: not an adtdef"), @@ -248,7 +248,21 @@ impl<'a, 'tcx> Context<'a, 'tcx> { GenericArgKind::Const(tc) => { match tc.kind() { TyConstKind::Param(paramtc) => { - let lit_ty = CharonLiteralTy::Integer(CharonIntegerTy::I32); //TO BE CHECKED, PARAMENV + //let lit_ty = CharonLiteralTy::Integer(CharonIntegerTy::I32); //TO BE CHECKED, PARAMENV + let def_id_internal = + rustc_internal::internal(self.tcx, adtdef.def_id()); + let paramenv = self.tcx.param_env(def_id_internal); + let pc_internal = rustc_middle::ty::ParamConst { + index: paramtc.index, + name: rustc_span::Symbol::intern(¶mtc.name), + }; + let ty_internal = pc_internal.find_ty_from_env(paramenv); + let ty_stable = rustc_internal::stable(ty_internal); + let trans_ty = self.translate_ty(ty_stable); + let lit_ty = match trans_ty.kind() { + CharonTyKind::Literal(lit) => lit.clone(), + _ => panic!("generic_params_from_adtdef: not a literal type"), + }; let c_constgeneric = CharonConstGenericVar { index: CharonConstGenericVarId::from_usize(paramtc.index as usize), name: paramtc.name.clone(), diff --git a/tests/expected/llbc/enum_test/expected b/tests/expected/llbc/enum_test/expected index 549a3bfdeca1..6c86139a52e8 100644 --- a/tests/expected/llbc/enum_test/expected +++ b/tests/expected/llbc/enum_test/expected @@ -29,7 +29,7 @@ fn test::main() let i@2: i32; // local e@1 := test::MyEnum::A { 0: const (1 : i32) } - i@2 := @Fun1(move (e@1)) + i@2 := @Fun0(move (e@1)) drop i@2 @0 := () return diff --git a/tests/expected/llbc/projection_test/expected b/tests/expected/llbc/projection_test/expected index 0fb9ece76bc6..5f71248c8d44 100644 --- a/tests/expected/llbc/projection_test/expected +++ b/tests/expected/llbc/projection_test/expected @@ -5,22 +5,22 @@ struct test::MyStruct = } enum test::MyEnum0 = -| A(0: @Adt0, 1: i32) +| A(0: @Adt1, 1: i32) | B() enum test::MyEnum = -| A(0: @Adt0, 1: @Adt2) +| A(0: @Adt1, 1: @Adt2) | B(0: (i32, i32)) -fn test::enum_match(@1: @Adt1) -> i32 +fn test::enum_match(@1: @Adt0) -> i32 { let @0: i32; // return - let e@1: @Adt1; // arg #1 - let s@2: @Adt0; // local + let e@1: @Adt0; // arg #1 + let s@2: @Adt1; // local let e0@3: @Adt2; // local - let s1@4: @Adt0; // local + let s1@4: @Adt1; // local let b@5: i32; // local let @6: i32; // anonymous local let @7: i32; // anonymous local @@ -66,18 +66,18 @@ fn test::enum_match(@1: @Adt1) -> i32 fn test::main() { let @0: (); // return - let s@1: @Adt0; // local - let s0@2: @Adt0; // local - let e@3: @Adt1; // local + let s@1: @Adt1; // local + let s0@2: @Adt1; // local + let e@3: @Adt0; // local let @4: @Adt2; // anonymous local let i@5: i32; // local - s@1 := @Adt0 { a: const (1 : i32), b: const (2 : i32) } - s0@2 := @Adt0 { a: const (1 : i32), b: const (2 : i32) } + s@1 := @Adt1 { a: const (1 : i32), b: const (2 : i32) } + s0@2 := @Adt1 { a: const (1 : i32), b: const (2 : i32) } @4 := test::MyEnum0::A { 0: move (s0@2), 1: const (1 : i32) } e@3 := test::MyEnum::A { 0: move (s@1), 1: move (@4) } drop @4 - i@5 := @Fun1(move (e@3)) + i@5 := @Fun0(move (e@3)) drop i@5 @0 := () return From 000d098a8f0b253c9376d1acf70528bb14fdea63 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Wed, 20 Nov 2024 14:25:50 -0800 Subject: [PATCH 17/22] fixed clippy --- kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index 4876e64df541..58d46a60c912 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -248,7 +248,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { GenericArgKind::Const(tc) => { match tc.kind() { TyConstKind::Param(paramtc) => { - //let lit_ty = CharonLiteralTy::Integer(CharonIntegerTy::I32); //TO BE CHECKED, PARAMENV let def_id_internal = rustc_internal::internal(self.tcx, adtdef.def_id()); let paramenv = self.tcx.param_env(def_id_internal); @@ -260,7 +259,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let ty_stable = rustc_internal::stable(ty_internal); let trans_ty = self.translate_ty(ty_stable); let lit_ty = match trans_ty.kind() { - CharonTyKind::Literal(lit) => lit.clone(), + CharonTyKind::Literal(lit) => *lit, _ => panic!("generic_params_from_adtdef: not a literal type"), }; let c_constgeneric = CharonConstGenericVar { @@ -802,6 +801,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let c_raw_constexpr = self.translate_allocation(alloc, *ty); translate_constant_expr_to_const_generic(c_raw_constexpr).unwrap() } + TyConstKind::Param(paramc) => CharonConstGeneric::Var(CharonConstGenericVarId::from_usize(paramc.index as usize)), _ => todo!(), } } From 4107f81c7d2b0d6112865d1c2647608ecceafdf6 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Wed, 20 Nov 2024 14:43:01 -0800 Subject: [PATCH 18/22] fixed format --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 53 +++++++++---------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index 58d46a60c912..34e3906fa2b5 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -245,33 +245,30 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } _ => panic!("generic_params_from_adtdef: not a param type"), }, - GenericArgKind::Const(tc) => { - match tc.kind() { - TyConstKind::Param(paramtc) => { - let def_id_internal = - rustc_internal::internal(self.tcx, adtdef.def_id()); - let paramenv = self.tcx.param_env(def_id_internal); - let pc_internal = rustc_middle::ty::ParamConst { - index: paramtc.index, - name: rustc_span::Symbol::intern(¶mtc.name), - }; - let ty_internal = pc_internal.find_ty_from_env(paramenv); - let ty_stable = rustc_internal::stable(ty_internal); - let trans_ty = self.translate_ty(ty_stable); - let lit_ty = match trans_ty.kind() { - CharonTyKind::Literal(lit) => *lit, - _ => panic!("generic_params_from_adtdef: not a literal type"), - }; - let c_constgeneric = CharonConstGenericVar { - index: CharonConstGenericVarId::from_usize(paramtc.index as usize), - name: paramtc.name.clone(), - ty: lit_ty, - }; - c_const_generics.push(c_constgeneric); - } - _ => panic!("generic_params_from_adtdef: not a param const"), + GenericArgKind::Const(tc) => match tc.kind() { + TyConstKind::Param(paramtc) => { + let def_id_internal = rustc_internal::internal(self.tcx, adtdef.def_id()); + let paramenv = self.tcx.param_env(def_id_internal); + let pc_internal = rustc_middle::ty::ParamConst { + index: paramtc.index, + name: rustc_span::Symbol::intern(¶mtc.name), + }; + let ty_internal = pc_internal.find_ty_from_env(paramenv); + let ty_stable = rustc_internal::stable(ty_internal); + let trans_ty = self.translate_ty(ty_stable); + let lit_ty = match trans_ty.kind() { + CharonTyKind::Literal(lit) => *lit, + _ => panic!("generic_params_from_adtdef: not a literal type"), + }; + let c_constgeneric = CharonConstGenericVar { + index: CharonConstGenericVarId::from_usize(paramtc.index as usize), + name: paramtc.name.clone(), + ty: lit_ty, + }; + c_const_generics.push(c_constgeneric); } - } + _ => panic!("generic_params_from_adtdef: not a param const"), + }, } } CharonGenericParams { @@ -801,7 +798,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let c_raw_constexpr = self.translate_allocation(alloc, *ty); translate_constant_expr_to_const_generic(c_raw_constexpr).unwrap() } - TyConstKind::Param(paramc) => CharonConstGeneric::Var(CharonConstGenericVarId::from_usize(paramc.index as usize)), + TyConstKind::Param(paramc) => { + CharonConstGeneric::Var(CharonConstGenericVarId::from_usize(paramc.index as usize)) + } _ => todo!(), } } From 43bd739542994f632da95dad795297216f75dd42 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Thu, 21 Nov 2024 13:35:36 -0800 Subject: [PATCH 19/22] group use statements and add a test that use generic args --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 93 ++++++++----------- tests/expected/llbc/generic_test/expected | 52 +++++++++++ tests/expected/llbc/generic_test/test.rs | 20 ++++ 3 files changed, 112 insertions(+), 53 deletions(-) create mode 100644 tests/expected/llbc/generic_test/expected create mode 100644 tests/expected/llbc/generic_test/test.rs diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index 34e3906fa2b5..b546760cf4ee 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -6,54 +6,36 @@ //! This module contains a context for translating stable MIR into Charon's //! unstructured low-level borrow calculus (ULLBC) -use core::panic; -use std::path::PathBuf; - -use charon_lib::ast::AggregateKind as CharonAggregateKind; -use charon_lib::ast::CastKind as CharonCastKind; -use charon_lib::ast::Field as CharonField; -use charon_lib::ast::FieldId as CharonFieldId; -use charon_lib::ast::Place as CharonPlace; -use charon_lib::ast::ProjectionElem as CharonProjectionElem; -use charon_lib::ast::Rvalue as CharonRvalue; -use charon_lib::ast::Span as CharonSpan; -use charon_lib::ast::TypeDecl as CharonTypeDecl; -use charon_lib::ast::TypeDeclKind as CharonTypeDeclKind; -use charon_lib::ast::Variant as CharonVariant; use charon_lib::ast::meta::{ AttrInfo as CharonAttrInfo, Loc as CharonLoc, RawSpan as CharonRawSpan, }; -use charon_lib::ast::types::Ty as CharonTy; -use charon_lib::ast::types::TyKind as CharonTyKind; -use charon_lib::ast::types::TypeDeclId as CharonTypeDeclId; -use charon_lib::ast::{ - AbortKind as CharonAbortKind, Body as CharonBody, Var as CharonVar, VarId as CharonVarId, +use charon_lib::ast::types::{ + Ty as CharonTy, TyKind as CharonTyKind, TypeDeclId as CharonTypeDeclId, }; use charon_lib::ast::{ - AnyTransId as CharonAnyTransId, Assert as CharonAssert, BodyId as CharonBodyId, - BuiltinTy as CharonBuiltinTy, ConstGeneric as CharonConstGeneric, - ConstGenericVar as CharonConstGenericVar, ConstGenericVarId as CharonConstGenericVarId, - Disambiguator as CharonDisambiguator, FieldProjKind as CharonFieldProjKind, - FileName as CharonFileName, FunDecl as CharonFunDecl, FunSig as CharonFunSig, - GenericArgs as CharonGenericArgs, GenericParams as CharonGenericParams, + AbortKind as CharonAbortKind, AggregateKind as CharonAggregateKind, + AnyTransId as CharonAnyTransId, Assert as CharonAssert, BinOp as CharonBinOp, + Body as CharonBody, BodyId as CharonBodyId, BorrowKind as CharonBorrowKind, + BuiltinTy as CharonBuiltinTy, Call as CharonCall, CastKind as CharonCastKind, + ConstGeneric as CharonConstGeneric, ConstGenericVar as CharonConstGenericVar, + ConstGenericVarId as CharonConstGenericVarId, ConstantExpr as CharonConstantExpr, + Disambiguator as CharonDisambiguator, Field as CharonField, FieldId as CharonFieldId, + FieldProjKind as CharonFieldProjKind, FileName as CharonFileName, FnOperand as CharonFnOperand, + FnPtr as CharonFnPtr, FunDecl as CharonFunDecl, FunDeclId as CharonFunDeclId, + FunId as CharonFunId, FunIdOrTraitMethodRef as CharonFunIdOrTraitMethodRef, + FunSig as CharonFunSig, GenericArgs as CharonGenericArgs, GenericParams as CharonGenericParams, IntegerTy as CharonIntegerTy, ItemKind as CharonItemKind, ItemMeta as CharonItemMeta, ItemOpacity as CharonItemOpacity, Literal as CharonLiteral, LiteralTy as CharonLiteralTy, - Name as CharonName, Opaque as CharonOpaque, PathElem as CharonPathElem, + Name as CharonName, Opaque as CharonOpaque, Operand as CharonOperand, + PathElem as CharonPathElem, Place as CharonPlace, ProjectionElem as CharonProjectionElem, RawConstantExpr as CharonRawConstantExpr, RefKind as CharonRefKind, Region as CharonRegion, - RegionId as CharonRegionId, RegionVar as CharonRegionVar, ScalarValue as CharonScalarValue, - TranslatedCrate as CharonTranslatedCrate, TypeId as CharonTypeId, TypeVar as CharonTypeVar, - TypeVarId as CharonTypeVarId, UnOp as CharonUnOp, -}; -use charon_lib::ast::{ - BinOp as CharonBinOp, Call as CharonCall, FnOperand as CharonFnOperand, FnPtr as CharonFnPtr, - FunDeclId as CharonFunDeclId, FunId as CharonFunId, - FunIdOrTraitMethodRef as CharonFunIdOrTraitMethodRef, VariantId as CharonVariantId, + RegionId as CharonRegionId, RegionVar as CharonRegionVar, Rvalue as CharonRvalue, + ScalarValue as CharonScalarValue, Span as CharonSpan, TranslatedCrate as CharonTranslatedCrate, + TypeDecl as CharonTypeDecl, TypeDeclKind as CharonTypeDeclKind, TypeId as CharonTypeId, + TypeVar as CharonTypeVar, TypeVarId as CharonTypeVarId, UnOp as CharonUnOp, Var as CharonVar, + VarId as CharonVarId, Variant as CharonVariant, VariantId as CharonVariantId, }; -use charon_lib::ast::{ - BorrowKind as CharonBorrowKind, ConstantExpr as CharonConstantExpr, Operand as CharonOperand, -}; -use charon_lib::errors::Error as CharonError; -use charon_lib::errors::ErrorCtx as CharonErrorCtx; +use charon_lib::errors::{Error as CharonError, ErrorCtx as CharonErrorCtx}; use charon_lib::ids::Vector as CharonVector; use charon_lib::ullbc_ast::{ BlockData as CharonBlockData, BlockId as CharonBlockId, BodyContents as CharonBodyContents, @@ -62,27 +44,23 @@ use charon_lib::ullbc_ast::{ SwitchTargets as CharonSwitchTargets, Terminator as CharonTerminator, }; use charon_lib::{error_assert, error_or_panic}; +use core::panic; use rustc_data_structures::fx::FxHashMap; use rustc_middle::ty::TyCtxt; use rustc_smir::rustc_internal; use stable_mir::abi::PassMode; -use stable_mir::mir::AggregateKind; -use stable_mir::mir::VarDebugInfoContents; -use stable_mir::mir::mono::Instance; -use stable_mir::mir::mono::InstanceDef; +use stable_mir::mir::mono::{Instance, InstanceDef}; use stable_mir::mir::{ - BasicBlock, BinOp, Body, BorrowKind, CastKind, ConstOperand, Local, Mutability, Operand, Place, - ProjectionElem, Rvalue, Statement, StatementKind, SwitchTargets, Terminator, TerminatorKind, - UnOp, + AggregateKind, BasicBlock, BinOp, Body, BorrowKind, CastKind, ConstOperand, Local, Mutability, + Operand, Place, ProjectionElem, Rvalue, Statement, StatementKind, SwitchTargets, Terminator, + TerminatorKind, UnOp, VarDebugInfoContents, }; -use stable_mir::ty::AdtDef; -use stable_mir::ty::AdtKind; use stable_mir::ty::{ - Allocation, ConstantKind, IndexedVal, IntTy, MirConst, Region, RegionKind, RigidTy, Span, Ty, - TyConst, TyConstKind, TyKind, UintTy, + AdtDef, AdtKind, Allocation, ConstantKind, GenericArgKind, GenericArgs, IndexedVal, IntTy, + MirConst, Region, RegionKind, RigidTy, Span, Ty, TyConst, TyConstKind, TyKind, UintTy, }; -use stable_mir::ty::{GenericArgKind, GenericArgs}; use stable_mir::{CrateDef, DefId}; +use std::path::PathBuf; use tracing::{debug, trace}; /// A context for translating a single MIR function to ULLBC. @@ -788,7 +766,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { TyKind::Param(paramty) => CharonTy::new(CharonTyKind::TypeVar( CharonTypeVarId::from_usize(paramty.index as usize), )), - x => unreachable!("Not yet implemented translation for TyKind: {:?}", x), + x => todo!("Not yet implemented translation for TyKind: {:?}", x), } } @@ -1061,7 +1039,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonTyKind::Adt(CharonTypeId::Adt(c_typedeclid), _) => { CharonRvalue::Discriminant(c_place, *c_typedeclid) } - _ => todo!(), + _ => todo!("Not yet implemented:{:?}", c_ty.kind()), } } @@ -1295,6 +1273,15 @@ impl<'a, 'tcx> Context<'a, 'tcx> { ProjectionElem::Downcast(varid) => { current_var = varid.to_index(); } + ProjectionElem::Index(local) => { + let c_operand = + CharonOperand::Copy(CharonPlace::new(CharonVarId::from_usize(*local))); + c_provec.push(CharonProjectionElem::Index { + offset: c_operand, + from_end: false, + ty: current_ty.clone(), + }); + } _ => continue, } diff --git a/tests/expected/llbc/generic_test/expected b/tests/expected/llbc/generic_test/expected new file mode 100644 index 000000000000..8345efd371d4 --- /dev/null +++ b/tests/expected/llbc/generic_test/expected @@ -0,0 +1,52 @@ +enum core::option::Option = +| None() +| Some(0: T) + + +fn test::add_opt(@1: @Adt0, @2: @Adt0) -> @Adt0 +{ + let @0: @Adt0; // return + let x@1: @Adt0; // arg #1 + let y@2: @Adt0; // arg #2 + let u@3: i32; // local + let v@4: i32; // local + let @5: i32; // anonymous local + + match x@1 { + 1 => { + u@3 := copy ((x@1 as variant @1).0) + match y@2 { + 1 => { + v@4 := copy ((y@2 as variant @1).0) + @5 := copy (u@3) + copy (v@4) + @0 := core::option::Option::Some { 0: move (@5) } + drop @5 + }, + 0 => { + @0 := core::option::Option::None { } + }, + } + }, + 0 => { + @0 := core::option::Option::None { } + }, + } + return +} + +fn test::main() +{ + let @0: (); // return + let e@1: @Adt0; // local + let @2: @Adt0; // anonymous local + let @3: @Adt0; // anonymous local + + @2 := core::option::Option::Some { 0: const (1 : i32) } + @3 := core::option::Option::Some { 0: const (2 : i32) } + e@1 := @Fun0(move (@2), move (@3)) + drop @3 + drop @2 + drop e@1 + @0 := () + return +} diff --git a/tests/expected/llbc/generic_test/test.rs b/tests/expected/llbc/generic_test/test.rs new file mode 100644 index 000000000000..b6df7071aded --- /dev/null +++ b/tests/expected/llbc/generic_test/test.rs @@ -0,0 +1,20 @@ +// Copyright Kani Contributors +// SPDX-License-Identifier: Apache-2.0 OR MIT +// kani-flags: -Zlean --print-llbc + +//! This test checks that Kani's LLBC backend handles simple generic args for option + +fn add_opt(x: Option, y: Option) -> Option { + match x { + Some(u) => match y { + Some(v) => Some(u + v), + _ => None, + }, + _ => None, + } +} + +#[kani::proof] +fn main() { + let e = add_opt(Some(1), Some(2)); +} From 137008c02347ad29079d7640f2ba42c6dbc93286 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Thu, 21 Nov 2024 14:13:17 -0800 Subject: [PATCH 20/22] fixed unreachable -> todo --- kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index b546760cf4ee..aa8a430bf8a7 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -1296,7 +1296,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { RegionKind::ReEarlyParam(_) | RegionKind::ReBound(_, _) | RegionKind::RePlaceholder(_) => { - unreachable!("Not yet implemented RegionKind: {:?}", region.kind) + todo! ("Not yet implemented RegionKind: {:?}", region.kind) } } } From df89b51aa4703a33f187e8f545b5618db939df4f Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Thu, 21 Nov 2024 14:14:09 -0800 Subject: [PATCH 21/22] fixed format --- kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index aa8a430bf8a7..ed5f3ee0349a 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -1296,7 +1296,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { RegionKind::ReEarlyParam(_) | RegionKind::ReBound(_, _) | RegionKind::RePlaceholder(_) => { - todo! ("Not yet implemented RegionKind: {:?}", region.kind) + todo!("Not yet implemented RegionKind: {:?}", region.kind) } } } From 2cb0e56b9cca9da7b6d14688031f46e268b83deb Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Thu, 21 Nov 2024 17:01:17 -0800 Subject: [PATCH 22/22] changing some test folders' names --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 27 ++++++++++++++----- .../llbc/{enum_test => enum}/expected | 0 .../expected/llbc/{enum_test => enum}/test.rs | 0 .../llbc/{generic_test => generic}/expected | 0 .../llbc/{generic_test => generic}/test.rs | 0 .../{projection_test => projection}/expected | 0 .../{projection_test => projection}/test.rs | 0 .../llbc/{struct_test => struct}/expected | 0 .../llbc/{struct_test => struct}/test.rs | 0 .../llbc/{tuple_test => tuple}/expected | 0 .../llbc/{tuple_test => tuple}/test.rs | 0 11 files changed, 21 insertions(+), 6 deletions(-) rename tests/expected/llbc/{enum_test => enum}/expected (100%) rename tests/expected/llbc/{enum_test => enum}/test.rs (100%) rename tests/expected/llbc/{generic_test => generic}/expected (100%) rename tests/expected/llbc/{generic_test => generic}/test.rs (100%) rename tests/expected/llbc/{projection_test => projection}/expected (100%) rename tests/expected/llbc/{projection_test => projection}/test.rs (100%) rename tests/expected/llbc/{struct_test => struct}/expected (100%) rename tests/expected/llbc/{struct_test => struct}/test.rs (100%) rename tests/expected/llbc/{tuple_test => tuple}/expected (100%) rename tests/expected/llbc/{tuple_test => tuple}/test.rs (100%) diff --git a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs index ed5f3ee0349a..62a772fc6873 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs @@ -861,7 +861,23 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let c_generic_args = self.translate_generic_args(genarg); CharonTy::new(CharonTyKind::Adt(CharonTypeId::Adt(c_typedeclid), c_generic_args)) } - _ => todo!(), + RigidTy::Slice(ty) => { + let c_ty = self.translate_ty(ty); + let mut c_types = CharonVector::new(); + c_types.push(c_ty); + CharonTy::new(CharonTyKind::Adt( + CharonTypeId::Builtin(CharonBuiltinTy::Slice), + CharonGenericArgs::new_from_types(c_types), + )) + } + RigidTy::RawPtr(ty, mutability) => { + let c_ty = self.translate_ty(ty); + CharonTy::new(CharonTyKind::RawPtr(c_ty, match mutability { + Mutability::Mut => CharonRefKind::Mut, + Mutability::Not => CharonRefKind::Shared, + })) + } + _ => todo!("Not yet implemented RigidTy: {:?}", rigid_ty), } } @@ -1293,9 +1309,8 @@ impl<'a, 'tcx> Context<'a, 'tcx> { match region.kind { RegionKind::ReStatic => CharonRegion::Static, RegionKind::ReErased => CharonRegion::Erased, - RegionKind::ReEarlyParam(_) - | RegionKind::ReBound(_, _) - | RegionKind::RePlaceholder(_) => { + RegionKind::ReEarlyParam(_) => CharonRegion::Unknown, + RegionKind::ReBound(_, _) | RegionKind::RePlaceholder(_) => { todo!("Not yet implemented RegionKind: {:?}", region.kind) } } @@ -1310,7 +1325,7 @@ fn translate_int_ty(int_ty: IntTy) -> CharonIntegerTy { IntTy::I64 => CharonIntegerTy::I64, IntTy::I128 => CharonIntegerTy::I128, // TODO: assumes 64-bit platform - IntTy::Isize => CharonIntegerTy::I64, + IntTy::Isize => CharonIntegerTy::Isize, } } @@ -1322,7 +1337,7 @@ fn translate_uint_ty(uint_ty: UintTy) -> CharonIntegerTy { UintTy::U64 => CharonIntegerTy::U64, UintTy::U128 => CharonIntegerTy::U128, // TODO: assumes 64-bit platform - UintTy::Usize => CharonIntegerTy::U64, + UintTy::Usize => CharonIntegerTy::Usize, } } diff --git a/tests/expected/llbc/enum_test/expected b/tests/expected/llbc/enum/expected similarity index 100% rename from tests/expected/llbc/enum_test/expected rename to tests/expected/llbc/enum/expected diff --git a/tests/expected/llbc/enum_test/test.rs b/tests/expected/llbc/enum/test.rs similarity index 100% rename from tests/expected/llbc/enum_test/test.rs rename to tests/expected/llbc/enum/test.rs diff --git a/tests/expected/llbc/generic_test/expected b/tests/expected/llbc/generic/expected similarity index 100% rename from tests/expected/llbc/generic_test/expected rename to tests/expected/llbc/generic/expected diff --git a/tests/expected/llbc/generic_test/test.rs b/tests/expected/llbc/generic/test.rs similarity index 100% rename from tests/expected/llbc/generic_test/test.rs rename to tests/expected/llbc/generic/test.rs diff --git a/tests/expected/llbc/projection_test/expected b/tests/expected/llbc/projection/expected similarity index 100% rename from tests/expected/llbc/projection_test/expected rename to tests/expected/llbc/projection/expected diff --git a/tests/expected/llbc/projection_test/test.rs b/tests/expected/llbc/projection/test.rs similarity index 100% rename from tests/expected/llbc/projection_test/test.rs rename to tests/expected/llbc/projection/test.rs diff --git a/tests/expected/llbc/struct_test/expected b/tests/expected/llbc/struct/expected similarity index 100% rename from tests/expected/llbc/struct_test/expected rename to tests/expected/llbc/struct/expected diff --git a/tests/expected/llbc/struct_test/test.rs b/tests/expected/llbc/struct/test.rs similarity index 100% rename from tests/expected/llbc/struct_test/test.rs rename to tests/expected/llbc/struct/test.rs diff --git a/tests/expected/llbc/tuple_test/expected b/tests/expected/llbc/tuple/expected similarity index 100% rename from tests/expected/llbc/tuple_test/expected rename to tests/expected/llbc/tuple/expected diff --git a/tests/expected/llbc/tuple_test/test.rs b/tests/expected/llbc/tuple/test.rs similarity index 100% rename from tests/expected/llbc/tuple_test/test.rs rename to tests/expected/llbc/tuple/test.rs