From e7f4152c33e27357f1b2d93d053284330cfeba88 Mon Sep 17 00:00:00 2001 From: NGUYEN Date: Fri, 15 Nov 2024 08:36:11 -0800 Subject: [PATCH 01/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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 From 24a30a3c1378401197e96834084558744d624451 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 25 Nov 2024 09:38:24 -0800 Subject: [PATCH 23/51] Some support for generic --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 176 +++++++++++++++--- 1 file changed, 150 insertions(+), 26 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 62a772fc6873..b50995bc0324 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 @@ -34,6 +34,7 @@ use charon_lib::ast::{ 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, + BuiltinFun as CharonBuiltinFun, BuiltinFunId as CharonBuiltinFunId, }; use charon_lib::errors::{Error as CharonError, ErrorCtx as CharonErrorCtx}; use charon_lib::ids::Vector as CharonVector; @@ -57,9 +58,9 @@ use stable_mir::mir::{ }; use stable_mir::ty::{ AdtDef, AdtKind, Allocation, ConstantKind, GenericArgKind, GenericArgs, IndexedVal, IntTy, - MirConst, Region, RegionKind, RigidTy, Span, Ty, TyConst, TyConstKind, TyKind, UintTy, + MirConst, Region, RegionKind, RigidTy, Span, Ty, TyConst, TyConstKind, TyKind, UintTy, FnDef, }; -use stable_mir::{CrateDef, DefId}; +use stable_mir::{CrateDef, CrateDefType, DefId}; use std::path::PathBuf; use tracing::{debug, trace}; @@ -113,7 +114,8 @@ impl<'a, 'tcx> Context<'a, 'tcx> { pub fn translate(&mut self) -> Result<(), ()> { // TODO: might want to populate `errors.dep_sources` to help with // debugging - + let instance_def = self.instance.def; + let is_builtin = self.is_builtin_fun(instance_def); let fid = self.register_fun_decl_id(self.instance.def.def_id()); let item_meta = match self.translate_item_meta_from_rid(self.instance) { @@ -122,26 +124,35 @@ impl<'a, 'tcx> Context<'a, 'tcx> { return Err(()); } }; - + let funcname = item_meta.name.clone(); + println!("Func name: {:?}", funcname); let signature = self.translate_function_signature(); - let body = match self.translate_function_body() { - Ok(body) => body, - Err(_) => { - return Err(()); - } + let body = if is_builtin { + Err(CharonOpaque) + } else { + let bodyid = match self.translate_function_body() { + Ok(body) => body, + Err(_) => { + return Err(()); + } + }; + Ok(bodyid) }; - let fun_decl = CharonFunDecl { def_id: fid, item_meta, signature, kind: CharonItemKind::Regular, - body: Ok(body), + body, }; - - self.translated.fun_decls.set_slot(fid, fun_decl); - + match self.translated.fun_decls.get(fid) { + None => self.translated.fun_decls.set_slot(fid, fun_decl), + Some(_) => {}, + }; + + println!("Complete Func name: {:?}", funcname); Ok(()) + } /// Get or create a `CharonFunDeclId` for the given function @@ -191,6 +202,75 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonScalarValue::from_bits(int_ty, discr_val) } + fn generic_params_from_fndef(&mut self, fndef: FnDef) -> CharonGenericParams { + let genvec = match fndef.ty().kind(){ + TyKind::RigidTy(RigidTy::FnDef(_, genarg)) => genarg.0, + _ => panic!("generic_params_from_fndef: not an FnDef"), + }; + 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 def_id_internal = rustc_internal::internal(self.tcx, fndef.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 { + 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 generic_params_from_adtdef(&mut self, adtdef: AdtDef) -> CharonGenericParams { let genvec = match adtdef.ty().kind() { TyKind::RigidTy(RigidTy::Adt(_, genarg)) => genarg.0, @@ -404,6 +484,19 @@ impl<'a, 'tcx> Context<'a, 'tcx> { Ok(CharonItemMeta { span, source_text, attr_info, name, is_local, opacity }) } + fn recognize_primitive_fun(&mut self, _: InstanceDef ) -> Option { + None + } + + fn is_builtin_fun(&mut self, func_def: InstanceDef ) -> bool { + let name = self.def_to_name(func_def).unwrap(); + let crate_name = match name.name.get(0).unwrap() { + CharonPathElem::Ident(cn,_) => cn, + _ => panic!("Imple name"), + }; + crate_name.starts_with("std") || crate_name.starts_with("core") + } + /// 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 @@ -665,10 +758,21 @@ impl<'a, 'tcx> Context<'a, 'tcx> { fn translate_function_signature(&mut self) -> CharonFunSig { let instance = self.instance; + let fndef = match instance.ty().kind() { + TyKind::RigidTy(RigidTy::FnDef(fndef,_ )) => fndef, + _ => panic!("Expected a function type"), + }; + let value = fndef.fn_sig().value; + let inputs = value.inputs().to_vec(); + let c_inputs: Vec = inputs.iter().map(|ty| self.translate_ty(*ty)).collect(); + let c_output = self.translate_ty(value.output()); + + let fn_abi = instance.fn_abi().unwrap(); let requires_caller_location = self.requires_caller_location(instance); let num_args = fn_abi.args.len(); - let args = fn_abi + + let args : Vec = fn_abi .args .iter() .enumerate() @@ -689,18 +793,21 @@ impl<'a, 'tcx> Context<'a, 'tcx> { }) .collect(); + debug!(?args, ?fn_abi, "function_type"); let ret_type = self.translate_ty(fn_abi.ret.ty); - + println!("cinput len {:?} ", c_inputs.len()); + println!("args len {:?}", args.clone().len()); + let c_genparam = self.generic_params_from_fndef(fndef); // TODO: populate the rest of the information (`is_unsafe`, `is_closure`, etc.) CharonFunSig { is_unsafe: false, is_closure: false, closure_info: None, - generics: CharonGenericParams::default(), + generics: c_genparam, parent_params_info: None, inputs: args, - output: ret_type, + output: c_output, } } @@ -959,16 +1066,33 @@ impl<'a, 'tcx> Context<'a, 'tcx> { TyKind::RigidTy(RigidTy::FnDef(def, args)) => { let instance = Instance::resolve(def, &args).unwrap(); let def_id = instance.def.def_id(); - let fid = self.register_fun_decl_id(def_id); + let builtin_fun = self.recognize_primitive_fun(instance.def); + let func = if let Some(builtin_fun) = builtin_fun { + println!("Found builtin func {:?}", instance.def.name()); + let aid = builtin_fun.to_ullbc_builtin_fun(); + match aid { + CharonBuiltinFunId::BoxNew => { + // Nothing to do + } + CharonBuiltinFunId::Index { .. } + | CharonBuiltinFunId::ArrayToSliceShared + | CharonBuiltinFunId::ArrayToSliceMut + | CharonBuiltinFunId::ArrayRepeat => { + // Those cases are introduced later, in micro-passes, by desugaring + // projections (for ArrayIndex and ArrayIndexMut for instnace) and= + // operations (for ArrayToSlice for instance) to function calls. + unreachable!() + } + }; + CharonFunIdOrTraitMethodRef::Fun(CharonFunId::Builtin(aid)) + } else { + let fid = self.register_fun_decl_id(def_id); + CharonFunIdOrTraitMethodRef::Fun(CharonFunId::Regular(fid)) + }; CharonFnPtr { - func: CharonFunIdOrTraitMethodRef::Fun(CharonFunId::Regular(fid)), + func: func, // TODO: populate generics? - generics: CharonGenericArgs { - regions: CharonVector::new(), - types: CharonVector::new(), - const_generics: CharonVector::new(), - trait_refs: CharonVector::new(), - }, + generics: self.translate_generic_args(args), } } TyKind::RigidTy(RigidTy::FnPtr(..)) => todo!(), From 6f5347c5e9a11f97e10798bf0159624c2290e5c8 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 25 Nov 2024 15:51:27 -0800 Subject: [PATCH 24/51] translating traits --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 267 +++++++++++++++++- 1 file changed, 256 insertions(+), 11 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 b50995bc0324..eccce13916d1 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 @@ -35,6 +35,8 @@ use charon_lib::ast::{ TypeVar as CharonTypeVar, TypeVarId as CharonTypeVarId, UnOp as CharonUnOp, Var as CharonVar, VarId as CharonVarId, Variant as CharonVariant, VariantId as CharonVariantId, BuiltinFun as CharonBuiltinFun, BuiltinFunId as CharonBuiltinFunId, + TraitClauseId as CharonTraitClauseId, TraitClause as CharonTraitClause, TraitDeclId as CharonTraitDeclId, + TraitDecl as CharonTraitDecl, TraitRef as CharonTraitRef, }; use charon_lib::errors::{Error as CharonError, ErrorCtx as CharonErrorCtx}; use charon_lib::ids::Vector as CharonVector; @@ -44,6 +46,7 @@ use charon_lib::ullbc_ast::{ RawTerminator as CharonRawTerminator, Statement as CharonStatement, SwitchTargets as CharonSwitchTargets, Terminator as CharonTerminator, }; +use std::collections::HashMap; use charon_lib::{error_assert, error_or_panic}; use core::panic; use rustc_data_structures::fx::FxHashMap; @@ -58,7 +61,8 @@ use stable_mir::mir::{ }; use stable_mir::ty::{ AdtDef, AdtKind, Allocation, ConstantKind, GenericArgKind, GenericArgs, IndexedVal, IntTy, - MirConst, Region, RegionKind, RigidTy, Span, Ty, TyConst, TyConstKind, TyKind, UintTy, FnDef, + MirConst, Region, RegionKind, RigidTy, Span, Ty, TyConst, TyConstKind, TyKind, UintTy, FnDef, GenericPredicates, + TraitDef, TraitDecl, }; use stable_mir::{CrateDef, CrateDefType, DefId}; use std::path::PathBuf; @@ -110,6 +114,57 @@ impl<'a, 'tcx> Context<'a, 'tcx> { self.errors.continue_on_failure() } + fn translate_traitdecl(&mut self, trait_def: TraitDef) -> DefId { + let trait_def_id = trait_def.def_id(); + let trait_decl_id = self.register_trait_decl_id(trait_def_id); + match self.translated.trait_decls.get(trait_decl_id) { + None => { + let trait_decl = TraitDef::declaration(&trait_def); + let mut consts = Vec::new(); + let mut const_defaults = HashMap::new(); + let mut types = Vec::new(); + let mut type_clauses = Vec::new(); + let mut type_defaults = HashMap::new(); + let mut required_methods = Vec::new(); + let mut provided_methods = Vec::new(); + let mut parent_clauses = CharonVector::new(); + let c_traitdecl = CharonTraitDecl{ + def_id: trait_decl_id, + item_meta: self.translate_item_meta_from_defid(trait_def_id), + generics, + parent_clauses, + type_clauses, + consts, + const_defaults, + types, + type_defaults, + required_methods, + provided_methods, + }; + self.translated.trait_decls.set_slot(trait_decl_id, c_traitdecl); + trait_def_id + }, + Some(_) => trait_def_id + } + + } + + fn get_trait_refs(&mut self, defid: DefId) { + let inter_defid = rustc_internal::internal(self.tcx,defid); + let predicates = self.tcx().predicates_of(inter_defid).predicates.to_vec(); + let mut c_trait_refs: CharonVector = CharonVector::new(); + for (clause, span) in predicates.iter() { + let trait_id_internal = clause.as_trait_clause().unwrap(); + let trait_def = rustc_internal::stable(trait_id_internal).value.trait_ref.def_id; + let c_def_id = self.register_trait_decl_id(trait_def.def_id()); + let trait_decl = TraitDef::declaration(&trait_def); + + + + } + println!("Predicates: {:?}", predicates); + } + /// Perform the translation pub fn translate(&mut self) -> Result<(), ()> { // TODO: might want to populate `errors.dep_sources` to help with @@ -149,7 +204,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { None => self.translated.fun_decls.set_slot(fid, fun_decl), Some(_) => {}, }; - + println!("Complete Func name: {:?}", funcname); Ok(()) @@ -188,6 +243,22 @@ impl<'a, 'tcx> Context<'a, 'tcx> { tid.try_into().unwrap() } + fn register_trait_decl_id(&mut self, def_id: DefId) -> CharonTraitDeclId { + debug!("register_trait_decl_id: {:?}", def_id); + let tid = match self.id_map.get(&def_id) { + Some(tid) => *tid, + None => { + debug!("***Not found!"); + let tid = CharonAnyTransId::TraitDecl(self.translated.trait_decls.reserve_slot()); + self.id_map.insert(def_id, tid); + self.translated.all_ids.insert(tid); + tid + } + }; + debug!("register_trait_decl_id: {:?}", self.id_map); + 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 get_type_decl_id(&self, def_id: DefId) -> CharonTypeDeclId { debug!("register_type_decl_id: {:?}", def_id); @@ -202,6 +273,72 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonScalarValue::from_bits(int_ty, discr_val) } + fn generic_params_from_traitdecl(&mut self, traitdecl: TraitDecl) -> CharonGenericParams { + let genvec = traitdecl.generics_of().par + 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 def_id_internal = rustc_internal::internal(self.tcx, fndef.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_fndef: 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_fndef: 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 generic_params_from_fndef(&mut self, fndef: FnDef) -> CharonGenericParams { let genvec = match fndef.ty().kind(){ TyKind::RigidTy(RigidTy::FnDef(_, genarg)) => genarg.0, @@ -247,7 +384,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { 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"), + _ => panic!("generic_params_from_fndef: not a literal type"), }; let c_constgeneric = CharonConstGenericVar { index: CharonConstGenericVarId::from_usize(paramtc.index as usize), @@ -256,7 +393,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { }; c_const_generics.push(c_constgeneric); } - _ => panic!("generic_params_from_adtdef: not a param const"), + _ => panic!("generic_params_from_fndef: not a param const"), }, } } @@ -402,6 +539,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { item_meta, }; self.translated.type_decls.set_slot(c_typedeclid, typedecl.clone()); + self.get_generic_predicate(def_id); typedecl } AdtKind::Struct => { @@ -464,6 +602,30 @@ impl<'a, 'tcx> Context<'a, 'tcx> { Ok(CharonItemMeta { span, source_text, attr_info, name, is_local, opacity }) } + fn translate_item_meta_from_defid( + &mut self, + defid: DefId, + ) -> CharonItemMeta { + let def_id = rustc_internal::internal(self.tcx(), defid); + let span = self.translate_span(rustc_internal::stable(self.tcx.def_span(def_id))); + let name = self.defid_to_name(defid); + // 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 + // 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; + + 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)?; @@ -497,6 +659,90 @@ impl<'a, 'tcx> Context<'a, 'tcx> { crate_name.starts_with("std") || crate_name.starts_with("core") } + + fn defid_to_name(&mut self, defid: DefId) -> CharonName { + let tcx = self.tcx(); + let def_id = rustc_internal::internal(self.tcx(), defid); + let span: CharonSpan = self.translate_span(rustc_internal::stable(tcx.def_span(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() + }; + + 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 => {} //will check + 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); + CharonName { name } + } + /// 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 @@ -767,11 +1013,10 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let c_inputs: Vec = inputs.iter().map(|ty| self.translate_ty(*ty)).collect(); let c_output = self.translate_ty(value.output()); - +/* let fn_abi = instance.fn_abi().unwrap(); let requires_caller_location = self.requires_caller_location(instance); let num_args = fn_abi.args.len(); - let args : Vec = fn_abi .args .iter() @@ -792,12 +1037,12 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } }) .collect(); - +*/ - debug!(?args, ?fn_abi, "function_type"); - let ret_type = self.translate_ty(fn_abi.ret.ty); + //debug!(?args, ?fn_abi, "function_type"); + //let ret_type = self.translate_ty(fn_abi.ret.ty); println!("cinput len {:?} ", c_inputs.len()); - println!("args len {:?}", args.clone().len()); + //println!("args len {:?}", args.clone().len()); let c_genparam = self.generic_params_from_fndef(fndef); // TODO: populate the rest of the information (`is_unsafe`, `is_closure`, etc.) CharonFunSig { @@ -806,7 +1051,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { closure_info: None, generics: c_genparam, parent_params_info: None, - inputs: args, + inputs: c_inputs, output: c_output, } } From 30026ccfffd40432ec5f6f962de4add10699db22 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Tue, 26 Nov 2024 14:28:05 -0800 Subject: [PATCH 25/51] added trait clauses --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 173 ++++++++++++------ tests/perf/s2n-quic | 2 +- 2 files changed, 117 insertions(+), 58 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 eccce13916d1..a7e13949e8e4 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 @@ -36,7 +36,8 @@ use charon_lib::ast::{ VarId as CharonVarId, Variant as CharonVariant, VariantId as CharonVariantId, BuiltinFun as CharonBuiltinFun, BuiltinFunId as CharonBuiltinFunId, TraitClauseId as CharonTraitClauseId, TraitClause as CharonTraitClause, TraitDeclId as CharonTraitDeclId, - TraitDecl as CharonTraitDecl, TraitRef as CharonTraitRef, + TraitDecl as CharonTraitDecl, TraitRef as CharonTraitRef, PolyTraitDeclRef as CharonPolyTraitDeclRef, + TraitDeclRef as CharonTraitDeclRef, TraitRefKind as CharonTraitRefKind, PredicateOrigin as CharonPredicateOrigin, }; use charon_lib::errors::{Error as CharonError, ErrorCtx as CharonErrorCtx}; use charon_lib::ids::Vector as CharonVector; @@ -62,7 +63,7 @@ use stable_mir::mir::{ use stable_mir::ty::{ AdtDef, AdtKind, Allocation, ConstantKind, GenericArgKind, GenericArgs, IndexedVal, IntTy, MirConst, Region, RegionKind, RigidTy, Span, Ty, TyConst, TyConstKind, TyKind, UintTy, FnDef, GenericPredicates, - TraitDef, TraitDecl, + TraitDef, TraitDecl, GenericParamDefKind }; use stable_mir::{CrateDef, CrateDefType, DefId}; use std::path::PathBuf; @@ -114,7 +115,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { self.errors.continue_on_failure() } - fn translate_traitdecl(&mut self, trait_def: TraitDef) -> DefId { + fn translate_traitdecl(&mut self, trait_def: TraitDef) -> CharonTraitDeclId { let trait_def_id = trait_def.def_id(); let trait_decl_id = self.register_trait_decl_id(trait_def_id); match self.translated.trait_decls.get(trait_decl_id) { @@ -131,7 +132,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let c_traitdecl = CharonTraitDecl{ def_id: trait_decl_id, item_meta: self.translate_item_meta_from_defid(trait_def_id), - generics, + generics: self.generic_params_from_traitdecl(trait_decl), parent_clauses, type_clauses, consts, @@ -142,27 +143,65 @@ impl<'a, 'tcx> Context<'a, 'tcx> { provided_methods, }; self.translated.trait_decls.set_slot(trait_decl_id, c_traitdecl); - trait_def_id + trait_decl_id }, - Some(_) => trait_def_id + Some(_) => trait_decl_id } } - fn get_trait_refs(&mut self, defid: DefId) { + fn get_traitrefs_from_defid(&mut self, defid: DefId) -> CharonVector{ let inter_defid = rustc_internal::internal(self.tcx,defid); let predicates = self.tcx().predicates_of(inter_defid).predicates.to_vec(); let mut c_trait_refs: CharonVector = CharonVector::new(); - for (clause, span) in predicates.iter() { + for (i,(clause, _)) in predicates.iter().enumerate() { let trait_id_internal = clause.as_trait_clause().unwrap(); - let trait_def = rustc_internal::stable(trait_id_internal).value.trait_ref.def_id; - let c_def_id = self.register_trait_decl_id(trait_def.def_id()); - let trait_decl = TraitDef::declaration(&trait_def); + let trait_ref = rustc_internal::stable(trait_id_internal).value.trait_ref; + let trait_def = trait_ref.def_id; + let c_traitdecl_id = self.translate_traitdecl(trait_def); + let c_genarg = self.translate_generic_args_withouttrait(trait_ref.args().clone()); + let c_polytrait = CharonPolyTraitDeclRef{ + regions: CharonVector::new(), + skip_binder : CharonTraitDeclRef {trait_id: c_traitdecl_id, generics: c_genarg}, + }; + let c_traitref = CharonTraitRef{ + kind: CharonTraitRefKind::Clause(CharonTraitClauseId::from_usize(i)), + trait_decl_ref: c_polytrait, + }; + c_trait_refs.push(c_traitref); + } + //println!("Predicates: {:?}", predicates); + c_trait_refs + } + + fn get_traitclauses_from_defid(&mut self, defid: DefId) -> CharonVector{ + let inter_defid = rustc_internal::internal(self.tcx,defid); + let predicates = self.tcx().predicates_of(inter_defid).predicates.to_vec(); + let mut c_trait_clauses: CharonVector = CharonVector::new(); + for (i,(clause, span)) in predicates.iter().enumerate() { + let trait_id_internal = clause.as_trait_clause().unwrap(); + let trait_ref = rustc_internal::stable(trait_id_internal).value.trait_ref; + let trait_def = trait_ref.def_id; + let c_traitdecl_id = self.translate_traitdecl(trait_def); + let c_genarg = self.translate_generic_args_withouttrait(trait_ref.args().clone()); + println!("Genargs Type: {:?}", c_genarg.types); + let c_polytrait = CharonPolyTraitDeclRef{ + regions: CharonVector::new(), + skip_binder : CharonTraitDeclRef {trait_id: c_traitdecl_id, generics: c_genarg}, + }; + let c_traitclause = CharonTraitClause{ + clause_id: CharonTraitClauseId::from_usize(i), + span: Some(self.translate_span(rustc_internal::stable(span))), + trait_: c_polytrait, + origin: CharonPredicateOrigin::WhereClauseOnType + }; + c_trait_clauses.push(c_traitclause); - } - println!("Predicates: {:?}", predicates); + } + + c_trait_clauses } /// Perform the translation @@ -274,41 +313,30 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } fn generic_params_from_traitdecl(&mut self, traitdecl: TraitDecl) -> CharonGenericParams { - let genvec = traitdecl.generics_of().par + let genvec = traitdecl.generics_of().params; 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), - }; + for gendef in genvec.iter() { + let genkind = gendef.kind.clone(); + let index = gendef.index as usize; + let name = gendef.name.clone(); + match genkind { + GenericParamDefKind::Lifetime => { + let c_region = CharonRegionVar {index: CharonRegionId::from_usize(index), name: Some(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"), + }, + GenericParamDefKind::Type{has_default : _, synthetic : _ } => { + let c_region = CharonTypeVar {index: CharonTypeVarId::from_usize(index) ,name}; + c_types.push(c_region); }, - GenericArgKind::Const(tc) => match tc.kind() { - TyConstKind::Param(paramtc) => { - let def_id_internal = rustc_internal::internal(self.tcx, fndef.def_id()); + GenericParamDefKind::Const{has_default: _} => { + let def_id_internal = rustc_internal::internal(self.tcx, gendef.def_id.0); 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), + index : index as u32, + name: rustc_span::Symbol::intern(&name.clone()), }; let ty_internal = pc_internal.find_ty_from_env(paramenv); let ty_stable = rustc_internal::stable(ty_internal); @@ -318,13 +346,11 @@ impl<'a, 'tcx> Context<'a, 'tcx> { _ => panic!("generic_params_from_fndef: not a literal type"), }; let c_constgeneric = CharonConstGenericVar { - index: CharonConstGenericVarId::from_usize(paramtc.index as usize), - name: paramtc.name.clone(), + index: CharonConstGenericVarId::from_usize(index), + name, ty: lit_ty, }; c_const_generics.push(c_constgeneric); - } - _ => panic!("generic_params_from_fndef: not a param const"), }, } } @@ -397,11 +423,12 @@ impl<'a, 'tcx> Context<'a, 'tcx> { }, } } + let trait_clauses = self.get_traitclauses_from_defid(fndef.def_id()); CharonGenericParams { regions: c_regions, types: c_types, const_generics: c_const_generics, - trait_clauses: CharonVector::new(), + trait_clauses, regions_outlive: Vec::new(), types_outlive: Vec::new(), trait_type_constraints: Vec::new(), @@ -466,11 +493,12 @@ impl<'a, 'tcx> Context<'a, 'tcx> { }, } } + let trait_clauses = self.get_traitclauses_from_defid(adtdef.def_id()); CharonGenericParams { regions: c_regions, types: c_types, const_generics: c_const_generics, - trait_clauses: CharonVector::new(), + trait_clauses, regions_outlive: Vec::new(), types_outlive: Vec::new(), trait_type_constraints: Vec::new(), @@ -539,7 +567,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { item_meta, }; self.translated.type_decls.set_slot(c_typedeclid, typedecl.clone()); - self.get_generic_predicate(def_id); typedecl } AdtKind::Struct => { @@ -608,7 +635,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { ) -> CharonItemMeta { let def_id = rustc_internal::internal(self.tcx(), defid); let span = self.translate_span(rustc_internal::stable(self.tcx.def_span(def_id))); - let name = self.defid_to_name(defid); + let name = self.defid_to_name(defid).unwrap(); // TODO: populate the source text let source_text = None; // TODO: populate the attribute info @@ -660,7 +687,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } - fn defid_to_name(&mut self, defid: DefId) -> CharonName { + fn defid_to_name(&mut self, defid: DefId) -> Result { let tcx = self.tcx(); let def_id = rustc_internal::internal(self.tcx(), defid); let span: CharonSpan = self.translate_span(rustc_internal::stable(tcx.def_span(def_id))); @@ -740,7 +767,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } trace!("{:?}", name); - CharonName { name } + Ok(CharonName { name }) } /// Retrieve an item name from a [DefId]. @@ -1041,7 +1068,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { //debug!(?args, ?fn_abi, "function_type"); //let ret_type = self.translate_ty(fn_abi.ret.ty); - println!("cinput len {:?} ", c_inputs.len()); + //println!("cinput len {:?} ", c_inputs.len()); //println!("args len {:?}", args.clone().len()); let c_genparam = self.generic_params_from_fndef(fndef); // TODO: populate the rest of the information (`is_unsafe`, `is_closure`, etc.) @@ -1081,7 +1108,39 @@ impl<'a, 'tcx> Context<'a, 'tcx> { instance_internal.def.requires_caller_location(self.tcx()) } - fn translate_generic_args(&mut self, ga: GenericArgs) -> CharonGenericArgs { + fn translate_generic_args(&mut self, ga: GenericArgs, defid: DefId) -> 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(); + 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); + } + } + } + let trait_refs = self.get_traitrefs_from_defid(defid); + CharonGenericArgs { + regions: c_regions, + types: c_types, + const_generics: c_const_generics, + trait_refs, + } + } + + fn translate_generic_args_withouttrait(&mut self, ga: GenericArgs) -> CharonGenericArgs { let genvec = ga.0; let mut c_regions: CharonVector = CharonVector::new(); let mut c_types: CharonVector = CharonVector::new(); @@ -1210,7 +1269,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { if self.translated.type_decls.get(c_typedeclid).is_none() { self.translate_adtdef(adt_def); } - let c_generic_args = self.translate_generic_args(genarg); + let c_generic_args = self.translate_generic_args(genarg, adt_def.def_id()); CharonTy::new(CharonTyKind::Adt(CharonTypeId::Adt(c_typedeclid), c_generic_args)) } RigidTy::Slice(ty) => { @@ -1335,9 +1394,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonFunIdOrTraitMethodRef::Fun(CharonFunId::Regular(fid)) }; CharonFnPtr { - func: func, + func, // TODO: populate generics? - generics: self.translate_generic_args(args), + generics: self.translate_generic_args(args, def.def_id()), } } TyKind::RigidTy(RigidTy::FnPtr(..)) => todo!(), @@ -1443,7 +1502,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 = self.translate_generic_args(genarg); + let c_generic_args = self.translate_generic_args(genarg, adt_def.def_id()); let c_agg_kind = CharonAggregateKind::Adt( c_type_id, c_variant_id, @@ -1458,7 +1517,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 = self.translate_generic_args(genarg); + let c_generic_args = self.translate_generic_args(genarg, adt_def.def_id()); let c_agg_kind = CharonAggregateKind::Adt( c_type_id, c_variant_id, diff --git a/tests/perf/s2n-quic b/tests/perf/s2n-quic index c84ba19d2688..4c3ba69e3d71 160000 --- a/tests/perf/s2n-quic +++ b/tests/perf/s2n-quic @@ -1 +1 @@ -Subproject commit c84ba19d2688b7026a23027553f684ad3b10552f +Subproject commit 4c3ba69e3d71d0a2d7aaf58a4be3dd3c6bceb96b From 11f5f10c48e7eda0cfd9fd19a24a0ca5e41af12a Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Tue, 26 Nov 2024 16:46:50 -0800 Subject: [PATCH 26/51] more on trait --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 34 +++++++++++++++++-- tests/perf/s2n-quic | 2 +- 2 files changed, 33 insertions(+), 3 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 a7e13949e8e4..1dbbd632dfc9 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 @@ -160,6 +160,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let trait_def = trait_ref.def_id; let c_traitdecl_id = self.translate_traitdecl(trait_def); let c_genarg = self.translate_generic_args_withouttrait(trait_ref.args().clone()); + //println!("Genargs Type: {:?}", c_genarg.types); let c_polytrait = CharonPolyTraitDeclRef{ regions: CharonVector::new(), skip_binder : CharonTraitDeclRef {trait_id: c_traitdecl_id, generics: c_genarg}, @@ -185,7 +186,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let trait_def = trait_ref.def_id; let c_traitdecl_id = self.translate_traitdecl(trait_def); let c_genarg = self.translate_generic_args_withouttrait(trait_ref.args().clone()); - println!("Genargs Type: {:?}", c_genarg.types); + //println!("Genargs Type: {:?}", c_genarg.types); let c_polytrait = CharonPolyTraitDeclRef{ regions: CharonVector::new(), skip_binder : CharonTraitDeclRef {trait_id: c_traitdecl_id, generics: c_genarg}, @@ -1131,7 +1132,33 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } } - let trait_refs = self.get_traitrefs_from_defid(defid); + let gen_trait_refs = self.get_traitrefs_from_defid(defid); + let mut trait_refs; + for (i, trait_ref) in gen_trait_refs.iter().enumerate() { + let traitgenarg = trait_ref.trait_decl_ref.skip_binder.generics.clone(); + let mut t_regions: CharonVector = CharonVector::new(); + let mut t_types: CharonVector = CharonVector::new(); + let mut t_const_generics: CharonVector = CharonVector::new(); + for tyvar in traitgenarg.types.iter(){ + match tyvar.kind() { + CharonTyKind::TypeVar(tyvarid) => { + let subs_ty = c_types.get(*tyvarid).unwrap().clone(); + t_types.push(subs_ty); + } + _ => todo!("TyKind of gen must be TyVar: {:?}", tyvar.kind()), + } + } + for region in traitgenarg.regions.iter(){ + match region.kind() { + CharonRegionKind::RegionVar(regionid) => { + let subs_region = c_regions.get(*regionid).unwrap().clone(); + t_regions.push(subs_region); + } + _ => todo!("RegionKind of gen must be RegionVar: {:?}", region.kind()), + } + } + + } CharonGenericArgs { regions: c_regions, types: c_types, @@ -1270,6 +1297,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { self.translate_adtdef(adt_def); } let c_generic_args = self.translate_generic_args(genarg, adt_def.def_id()); + //println!("Generic arg type {:?}", c_generic_args.types); + //println!("Generic param type {:?}", self.generic_params_from_adtdef(adt_def).types); + //println!("Generic trait type {:?}", c_generic_args.trait_refs); CharonTy::new(CharonTyKind::Adt(CharonTypeId::Adt(c_typedeclid), c_generic_args)) } RigidTy::Slice(ty) => { diff --git a/tests/perf/s2n-quic b/tests/perf/s2n-quic index 4c3ba69e3d71..c84ba19d2688 160000 --- a/tests/perf/s2n-quic +++ b/tests/perf/s2n-quic @@ -1 +1 @@ -Subproject commit 4c3ba69e3d71d0a2d7aaf58a4be3dd3c6bceb96b +Subproject commit c84ba19d2688b7026a23027553f684ad3b10552f From 28b11e18d65294f9208d295911034406ae78de8e Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Wed, 27 Nov 2024 09:23:37 -0800 Subject: [PATCH 27/51] save --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 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 1dbbd632dfc9..243d452350a5 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 @@ -156,7 +156,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let mut c_trait_refs: CharonVector = CharonVector::new(); for (i,(clause, _)) in predicates.iter().enumerate() { let trait_id_internal = clause.as_trait_clause().unwrap(); - let trait_ref = rustc_internal::stable(trait_id_internal).value.trait_ref; + let trait_binder = rustc_internal::stable(trait_id_internal); + let trait_param = trait_binder.bound_vars; + let trait_ref = trait_binder.value.trait_ref; let trait_def = trait_ref.def_id; let c_traitdecl_id = self.translate_traitdecl(trait_def); let c_genarg = self.translate_generic_args_withouttrait(trait_ref.args().clone()); @@ -1133,8 +1135,8 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } let gen_trait_refs = self.get_traitrefs_from_defid(defid); - let mut trait_refs; - for (i, trait_ref) in gen_trait_refs.iter().enumerate() { + let mut trait_refs: CharonVector = CharonVector::new(); + for trait_ref in gen_trait_refs.iter() { let traitgenarg = trait_ref.trait_decl_ref.skip_binder.generics.clone(); let mut t_regions: CharonVector = CharonVector::new(); let mut t_types: CharonVector = CharonVector::new(); @@ -1148,17 +1150,24 @@ impl<'a, 'tcx> Context<'a, 'tcx> { _ => todo!("TyKind of gen must be TyVar: {:?}", tyvar.kind()), } } - for region in traitgenarg.regions.iter(){ - match region.kind() { - CharonRegionKind::RegionVar(regionid) => { - let subs_region = c_regions.get(*regionid).unwrap().clone(); - t_regions.push(subs_region); - } - _ => todo!("RegionKind of gen must be RegionVar: {:?}", region.kind()), - } - } - - } + let subs_traitdeclref = CharonPolyTraitDeclRef { + regions : trait_ref.trait_decl_ref.regions.clone(), + skip_binder : CharonTraitDeclRef { + trait_id: trait_ref.trait_decl_ref.skip_binder.trait_id, + generics: CharonGenericArgs { + regions: t_regions, + types: t_types, + const_generics: t_const_generics, + trait_refs: trait_ref.trait_decl_ref.skip_binder.generics.trait_refs.clone(), + }, + }, + }; + let subs_traitref = CharonTraitRef { + kind : trait_ref.kind.clone(), + trait_decl_ref: subs_traitdeclref + }; + trait_refs.push(subs_traitref); + } CharonGenericArgs { regions: c_regions, types: c_types, @@ -1297,9 +1306,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { self.translate_adtdef(adt_def); } let c_generic_args = self.translate_generic_args(genarg, adt_def.def_id()); - //println!("Generic arg type {:?}", c_generic_args.types); + println!("Generic arg type {:?}", c_generic_args.types); //println!("Generic param type {:?}", self.generic_params_from_adtdef(adt_def).types); - //println!("Generic trait type {:?}", c_generic_args.trait_refs); + println!("Generic trait type {:?}", c_generic_args.trait_refs); CharonTy::new(CharonTyKind::Adt(CharonTypeId::Adt(c_typedeclid), c_generic_args)) } RigidTy::Slice(ty) => { From 659f83b9ed9f4c93c895fe01f9810431892ebaf6 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Wed, 27 Nov 2024 13:24:25 -0800 Subject: [PATCH 28/51] save --- .../src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 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 243d452350a5..1c437a90b14b 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,6 +78,7 @@ pub struct Context<'a, 'tcx> { id_map: &'a mut FxHashMap, errors: &'a mut CharonErrorCtx<'tcx>, local_names: FxHashMap, + trait_clauses : &'a mut CharonVector, } impl<'a, 'tcx> Context<'a, 'tcx> { @@ -99,8 +100,8 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } } - - Self { tcx, instance, translated, id_map, errors, local_names } + let mut + Self { tcx, instance, translated, id_map, errors, local_names, trait_clauses: CharonVector::new() } } fn tcx(&self) -> TyCtxt<'tcx> { @@ -224,6 +225,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let funcname = item_meta.name.clone(); println!("Func name: {:?}", funcname); let signature = self.translate_function_signature(); + println!("Func sig: {:?}", signature.generics.trait_clauses); let body = if is_builtin { Err(CharonOpaque) } else { @@ -1038,6 +1040,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { TyKind::RigidTy(RigidTy::FnDef(fndef,_ )) => fndef, _ => panic!("Expected a function type"), }; + let c_genparam = self.generic_params_from_fndef(fndef); let value = fndef.fn_sig().value; let inputs = value.inputs().to_vec(); let c_inputs: Vec = inputs.iter().map(|ty| self.translate_ty(*ty)).collect(); @@ -1073,7 +1076,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { //let ret_type = self.translate_ty(fn_abi.ret.ty); //println!("cinput len {:?} ", c_inputs.len()); //println!("args len {:?}", args.clone().len()); - let c_genparam = self.generic_params_from_fndef(fndef); + // TODO: populate the rest of the information (`is_unsafe`, `is_closure`, etc.) CharonFunSig { is_unsafe: false, @@ -1306,9 +1309,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { self.translate_adtdef(adt_def); } let c_generic_args = self.translate_generic_args(genarg, adt_def.def_id()); - println!("Generic arg type {:?}", c_generic_args.types); + //println!("Generic arg type {:?}", c_generic_args.types); //println!("Generic param type {:?}", self.generic_params_from_adtdef(adt_def).types); - println!("Generic trait type {:?}", c_generic_args.trait_refs); + //println!("Generic trait type {:?}", c_generic_args.trait_refs); CharonTy::new(CharonTyKind::Adt(CharonTypeId::Adt(c_typedeclid), c_generic_args)) } RigidTy::Slice(ty) => { From e668d4486d593d7e86382b682971ac611ee86970 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Wed, 27 Nov 2024 16:02:04 -0800 Subject: [PATCH 29/51] save --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 48 +++++++++++++------ 1 file changed, 34 insertions(+), 14 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 1c437a90b14b..51df16b066f1 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,7 +78,7 @@ pub struct Context<'a, 'tcx> { id_map: &'a mut FxHashMap, errors: &'a mut CharonErrorCtx<'tcx>, local_names: FxHashMap, - trait_clauses : &'a mut CharonVector, + trait_clauses : CharonVector, } impl<'a, 'tcx> Context<'a, 'tcx> { @@ -100,7 +100,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } } - let mut Self { tcx, instance, translated, id_map, errors, local_names, trait_clauses: CharonVector::new() } } @@ -151,6 +150,18 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } + fn find_trait_clause_id(&mut self, id: CharonTraitDeclId, genarg: CharonGenericArgs, j: usize) -> CharonTraitClauseId { + for (i, tc) in self.trait_clauses.iter().enumerate() { + if tc.trait_.skip_binder.trait_id == id { + if tc.trait_.skip_binder.generics == genarg { + println!("found {:?} {:?}", i, j); + return CharonTraitClauseId::from_usize(i); + } + } + } + CharonTraitClauseId::from_usize(j) + } + fn get_traitrefs_from_defid(&mut self, defid: DefId) -> CharonVector{ let inter_defid = rustc_internal::internal(self.tcx,defid); let predicates = self.tcx().predicates_of(inter_defid).predicates.to_vec(); @@ -166,7 +177,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { //println!("Genargs Type: {:?}", c_genarg.types); let c_polytrait = CharonPolyTraitDeclRef{ regions: CharonVector::new(), - skip_binder : CharonTraitDeclRef {trait_id: c_traitdecl_id, generics: c_genarg}, + skip_binder : CharonTraitDeclRef {trait_id: c_traitdecl_id, generics: c_genarg.clone()}, }; let c_traitref = CharonTraitRef{ kind: CharonTraitRefKind::Clause(CharonTraitClauseId::from_usize(i)), @@ -175,7 +186,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { c_trait_refs.push(c_traitref); } - //println!("Predicates: {:?}", predicates); + //println!("Predicates: {:?}", predicates);cargo build-dev c_trait_refs } @@ -225,7 +236,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let funcname = item_meta.name.clone(); println!("Func name: {:?}", funcname); let signature = self.translate_function_signature(); - println!("Func sig: {:?}", signature.generics.trait_clauses); + for l in self.trait_clauses.iter(){ + println!("Fun Trait Clause: {:?}", l); + } let body = if is_builtin { Err(CharonOpaque) } else { @@ -1040,10 +1053,14 @@ impl<'a, 'tcx> Context<'a, 'tcx> { TyKind::RigidTy(RigidTy::FnDef(fndef,_ )) => fndef, _ => panic!("Expected a function type"), }; - let c_genparam = self.generic_params_from_fndef(fndef); + let c_genparam = self.generic_params_from_fndef(fndef); + self.trait_clauses = c_genparam.trait_clauses.clone(); let value = fndef.fn_sig().value; let inputs = value.inputs().to_vec(); let c_inputs: Vec = inputs.iter().map(|ty| self.translate_ty(*ty)).collect(); + for l in c_inputs.iter() { + println!("Input ty {:?}", l); + } let c_output = self.translate_ty(value.output()); /* @@ -1153,20 +1170,23 @@ impl<'a, 'tcx> Context<'a, 'tcx> { _ => todo!("TyKind of gen must be TyVar: {:?}", tyvar.kind()), } } + let generics= CharonGenericArgs { + regions: t_regions, + types: t_types, + const_generics: t_const_generics, + trait_refs: trait_ref.trait_decl_ref.skip_binder.generics.trait_refs.clone(), + }; + let traitdecl_id = trait_ref.trait_decl_ref.skip_binder.trait_id; let subs_traitdeclref = CharonPolyTraitDeclRef { regions : trait_ref.trait_decl_ref.regions.clone(), skip_binder : CharonTraitDeclRef { - trait_id: trait_ref.trait_decl_ref.skip_binder.trait_id, - generics: CharonGenericArgs { - regions: t_regions, - types: t_types, - const_generics: t_const_generics, - trait_refs: trait_ref.trait_decl_ref.skip_binder.generics.trait_refs.clone(), - }, + trait_id: traitdecl_id.clone(), + generics: generics.clone(), }, }; + let traitclause_id = self.find_trait_clause_id(traitdecl_id, generics.clone(), 0); let subs_traitref = CharonTraitRef { - kind : trait_ref.kind.clone(), + kind : CharonTraitRefKind::Clause(traitclause_id), trait_decl_ref: subs_traitdeclref }; trait_refs.push(subs_traitref); From 9f5774cd609d17c5d993a63dae60b6a29b2f617b Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 30 Dec 2024 13:43:55 -0800 Subject: [PATCH 30/51] translate trait --- .../codegen_aeneas_llbc/compiler_interface.rs | 2 +- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 335 ++++++++++++------ 2 files changed, 226 insertions(+), 111 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs b/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs index 0cccda92f3b7..1d96e0c9ec98 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs @@ -397,7 +397,7 @@ where fn create_charon_transformation_context(tcx: TyCtxt) -> TransformCtx { let options = TransformOptions { no_code_duplication: false, - hide_marker_traits: false, + hide_marker_traits: true, no_merge_goto_chains: false, item_opacities: Vec::new(), }; 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 3c12764a8ffc..47ba6443a339 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 @@ -12,6 +12,8 @@ use charon_lib::ast::meta::{ use charon_lib::ast::types::{ Ty as CharonTy, TyKind as CharonTyKind, TypeDeclId as CharonTypeDeclId, }; +use rustc_middle::query::Key; +use std::iter::zip; use charon_lib::ast::{ AbortKind as CharonAbortKind, AggregateKind as CharonAggregateKind, AnyTransId as CharonAnyTransId, Assert as CharonAssert, BinOp as CharonBinOp, @@ -38,6 +40,9 @@ use charon_lib::ast::{ TraitClauseId as CharonTraitClauseId, TraitClause as CharonTraitClause, TraitDeclId as CharonTraitDeclId, TraitDecl as CharonTraitDecl, TraitRef as CharonTraitRef, PolyTraitDeclRef as CharonPolyTraitDeclRef, TraitDeclRef as CharonTraitDeclRef, TraitRefKind as CharonTraitRefKind, PredicateOrigin as CharonPredicateOrigin, + DeBruijnId as CharonDeBruijnId, GlobalDeclId as CharonGlobalDeclId, GlobalDecl as CharonGlobalDecl, + GlobalDeclRef as CharonGlobalDeclRef, ExistentialPredicate as CharonExistentialPredicate, + TraitImplId as CharonTraitImplId, ImplElem as CharonImplElem, }; use charon_lib::errors::{Error as CharonError, ErrorCtx as CharonErrorCtx}; use charon_lib::ids::Vector as CharonVector; @@ -61,9 +66,7 @@ use stable_mir::mir::{ TerminatorKind, UnOp, VarDebugInfoContents, }; use stable_mir::ty::{ - AdtDef, AdtKind, Allocation, ConstantKind, GenericArgKind, GenericArgs, IndexedVal, IntTy, - MirConst, Region, RegionKind, RigidTy, Span, Ty, TyConst, TyConstKind, TyKind, UintTy, FnDef, GenericPredicates, - TraitDef, TraitDecl, GenericParamDefKind + AdtDef, AdtKind, AliasKind, Allocation, ConstantKind, FnDef, GenericArgKind, GenericArgs, GenericParamDefKind, GenericPredicates, IndexedVal, IntTy, MirConst, Region, RegionKind, RigidTy, Span, TraitDecl, TraitDef, TraitRef, Ty, TyConst, TyConstKind, TyKind, UintTy }; use stable_mir::{CrateDef, CrateDefType, DefId}; use std::path::PathBuf; @@ -117,6 +120,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { fn translate_traitdecl(&mut self, trait_def: TraitDef) -> CharonTraitDeclId { let trait_def_id = trait_def.def_id(); + //println!("Trait name {:?}", self.defid_to_name(trait_def_id)); let trait_decl_id = self.register_trait_decl_id(trait_def_id); match self.translated.trait_decls.get(trait_decl_id) { None => { @@ -150,31 +154,61 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } - fn find_trait_clause_id(&mut self, id: CharonTraitDeclId, genarg: CharonGenericArgs, j: usize) -> CharonTraitClauseId { + fn register_trait_clause_id(&mut self, id: CharonTraitDeclId, genarg: CharonGenericArgs, span: CharonSpan) -> CharonTraitClauseId { for (i, tc) in self.trait_clauses.iter().enumerate() { if tc.trait_.skip_binder.trait_id == id { if tc.trait_.skip_binder.generics == genarg { - println!("found {:?} {:?}", i, j); return CharonTraitClauseId::from_usize(i); } } } - CharonTraitClauseId::from_usize(j) + let c_polytrait = CharonPolyTraitDeclRef{ + regions: CharonVector::new(), + skip_binder : CharonTraitDeclRef {trait_id: id, generics: genarg}, + }; + let clause_id = CharonTraitClauseId::from_usize(self.trait_clauses.len()); + let c_traitclause = CharonTraitClause{ + clause_id: clause_id.clone(), + span: Some(span), + trait_: c_polytrait, + origin: CharonPredicateOrigin::WhereClauseOnType + + }; + self.trait_clauses.push(c_traitclause); + clause_id + } + + fn translate_traitref(&mut self, trait_ref: TraitRef) -> CharonTraitRef{ + let trait_def = trait_ref.def_id; + let c_traitdecl_id = self.translate_traitdecl(trait_def); + let c_genarg = self.translate_generic_args_withouttrait(trait_ref.args().clone()); + let c_polytrait = CharonPolyTraitDeclRef{ + regions: CharonVector::new(), + skip_binder : CharonTraitDeclRef {trait_id: c_traitdecl_id, generics: c_genarg.clone()}, + }; + CharonTraitRef{ + //kind: CharonTraitRefKind::TraitImpl((), ()), + kind: CharonTraitRefKind::Clause(CharonTraitClauseId::from_usize(0)), + trait_decl_ref: c_polytrait, + } } - fn get_traitrefs_from_defid(&mut self, defid: DefId) -> CharonVector{ + fn get_traitrefs_and_span_from_defid(&mut self, defid: DefId) -> (CharonVector, Vec){ let inter_defid = rustc_internal::internal(self.tcx,defid); let predicates = self.tcx().predicates_of(inter_defid).predicates.to_vec(); let mut c_trait_refs: CharonVector = CharonVector::new(); - for (i,(clause, _)) in predicates.iter().enumerate() { + let mut c_spans = Vec::new(); + for (i,(clause, span)) in predicates.iter().enumerate() { + let trait_clause = clause.as_trait_clause(); + if trait_clause.is_none() {continue}; let trait_id_internal = clause.as_trait_clause().unwrap(); let trait_binder = rustc_internal::stable(trait_id_internal); let trait_param = trait_binder.bound_vars; let trait_ref = trait_binder.value.trait_ref; let trait_def = trait_ref.def_id; + if self.is_marker_trait(trait_def) {continue}; let c_traitdecl_id = self.translate_traitdecl(trait_def); let c_genarg = self.translate_generic_args_withouttrait(trait_ref.args().clone()); - //println!("Genargs Type: {:?}", c_genarg.types); let c_polytrait = CharonPolyTraitDeclRef{ regions: CharonVector::new(), skip_binder : CharonTraitDeclRef {trait_id: c_traitdecl_id, generics: c_genarg.clone()}, @@ -184,10 +218,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { trait_decl_ref: c_polytrait, }; c_trait_refs.push(c_traitref); - + c_spans.push(self.translate_span(rustc_internal::stable(span))); } - //println!("Predicates: {:?}", predicates);cargo build-dev - c_trait_refs + (c_trait_refs, c_spans) } fn get_traitclauses_from_defid(&mut self, defid: DefId) -> CharonVector{ @@ -195,12 +228,14 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let predicates = self.tcx().predicates_of(inter_defid).predicates.to_vec(); let mut c_trait_clauses: CharonVector = CharonVector::new(); for (i,(clause, span)) in predicates.iter().enumerate() { + let trait_clause = clause.as_trait_clause(); + if trait_clause.is_none() {continue}; let trait_id_internal = clause.as_trait_clause().unwrap(); let trait_ref = rustc_internal::stable(trait_id_internal).value.trait_ref; let trait_def = trait_ref.def_id; + if self.is_marker_trait(trait_def) {continue}; let c_traitdecl_id = self.translate_traitdecl(trait_def); let c_genarg = self.translate_generic_args_withouttrait(trait_ref.args().clone()); - //println!("Genargs Type: {:?}", c_genarg.types); let c_polytrait = CharonPolyTraitDeclRef{ regions: CharonVector::new(), skip_binder : CharonTraitDeclRef {trait_id: c_traitdecl_id, generics: c_genarg}, @@ -226,7 +261,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let instance_def = self.instance.def; let is_builtin = self.is_builtin_fun(instance_def); let fid = self.register_fun_decl_id(self.instance.def.def_id()); - let item_meta = match self.translate_item_meta_from_rid(self.instance) { Ok(item_meta) => item_meta, Err(_) => { @@ -235,14 +269,12 @@ impl<'a, 'tcx> Context<'a, 'tcx> { }; let funcname = item_meta.name.clone(); println!("Func name: {:?}", funcname); - let signature = self.translate_function_signature(); - for l in self.trait_clauses.iter(){ - println!("Fun Trait Clause: {:?}", l); - } + println!("Func def_id: {:?}", fid); + let signature = self.translate_function_signature(self.instance); let body = if is_builtin { Err(CharonOpaque) } else { - let bodyid = match self.translate_function_body() { + let bodyid = match self.translate_function_body(self.instance) { Ok(body) => body, Err(_) => { return Err(()); @@ -261,12 +293,12 @@ impl<'a, 'tcx> Context<'a, 'tcx> { None => self.translated.fun_decls.set_slot(fid, fun_decl), Some(_) => {}, }; - println!("Complete Func name: {:?}", funcname); Ok(()) } + /// 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); @@ -316,6 +348,38 @@ impl<'a, 'tcx> Context<'a, 'tcx> { tid.try_into().unwrap() } + fn register_trait_impl_id(&mut self, def_id: DefId) -> CharonTraitImplId { + debug!("register_trait_decl_id: {:?}", def_id); + let tid = match self.id_map.get(&def_id) { + Some(tid) => *tid, + None => { + debug!("***Not found!"); + let tid = CharonAnyTransId::TraitImpl(self.translated.trait_impls.reserve_slot()); + self.id_map.insert(def_id, tid); + self.translated.all_ids.insert(tid); + tid + } + }; + debug!("register_trait_decl_id: {:?}", self.id_map); + tid.try_into().unwrap() + } + + fn register_global_decl_id(&mut self, def_id: DefId) -> CharonGlobalDeclId { + debug!("register_trait_decl_id: {:?}", def_id); + let tid = match self.id_map.get(&def_id) { + Some(tid) => *tid, + None => { + debug!("***Not found!"); + let tid = CharonAnyTransId::Global(self.translated.global_decls.reserve_slot()); + self.id_map.insert(def_id, tid); + self.translated.all_ids.insert(tid); + tid + } + }; + debug!("register_global_decl_id: {:?}", self.id_map); + 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 get_type_decl_id(&self, def_id: DefId) -> CharonTypeDeclId { debug!("register_type_decl_id: {:?}", def_id); @@ -351,11 +415,13 @@ impl<'a, 'tcx> Context<'a, 'tcx> { }, GenericParamDefKind::Const{has_default: _} => { let def_id_internal = rustc_internal::internal(self.tcx, gendef.def_id.0); - let paramenv = self.tcx.param_env(def_id_internal); + let gitnv = self.tcx.param_env(def_id_internal); let pc_internal = rustc_middle::ty::ParamConst { index : index as u32, name: rustc_span::Symbol::intern(&name.clone()), }; + let paramenv = + TypingEnv::post_analysis(self.tcx, def_id_internal).param_env; 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); @@ -383,11 +449,15 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } - fn generic_params_from_fndef(&mut self, fndef: FnDef) -> CharonGenericParams { + fn generic_params_from_fndef(&mut self, fndef: FnDef, input: Vec) -> CharonGenericParams { let genvec = match fndef.ty().kind(){ TyKind::RigidTy(RigidTy::FnDef(_, genarg)) => genarg.0, _ => panic!("generic_params_from_fndef: not an FnDef"), }; + let internal_id = rustc_internal::internal(self.tcx,fndef.def_id()); + let genvecparam = self.tcx.generics_of(internal_id).own_params.clone(); + let value = fndef.fn_sig().value; + let genvecparam = value.inputs().get(0); let mut c_regions: CharonVector = CharonVector::new(); let mut c_types: CharonVector = CharonVector::new(); let mut c_const_generics: CharonVector = @@ -441,6 +511,25 @@ impl<'a, 'tcx> Context<'a, 'tcx> { }, } } + for inpty in input.iter(){ + match inpty.kind() { + TyKind::RigidTy(rty) => match rty { + RigidTy::Ref(r, _ , _ ) => match r.kind { + RegionKind::ReBound(_,br ) => { + let id =br.var as usize; + let c_region = CharonRegionVar { + index: CharonRegionId::from_usize(id), + name: None + }; + c_regions.push(c_region); + } + _ => (), + } + _ => (), + } + _ => (), + } + } let trait_clauses = self.get_traitclauses_from_defid(fndef.def_id()); CharonGenericParams { regions: c_regions, @@ -702,7 +791,20 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonPathElem::Ident(cn,_) => cn, _ => panic!("Imple name"), }; - crate_name.starts_with("std") || crate_name.starts_with("core") + crate_name.starts_with("std") || crate_name.starts_with("core") || crate_name.starts_with("alloc") + } + + fn is_marker_trait(&mut self, traitdef: TraitDef ) -> bool { + let name = self.defid_to_name(traitdef.def_id()).unwrap(); + let crate_name = match name.name.get(0).unwrap() { + CharonPathElem::Ident(cn,_) => cn, + _ => panic!("Imple name"), + }; + let marker = match name.name.get(1).unwrap() { + CharonPathElem::Ident(cn,_) => cn, + _ => panic!("Imple name"), + }; + crate_name.starts_with("core") && marker.starts_with("marker") } @@ -928,6 +1030,19 @@ impl<'a, 'tcx> Context<'a, 'tcx> { name.push(CharonPathElem::Ident(crate_name, CharonDisambiguator::new(0))); } + let instancedef_internal = rustc_span::def_id::DefId::local(rustc_span::def_id::DefIndex::from_usize(def_id.index.as_usize())); + match self.tcx.impl_of_method(instancedef_internal) { + Some(impl_defid_internal) => { + let impl_defid = DefId::to_val(impl_defid_internal.index.as_usize()); + let impl_id =self.register_trait_impl_id(impl_defid); + let funcname =match name.pop().unwrap() { + CharonPathElem::Ident(name, _) => name + &impl_id.to_string(), + _ => panic!("Expected ident") + }; + name.push(CharonPathElem::Ident(funcname, CharonDisambiguator::new(0))); + } + None => {} + }; trace!("{:?}", name); Ok(CharonName { name }) } @@ -1048,53 +1163,21 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonSpan { span: rspan, generated_from_span: None } } - fn translate_function_signature(&mut self) -> CharonFunSig { - let instance = self.instance; + fn translate_function_signature(&mut self, instance: Instance) -> CharonFunSig { + //let instance = self.instance; let fndef = match instance.ty().kind() { TyKind::RigidTy(RigidTy::FnDef(fndef,_ )) => fndef, _ => panic!("Expected a function type"), }; - let c_genparam = self.generic_params_from_fndef(fndef); - self.trait_clauses = c_genparam.trait_clauses.clone(); + //self.trait_clauses = c_genparam.trait_clauses.clone(); let value = fndef.fn_sig().value; let inputs = value.inputs().to_vec(); + let c_genparam = self.generic_params_from_fndef(fndef, inputs.clone()); + //println!("generic param {:?}", c_genparam.clone()); + //println!("inp types {:?}", inputs.clone()); let c_inputs: Vec = inputs.iter().map(|ty| self.translate_ty(*ty)).collect(); - for l in c_inputs.iter() { - println!("Input ty {:?}", l); - } + //println!("trans input type{:?}", c_inputs.clone()); let c_output = self.translate_ty(value.output()); - -/* - let fn_abi = instance.fn_abi().unwrap(); - let requires_caller_location = self.requires_caller_location(instance); - let num_args = fn_abi.args.len(); - let args : Vec = fn_abi - .args - .iter() - .enumerate() - .filter_map(|(idx, arg_abi)| { - // We ignore zero-sized parameters. - // See https://github.com/model-checking/kani/issues/274 for more details. - // We also ingore the last parameter if the function requires - // caller location. - if arg_abi.mode == PassMode::Ignore - || (requires_caller_location && idx + 1 == num_args) - { - None - } else { - let ty = arg_abi.ty; - debug!(?idx, ?arg_abi, "fn_typ"); - Some(self.translate_ty(ty)) - } - }) - .collect(); -*/ - - //debug!(?args, ?fn_abi, "function_type"); - //let ret_type = self.translate_ty(fn_abi.ret.ty); - //println!("cinput len {:?} ", c_inputs.len()); - //println!("args len {:?}", args.clone().len()); - // TODO: populate the rest of the information (`is_unsafe`, `is_closure`, etc.) CharonFunSig { is_unsafe: false, @@ -1107,9 +1190,13 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } - fn translate_function_body(&mut self) -> Result { - let instance = self.instance; - let mir_body = instance.body().unwrap(); + fn translate_function_body(&mut self, instance: Instance) -> Result { + //let instance = self.instance; + let fndef = match instance.ty().kind() { + TyKind::RigidTy(RigidTy::FnDef(fndef,_ )) => fndef, + _ => panic!("Expected a function type"), + }; + let mir_body = fndef.body().unwrap(); let body_id = self.translated.bodies.reserve_slot(); let body = self.translate_body(mir_body); self.translated.bodies.set_slot(body_id, body); @@ -1141,10 +1228,12 @@ impl<'a, 'tcx> Context<'a, 'tcx> { 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); @@ -1153,11 +1242,13 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let c_const_generic = self.tyconst_to_constgeneric(tc); c_const_generics.push(c_const_generic); } + //_ => (), } } - let gen_trait_refs = self.get_traitrefs_from_defid(defid); + let (gen_trait_refs, spans) = self.get_traitrefs_and_span_from_defid(defid); let mut trait_refs: CharonVector = CharonVector::new(); - for trait_ref in gen_trait_refs.iter() { + let trait_ref_span_zip = zip(spans.clone(), gen_trait_refs.clone()); + for (span, trait_ref) in trait_ref_span_zip { let traitgenarg = trait_ref.trait_decl_ref.skip_binder.generics.clone(); let mut t_regions: CharonVector = CharonVector::new(); let mut t_types: CharonVector = CharonVector::new(); @@ -1185,13 +1276,13 @@ impl<'a, 'tcx> Context<'a, 'tcx> { generics: generics.clone(), }, }; - let traitclause_id = self.find_trait_clause_id(traitdecl_id, generics.clone(), 0); + let traitclause_id = self.register_trait_clause_id(traitdecl_id, generics.clone(), span); let subs_traitref = CharonTraitRef { - kind : CharonTraitRefKind::Clause(traitclause_id), + kind : CharonTraitRefKind::BuiltinOrAuto(subs_traitdeclref.clone()), trait_decl_ref: subs_traitdeclref }; trait_refs.push(subs_traitref); - } + } CharonGenericArgs { regions: c_regions, types: c_types, @@ -1237,6 +1328,27 @@ impl<'a, 'tcx> Context<'a, 'tcx> { TyKind::Param(paramty) => CharonTy::new(CharonTyKind::TypeVar( CharonTypeVarId::from_usize(paramty.index as usize), )), + /* + TyKind::Alias(akind, atype) => { + let tk_internal = rustc_internal::internal(self.tcx, ty).kind().clone(); + match tk_internal { + rustc_middle::ty::TyKind::Alias(akind,aty ) =>{ + match akind { + rustc_middle::ty::AliasTyKind::Opaque => { + let hiddentype = rustc_internal::stable(aty.to_ty(self.tcx)); + self.translate_ty(hiddentype) + } + rustc_middle::ty::AliasTyKind::Projection => { + let trait_ref = rustc_internal::stable(aty.trait_ref(self.tcx)); + + } + _ => panic + } + } + _=> panic + } + + }*/ x => todo!("Not yet implemented translation for TyKind: {:?}", x), } } @@ -1314,9 +1426,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonTy::new(CharonTyKind::Adt(CharonTypeId::Tuple, generic_args)) } RigidTy::FnDef(def_id, args) => { - if !args.0.is_empty() { - unimplemented!("generic args are not yet handled"); - } let sig = def_id.fn_sig().value; let inputs = sig.inputs().iter().map(|ty| self.translate_ty(*ty)).collect(); let output = self.translate_ty(sig.output()); @@ -1330,9 +1439,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { self.translate_adtdef(adt_def); } let c_generic_args = self.translate_generic_args(genarg, adt_def.def_id()); - //println!("Generic arg type {:?}", c_generic_args.types); - //println!("Generic param type {:?}", self.generic_params_from_adtdef(adt_def).types); - //println!("Generic trait type {:?}", c_generic_args.trait_refs); CharonTy::new(CharonTyKind::Adt(CharonTypeId::Adt(c_typedeclid), c_generic_args)) } RigidTy::Slice(ty) => { @@ -1351,6 +1457,14 @@ impl<'a, 'tcx> Context<'a, 'tcx> { Mutability::Not => CharonRefKind::Shared, })) } + RigidTy::FnPtr(polyfunsig) => { + let value = polyfunsig.value; + let inputs = value.inputs().to_vec(); + let c_inputs: Vec = inputs.iter().map(|ty| self.translate_ty(*ty)).collect(); + let c_output = self.translate_ty(value.output()); + CharonTy::new(CharonTyKind::Arrow(CharonVector::new(), c_inputs, c_output)) + } + RigidTy::Dynamic(ep,_ ,_ ) => CharonTy::new(CharonTyKind::DynTrait(CharonExistentialPredicate)), _ => todo!("Not yet implemented RigidTy: {:?}", rigid_ty), } } @@ -1428,38 +1542,24 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } TerminatorKind::Call { func, args, destination, target, .. } => { debug!("translate_call: {func:?} {args:?} {destination:?} {target:?}"); + println!("Calling {:?}", func); let fn_ty = func.ty(self.instance.body().unwrap().locals()).unwrap(); let fn_ptr = match fn_ty.kind() { - TyKind::RigidTy(RigidTy::FnDef(def, args)) => { - let instance = Instance::resolve(def, &args).unwrap(); + TyKind::RigidTy(RigidTy::FnDef(def, genarg)) => { + let instance = Instance::resolve(def, &genarg).unwrap(); let def_id = instance.def.def_id(); - let builtin_fun = self.recognize_primitive_fun(instance.def); - let func = if let Some(builtin_fun) = builtin_fun { - println!("Found builtin func {:?}", instance.def.name()); - let aid = builtin_fun.to_ullbc_builtin_fun(); - match aid { - CharonBuiltinFunId::BoxNew => { - // Nothing to do - } - CharonBuiltinFunId::Index { .. } - | CharonBuiltinFunId::ArrayToSliceShared - | CharonBuiltinFunId::ArrayToSliceMut - | CharonBuiltinFunId::ArrayRepeat => { - // Those cases are introduced later, in micro-passes, by desugaring - // projections (for ArrayIndex and ArrayIndexMut for instnace) and= - // operations (for ArrayToSlice for instance) to function calls. - unreachable!() - } - }; - CharonFunIdOrTraitMethodRef::Fun(CharonFunId::Builtin(aid)) - } else { - let fid = self.register_fun_decl_id(def_id); - CharonFunIdOrTraitMethodRef::Fun(CharonFunId::Regular(fid)) - }; + let fid = self.register_fun_decl_id(def_id); + let genarg_resolve = match instance.ty().kind() { + TyKind::RigidTy(RigidTy::FnDef(_, ga )) => ga, + _ => panic!("Expected a function type"), + }; + let funcid = CharonFunIdOrTraitMethodRef::Fun(CharonFunId::Regular(fid)); + let generics = self.translate_generic_args(genarg_resolve, def_id); + println!("Func call genarg {:?}", generics); CharonFnPtr { - func, + func: funcid, // TODO: populate generics? - generics: self.translate_generic_args(args, def.def_id()), + generics } } TyKind::RigidTy(RigidTy::FnPtr(..)) => todo!(), @@ -1468,9 +1568,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { x ), }; - let func = CharonFnOperand::Regular(fn_ptr); + let c_func_op = CharonFnOperand::Regular(fn_ptr); let call = CharonCall { - func, + func: c_func_op, args: args.iter().map(|arg| self.translate_operand(arg)).collect(), dest: self.translate_place(destination), }; @@ -1529,7 +1629,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { self.translate_operand(lhs), self.translate_operand(rhs), ), - //TODO: recheck Rvalue::CheckedBinaryOp(bin_op, lhs, rhs) => CharonRvalue::BinaryOp( translate_bin_op(*bin_op), self.translate_operand(lhs), @@ -1634,13 +1733,18 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonConstantExpr { value, ty: self.translate_ty(constant.ty()) } } - fn translate_constant_value(&self, constant: &MirConst) -> CharonRawConstantExpr { + fn translate_constant_value(&mut self, constant: &MirConst) -> CharonRawConstantExpr { trace!("translate_constant_value: {constant:?}"); match constant.kind() { ConstantKind::Allocated(alloc) => self.translate_allocation(alloc, constant.ty()), ConstantKind::Ty(_) => todo!(), ConstantKind::ZeroSized => todo!(), - ConstantKind::Unevaluated(_) => todo!(), + ConstantKind::Unevaluated(uc) => { + let defid = uc.def.def_id(); + let c_defid = self.register_global_decl_id(defid); + let c_genarg = self.translate_generic_args(uc.args.clone(), defid); + CharonRawConstantExpr::Global(CharonGlobalDeclRef{id: c_defid, generics: c_genarg}) + } ConstantKind::Param(_) => todo!(), } } @@ -1748,7 +1852,13 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let mut current_var: usize = 0; for prj in projection.iter() { match prj { - ProjectionElem::Deref => c_provec.push(CharonProjectionElem::Deref), + ProjectionElem::Deref => { + match current_ty.kind() { + CharonTyKind::Ref(_,ty,_ , ) => current_ty = ty.clone(), + _ => (), + } + c_provec.push(CharonProjectionElem::Deref) + } ProjectionElem::Field(fid, ty) => { let c_fieldid = CharonFieldId::from_usize(*fid); let c_variantid = CharonVariantId::from_usize(current_var); @@ -1801,7 +1911,12 @@ impl<'a, 'tcx> Context<'a, 'tcx> { RegionKind::ReStatic => CharonRegion::Static, RegionKind::ReErased => CharonRegion::Erased, RegionKind::ReEarlyParam(_) => CharonRegion::Unknown, - RegionKind::ReBound(_, _) | RegionKind::RePlaceholder(_) => { + RegionKind::ReBound(var,boundregion) => //CharonRegion::Static, + { + println!("region {:?}", boundregion.var.clone()); + CharonRegion::BVar(CharonDeBruijnId{index: var as usize}, CharonRegionId::from_usize(boundregion.var as usize)) + } + RegionKind::RePlaceholder(_) => { todo!("Not yet implemented RegionKind: {:?}", region.kind) } } From 865bdd9876a5539217951f7447a01f186dccddc0 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Tue, 31 Dec 2024 10:24:26 -0800 Subject: [PATCH 31/51] fixed clippy --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 386 +++++++++--------- 1 file changed, 204 insertions(+), 182 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 731313151f9a..724c8d8b48aa 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,14 +6,11 @@ //! This module contains a context for translating stable MIR into Charon's //! unstructured low-level borrow calculus (ULLBC) +use charon_lib::ast::krate::TypeDeclId as CharonTypeDeclId; use charon_lib::ast::meta::{ AttrInfo as CharonAttrInfo, Loc as CharonLoc, RawSpan as CharonRawSpan, }; -use charon_lib::ast::types::{ - Ty as CharonTy, TyKind as CharonTyKind, -}; -use charon_lib::ast::krate::TypeDeclId as CharonTypeDeclId; -use std::iter::zip; +use charon_lib::ast::types::{Ty as CharonTy, TyKind as CharonTyKind}; use charon_lib::ast::{ AbortKind as CharonAbortKind, AggregateKind as CharonAggregateKind, AnyTransId as CharonAnyTransId, Assert as CharonAssert, BinOp as CharonBinOp, @@ -21,28 +18,31 @@ use charon_lib::ast::{ 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, + DeBruijnId as CharonDeBruijnId, DeBruijnVar as CharonDeBruijnVar, + Disambiguator as CharonDisambiguator, ExistentialPredicate as CharonExistentialPredicate, + Field as CharonField, FieldId as CharonFieldId, FieldProjKind as CharonFieldProjKind, + File as CharonFile, FileId as CharonFileId, 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, + GlobalDeclId as CharonGlobalDeclId, GlobalDeclRef as CharonGlobalDeclRef, IntegerTy as CharonIntegerTy, ItemKind as CharonItemKind, ItemMeta as CharonItemMeta, ItemOpacity as CharonItemOpacity, Literal as CharonLiteral, LiteralTy as CharonLiteralTy, - Name as CharonName, Opaque as CharonOpaque, Operand as CharonOperand, - PathElem as CharonPathElem, Place as CharonPlace, ProjectionElem as CharonProjectionElem, + Locals as CharonLocals, Name as CharonName, Opaque as CharonOpaque, Operand as CharonOperand, + PathElem as CharonPathElem, Place as CharonPlace, PolyTraitDeclRef as CharonPolyTraitDeclRef, + PredicateOrigin as CharonPredicateOrigin, ProjectionElem as CharonProjectionElem, RawConstantExpr as CharonRawConstantExpr, RefKind as CharonRefKind, Region as CharonRegion, - 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, - TraitClauseId as CharonTraitClauseId, TraitClause as CharonTraitClause, TraitDeclId as CharonTraitDeclId, - TraitDecl as CharonTraitDecl, TraitRef as CharonTraitRef, PolyTraitDeclRef as CharonPolyTraitDeclRef, - TraitDeclRef as CharonTraitDeclRef, TraitRefKind as CharonTraitRefKind, PredicateOrigin as CharonPredicateOrigin, - DeBruijnId as CharonDeBruijnId, GlobalDeclId as CharonGlobalDeclId, - GlobalDeclRef as CharonGlobalDeclRef, ExistentialPredicate as CharonExistentialPredicate, - TraitImplId as CharonTraitImplId, Locals as CharonLocals, RegionBinder as CharonRegionBinder, - DeBruijnVar as CharonDeBruijnVar, FileId as CharonFileId, File as CharonFile, + RegionBinder as CharonRegionBinder, RegionId as CharonRegionId, RegionVar as CharonRegionVar, + Rvalue as CharonRvalue, ScalarValue as CharonScalarValue, Span as CharonSpan, + TraitClause as CharonTraitClause, TraitClauseId as CharonTraitClauseId, + TraitDecl as CharonTraitDecl, TraitDeclId as CharonTraitDeclId, + TraitDeclRef as CharonTraitDeclRef, TraitImplId as CharonTraitImplId, + TraitRef as CharonTraitRef, TraitRefKind as CharonTraitRefKind, + 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::errors::{Error as CharonError, ErrorCtx as CharonErrorCtx}; use charon_lib::ids::Vector as CharonVector; @@ -52,7 +52,6 @@ use charon_lib::ullbc_ast::{ RawTerminator as CharonRawTerminator, Statement as CharonStatement, SwitchTargets as CharonSwitchTargets, Terminator as CharonTerminator, }; -use std::collections::HashMap; use charon_lib::{error_assert, error_or_panic}; use core::panic; use rustc_data_structures::fx::FxHashMap; @@ -65,9 +64,13 @@ use stable_mir::mir::{ TerminatorKind, UnOp, VarDebugInfoContents, }; use stable_mir::ty::{ - AdtDef, AdtKind, Allocation, ConstantKind, FnDef, GenericArgKind, GenericArgs, GenericParamDefKind, IndexedVal, IntTy, MirConst, Region, RegionKind, RigidTy, Span, TraitDecl, TraitDef, Ty, TyConst, TyConstKind, TyKind, UintTy + AdtDef, AdtKind, Allocation, ConstantKind, FnDef, GenericArgKind, GenericArgs, + GenericParamDefKind, IndexedVal, IntTy, MirConst, Region, RegionKind, RigidTy, Span, TraitDecl, + TraitDef, Ty, TyConst, TyConstKind, TyKind, UintTy, }; use stable_mir::{CrateDef, CrateDefType, DefId}; +use std::collections::HashMap; +use std::iter::zip; use std::path::PathBuf; use tracing::{debug, trace}; @@ -101,7 +104,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } } - Self { tcx, instance, translated, id_map, errors, local_names} + Self { tcx, instance, translated, id_map, errors, local_names } } fn tcx(&self) -> TyCtxt<'tcx> { @@ -122,7 +125,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let trait_decl_id = self.register_trait_decl_id(trait_def_id); match self.translated.trait_decls.get(trait_decl_id) { None => { - let trait_decl = TraitDef::declaration(&trait_def); + let trait_decl = TraitDef::declaration(&trait_def); let consts = Vec::new(); let const_defaults = HashMap::new(); let types = Vec::new(); @@ -131,7 +134,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let required_methods = Vec::new(); let provided_methods = Vec::new(); let parent_clauses = CharonVector::new(); - let c_traitdecl = CharonTraitDecl{ + let c_traitdecl = CharonTraitDecl { def_id: trait_decl_id, item_meta: self.translate_item_meta_from_defid(trait_def_id), generics: self.generic_params_from_traitdecl(trait_decl), @@ -142,75 +145,90 @@ impl<'a, 'tcx> Context<'a, 'tcx> { types, type_defaults, required_methods, - provided_methods, + provided_methods, }; self.translated.trait_decls.set_slot(trait_decl_id, c_traitdecl); - trait_decl_id - }, - Some(_) => trait_decl_id + trait_decl_id + } + Some(_) => trait_decl_id, } - } - - fn get_traitrefs_and_span_from_defid(&mut self, defid: DefId) -> (CharonVector, Vec){ - let inter_defid = rustc_internal::internal(self.tcx,defid); + fn get_traitrefs_and_span_from_defid( + &mut self, + defid: DefId, + ) -> (CharonVector, Vec) { + let inter_defid = rustc_internal::internal(self.tcx, defid); let predicates = self.tcx().predicates_of(inter_defid).predicates.to_vec(); - let mut c_trait_refs: CharonVector = CharonVector::new(); + let mut c_trait_refs: CharonVector = + CharonVector::new(); let mut c_spans = Vec::new(); - for (i,(clause, span)) in predicates.iter().enumerate() { + for (i, (clause, span)) in predicates.iter().enumerate() { let trait_clause = clause.as_trait_clause(); - if trait_clause.is_none() {continue}; + if trait_clause.is_none() { + continue; + }; let trait_id_internal = clause.as_trait_clause().unwrap(); let trait_binder = rustc_internal::stable(trait_id_internal); let trait_ref = trait_binder.value.trait_ref; let trait_def = trait_ref.def_id; - if self.is_marker_trait(trait_def) {continue}; + if self.is_marker_trait(trait_def) { + continue; + }; let c_traitdecl_id = self.translate_traitdecl(trait_def); let c_genarg = self.translate_generic_args_withouttrait(trait_ref.args().clone()); - let c_polytrait = CharonPolyTraitDeclRef{ + let c_polytrait = CharonPolyTraitDeclRef { regions: CharonVector::new(), - skip_binder : CharonTraitDeclRef {trait_id: c_traitdecl_id, generics: c_genarg.clone()}, + skip_binder: CharonTraitDeclRef { + trait_id: c_traitdecl_id, + generics: c_genarg.clone(), + }, }; let debr = CharonDeBruijnVar::free(CharonTraitClauseId::from_usize(i)); - let c_traitref = CharonTraitRef{ + let c_traitref = CharonTraitRef { kind: CharonTraitRefKind::Clause(debr), trait_decl_ref: c_polytrait, }; c_trait_refs.push(c_traitref); c_spans.push(self.translate_span(rustc_internal::stable(span))); - } + } (c_trait_refs, c_spans) } - fn get_traitclauses_from_defid(&mut self, defid: DefId) -> CharonVector{ - let inter_defid = rustc_internal::internal(self.tcx,defid); + fn get_traitclauses_from_defid( + &mut self, + defid: DefId, + ) -> CharonVector { + let inter_defid = rustc_internal::internal(self.tcx, defid); let predicates = self.tcx().predicates_of(inter_defid).predicates.to_vec(); - let mut c_trait_clauses: CharonVector = CharonVector::new(); - for (i,(clause, span)) in predicates.iter().enumerate() { + let mut c_trait_clauses: CharonVector = + CharonVector::new(); + for (i, (clause, span)) in predicates.iter().enumerate() { let trait_clause = clause.as_trait_clause(); - if trait_clause.is_none() {continue}; + if trait_clause.is_none() { + continue; + }; let trait_id_internal = clause.as_trait_clause().unwrap(); let trait_ref = rustc_internal::stable(trait_id_internal).value.trait_ref; let trait_def = trait_ref.def_id; - if self.is_marker_trait(trait_def) {continue}; + if self.is_marker_trait(trait_def) { + continue; + }; let c_traitdecl_id = self.translate_traitdecl(trait_def); let c_genarg = self.translate_generic_args_withouttrait(trait_ref.args().clone()); - let c_polytrait = CharonPolyTraitDeclRef{ + let c_polytrait = CharonPolyTraitDeclRef { regions: CharonVector::new(), - skip_binder : CharonTraitDeclRef {trait_id: c_traitdecl_id, generics: c_genarg}, + skip_binder: CharonTraitDeclRef { trait_id: c_traitdecl_id, generics: c_genarg }, }; - let c_traitclause = CharonTraitClause{ + let c_traitclause = CharonTraitClause { clause_id: CharonTraitClauseId::from_usize(i), span: Some(self.translate_span(rustc_internal::stable(span))), trait_: c_polytrait, - origin: CharonPredicateOrigin::WhereClauseOnType - + origin: CharonPredicateOrigin::WhereClauseOnType, }; c_trait_clauses.push(c_traitclause); + } - } - c_trait_clauses } @@ -240,7 +258,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { return Err(()); } }; - Ok(bodyid) + Ok(bodyid) }; let fun_decl = CharonFunDecl { def_id: fid, @@ -248,18 +266,13 @@ impl<'a, 'tcx> Context<'a, 'tcx> { signature, kind: CharonItemKind::Regular, body, - is_global_initializer :None - }; - match self.translated.fun_decls.get(fid) { - None => self.translated.fun_decls.set_slot(fid, fun_decl), - Some(_) => {}, + is_global_initializer: None, }; + if self.translated.fun_decls.get(fid).is_none() { self.translated.fun_decls.set_slot(fid, fun_decl) }; println!("Complete Func name: {:?}", funcname); Ok(()) - } - /// 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); @@ -367,35 +380,38 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let name = gendef.name.clone(); match genkind { GenericParamDefKind::Lifetime => { - let c_region = CharonRegionVar {index: CharonRegionId::from_usize(index), name: Some(name),}; - c_regions.push(c_region); - }, - GenericParamDefKind::Type{has_default : _, synthetic : _ } => { - let c_region = CharonTypeVar {index: CharonTypeVarId::from_usize(index) ,name}; + let c_region = CharonRegionVar { + index: CharonRegionId::from_usize(index), + name: Some(name), + }; + c_regions.push(c_region); + } + GenericParamDefKind::Type { has_default: _, synthetic: _ } => { + let c_region = + CharonTypeVar { index: CharonTypeVarId::from_usize(index), name }; c_types.push(c_region); - }, - GenericParamDefKind::Const{has_default: _} => { - let def_id_internal = rustc_internal::internal(self.tcx, gendef.def_id.0); - let pc_internal = rustc_middle::ty::ParamConst { - index : index as u32, - name: rustc_span::Symbol::intern(&name.clone()), - }; - let paramenv = - TypingEnv::post_analysis(self.tcx, def_id_internal).param_env; - 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_fndef: not a literal type"), - }; - let c_constgeneric = CharonConstGenericVar { - index: CharonConstGenericVarId::from_usize(index), - name, - ty: lit_ty, - }; - c_const_generics.push(c_constgeneric); - }, + } + GenericParamDefKind::Const { has_default: _ } => { + let def_id_internal = rustc_internal::internal(self.tcx, gendef.def_id.0); + let pc_internal = rustc_middle::ty::ParamConst { + index: index as u32, + name: rustc_span::Symbol::intern(&name.clone()), + }; + let paramenv = TypingEnv::post_analysis(self.tcx, def_id_internal).param_env; + 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_fndef: not a literal type"), + }; + let c_constgeneric = CharonConstGenericVar { + index: CharonConstGenericVarId::from_usize(index), + name, + ty: lit_ty, + }; + c_const_generics.push(c_constgeneric); + } } } CharonGenericParams { @@ -410,7 +426,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } fn generic_params_from_fndef(&mut self, fndef: FnDef, input: Vec) -> CharonGenericParams { - let genvec = match fndef.ty().kind(){ + let genvec = match fndef.ty().kind() { TyKind::RigidTy(RigidTy::FnDef(_, genarg)) => genarg.0, _ => panic!("generic_params_from_fndef: not an FnDef"), }; @@ -467,25 +483,18 @@ impl<'a, 'tcx> Context<'a, 'tcx> { }, } } - for inpty in input.iter(){ - match inpty.kind() { - TyKind::RigidTy(rty) => match rty { - RigidTy::Ref(r, _ , _ ) => match r.kind { - RegionKind::ReBound(_,br ) => { - let id =br.var as usize; - let c_region = CharonRegionVar { - index: CharonRegionId::from_usize(id), - name: None - }; - c_regions.push(c_region); - } - _ => (), + for inpty in input.iter() { + if let TyKind::RigidTy(RigidTy::Ref(r, _, _)) = inpty.kind() { + if let RegionKind::ReBound(_, br) = r.kind { + let id = br.var as usize; + let c_region = CharonRegionVar { + index: CharonRegionId::from_usize(id), + name: None, + }; + c_regions.push(c_region); } - _ => (), } - _ => (), - } - } + } let trait_clauses = self.get_traitclauses_from_defid(fndef.def_id()); CharonGenericParams { regions: c_regions, @@ -693,10 +702,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { Ok(CharonItemMeta { span, source_text, attr_info, name, is_local, opacity }) } - fn translate_item_meta_from_defid( - &mut self, - defid: DefId, - ) -> CharonItemMeta { + fn translate_item_meta_from_defid(&mut self, defid: DefId) -> CharonItemMeta { let def_id = rustc_internal::internal(self.tcx(), defid); let span = self.translate_span(rustc_internal::stable(self.tcx.def_span(def_id))); let name = self.defid_to_name(defid).unwrap(); @@ -737,30 +743,30 @@ impl<'a, 'tcx> Context<'a, 'tcx> { Ok(CharonItemMeta { span, source_text, attr_info, name, is_local, opacity }) } - - fn is_builtin_fun(&mut self, func_def: InstanceDef ) -> bool { + fn is_builtin_fun(&mut self, func_def: InstanceDef) -> bool { let name = self.def_to_name(func_def).unwrap(); - let crate_name = match name.name.get(0).unwrap() { - CharonPathElem::Ident(cn,_) => cn, + let crate_name = match name.name.first().unwrap() { + CharonPathElem::Ident(cn, _) => cn, _ => panic!("Imple name"), }; - crate_name.starts_with("std") || crate_name.starts_with("core") || crate_name.starts_with("alloc") + crate_name.starts_with("std") + || crate_name.starts_with("core") + || crate_name.starts_with("alloc") } - fn is_marker_trait(&mut self, traitdef: TraitDef ) -> bool { + fn is_marker_trait(&mut self, traitdef: TraitDef) -> bool { let name = self.defid_to_name(traitdef.def_id()).unwrap(); - let crate_name = match name.name.get(0).unwrap() { - CharonPathElem::Ident(cn,_) => cn, + let crate_name = match name.name.first().unwrap() { + CharonPathElem::Ident(cn, _) => cn, _ => panic!("Imple name"), }; let marker = match name.name.get(1).unwrap() { - CharonPathElem::Ident(cn,_) => cn, + CharonPathElem::Ident(cn, _) => cn, _ => panic!("Imple name"), }; - crate_name.starts_with("core") && marker.starts_with("marker") + crate_name.starts_with("core") && marker.starts_with("marker") } - fn defid_to_name(&mut self, defid: DefId) -> Result { let tcx = self.tcx(); let def_id = rustc_internal::internal(self.tcx(), defid); @@ -983,18 +989,20 @@ impl<'a, 'tcx> Context<'a, 'tcx> { name.push(CharonPathElem::Ident(crate_name, CharonDisambiguator::new(0))); } - let instancedef_internal = rustc_span::def_id::DefId::local(rustc_span::def_id::DefIndex::from_usize(def_id.index.as_usize())); + let instancedef_internal = rustc_span::def_id::DefId::local( + rustc_span::def_id::DefIndex::from_usize(def_id.index.as_usize()), + ); match self.tcx.impl_of_method(instancedef_internal) { Some(impl_defid_internal) => { let impl_defid = DefId::to_val(impl_defid_internal.index.as_usize()); - let impl_id =self.register_trait_impl_id(impl_defid); - let funcname =match name.pop().unwrap() { + let impl_id = self.register_trait_impl_id(impl_defid); + let funcname = match name.pop().unwrap() { CharonPathElem::Ident(name, _) => name + &impl_id.to_string(), - _ => panic!("Expected ident") + _ => panic!("Expected ident"), }; name.push(CharonPathElem::Ident(funcname, CharonDisambiguator::new(0))); } - None => {} + None => panic!("Expected impl"), }; trace!("{:?}", name); Ok(CharonName { name }) @@ -1095,14 +1103,14 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } fn file_to_id(&mut self, filename: &CharonFileName) -> Option { - for (id,file) in self.translated.files.iter().enumerate() { + for (id, file) in self.translated.files.iter().enumerate() { if file.name == *filename { - return Some(CharonFileId::from_usize(id)) + return Some(CharonFileId::from_usize(id)); } } None } - + /// Compute the span information for MIR span fn translate_span(&mut self, span: Span) -> CharonSpan { let filename = CharonFileName::Local(PathBuf::from(span.get_filename())); @@ -1110,8 +1118,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { Some(file_id) => file_id, None => { let file = CharonFile { name: filename.clone(), contents: None }; - let file_id = self.translated.files.push(file); - file_id + self.translated.files.push(file) } }; let lineinfo = span.get_lines(); @@ -1128,13 +1135,13 @@ impl<'a, 'tcx> Context<'a, 'tcx> { fn translate_function_signature(&mut self, instance: Instance) -> CharonFunSig { //let instance = self.instance; let fndef = match instance.ty().kind() { - TyKind::RigidTy(RigidTy::FnDef(fndef,_ )) => fndef, + TyKind::RigidTy(RigidTy::FnDef(fndef, _)) => fndef, _ => panic!("Expected a function type"), }; - //self.trait_clauses = c_genparam.trait_clauses.clone(); + //self.trait_clauses = c_genparam.trait_clauses.clone(); let value = fndef.fn_sig().value; let inputs = value.inputs().to_vec(); - let c_genparam = self.generic_params_from_fndef(fndef, inputs.clone()); + let c_genparam = self.generic_params_from_fndef(fndef, inputs.clone()); //println!("generic param {:?}", c_genparam.clone()); //println!("inp types {:?}", inputs.clone()); let c_inputs: Vec = inputs.iter().map(|ty| self.translate_ty(*ty)).collect(); @@ -1151,10 +1158,13 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } - fn translate_function_body(&mut self, instance: Instance) -> Result { + fn translate_function_body( + &mut self, + instance: Instance, + ) -> Result { //let instance = self.instance; let fndef = match instance.ty().kind() { - TyKind::RigidTy(RigidTy::FnDef(fndef,_ )) => fndef, + TyKind::RigidTy(RigidTy::FnDef(fndef, _)) => fndef, _ => panic!("Expected a function type"), }; let mir_body = fndef.body().unwrap(); @@ -1176,7 +1186,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonBody::Unstructured(body_expr) } - fn translate_generic_args(&mut self, ga: GenericArgs, defid: DefId) -> CharonGenericArgs { let genvec = ga.0; let mut c_regions: CharonVector = CharonVector::new(); @@ -1186,12 +1195,11 @@ impl<'a, 'tcx> Context<'a, 'tcx> { 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); @@ -1199,8 +1207,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { GenericArgKind::Const(tc) => { let c_const_generic = self.tyconst_to_constgeneric(tc); c_const_generics.push(c_const_generic); - } - //_ => (), + } //_ => (), } } let (gen_trait_refs, spans) = self.get_traitrefs_and_span_from_defid(defid); @@ -1210,13 +1217,14 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let traitgenarg = trait_ref.trait_decl_ref.skip_binder.generics.clone(); let t_regions: CharonVector = CharonVector::new(); let mut t_types: CharonVector = CharonVector::new(); - let t_const_generics: CharonVector = CharonVector::new(); - for tyvar in traitgenarg.types.iter(){ + let t_const_generics: CharonVector = + CharonVector::new(); + for tyvar in traitgenarg.types.iter() { match tyvar.kind() { CharonTyKind::TypeVar(dbtyvarid) => { - let tyvarid= match dbtyvarid { + let tyvarid = match dbtyvarid { CharonDeBruijnVar::Free(tyvarid) => *tyvarid, - _ => panic!("Expect free type var id") + _ => panic!("Expect free type var id"), }; let subs_ty = c_types.get(tyvarid).unwrap().clone(); t_types.push(subs_ty); @@ -1224,7 +1232,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { _ => todo!("TyKind of gen must be TyVar: {:?}", tyvar.kind()), } } - let generics= CharonGenericArgs { + let generics = CharonGenericArgs { regions: t_regions, types: t_types, const_generics: t_const_generics, @@ -1232,18 +1240,18 @@ impl<'a, 'tcx> Context<'a, 'tcx> { }; let traitdecl_id = trait_ref.trait_decl_ref.skip_binder.trait_id; let subs_traitdeclref = CharonPolyTraitDeclRef { - regions : trait_ref.trait_decl_ref.regions.clone(), - skip_binder : CharonTraitDeclRef { - trait_id: traitdecl_id.clone(), + regions: trait_ref.trait_decl_ref.regions.clone(), + skip_binder: CharonTraitDeclRef { + trait_id: traitdecl_id, generics: generics.clone(), }, }; let subs_traitref = CharonTraitRef { - kind : CharonTraitRefKind::BuiltinOrAuto(subs_traitdeclref.clone()), - trait_decl_ref: subs_traitdeclref + kind: CharonTraitRefKind::BuiltinOrAuto(subs_traitdeclref.clone()), + trait_decl_ref: subs_traitdeclref, }; trait_refs.push(subs_traitref); - } + } CharonGenericArgs { regions: c_regions, types: c_types, @@ -1287,10 +1295,11 @@ impl<'a, 'tcx> Context<'a, 'tcx> { match ty.kind() { TyKind::RigidTy(rigid_ty) => self.translate_rigid_ty(rigid_ty), TyKind::Param(paramty) => { - let debr = CharonDeBruijnVar::free(CharonTypeVarId::from_usize(paramty.index as usize)); + let debr = + CharonDeBruijnVar::free(CharonTypeVarId::from_usize(paramty.index as usize)); CharonTy::new(CharonTyKind::TypeVar(debr)) } - /* + /* TyKind::Alias(akind, atype) => { let tk_internal = rustc_internal::internal(self.tcx, ty).kind().clone(); match tk_internal { @@ -1322,7 +1331,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { translate_constant_expr_to_const_generic(c_raw_constexpr).unwrap() } TyConstKind::Param(paramc) => { - let debr = CharonDeBruijnVar::free(CharonConstGenericVarId::from_usize(paramc.index as usize)); + let debr = CharonDeBruijnVar::free(CharonConstGenericVarId::from_usize( + paramc.index as usize, + )); CharonConstGeneric::Var(debr) } _ => todo!(), @@ -1395,7 +1406,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { // TODO: populate regions? let rb = CharonRegionBinder { regions: CharonVector::new(), - skip_binder: (inputs, output) + skip_binder: (inputs, output), }; CharonTy::new(CharonTyKind::Arrow(rb)) } @@ -1427,15 +1438,18 @@ impl<'a, 'tcx> Context<'a, 'tcx> { RigidTy::FnPtr(polyfunsig) => { let value = polyfunsig.value; let inputs = value.inputs().to_vec(); - let c_inputs: Vec = inputs.iter().map(|ty| self.translate_ty(*ty)).collect(); + let c_inputs: Vec = + inputs.iter().map(|ty| self.translate_ty(*ty)).collect(); let c_output = self.translate_ty(value.output()); let rb = CharonRegionBinder { regions: CharonVector::new(), - skip_binder: (c_inputs, c_output) + skip_binder: (c_inputs, c_output), }; CharonTy::new(CharonTyKind::Arrow(rb)) } - RigidTy::Dynamic(_,_ ,_ ) => CharonTy::new(CharonTyKind::DynTrait(CharonExistentialPredicate)), + RigidTy::Dynamic(_, _, _) => { + CharonTy::new(CharonTyKind::DynTrait(CharonExistentialPredicate)) + } _ => todo!("Not yet implemented RigidTy: {:?}", rigid_ty), } } @@ -1519,18 +1533,18 @@ impl<'a, 'tcx> Context<'a, 'tcx> { TyKind::RigidTy(RigidTy::FnDef(def, genarg)) => { let instance = Instance::resolve(def, &genarg).unwrap(); let def_id = instance.def.def_id(); - let fid = self.register_fun_decl_id(def_id); + let fid = self.register_fun_decl_id(def_id); let genarg_resolve = match instance.ty().kind() { - TyKind::RigidTy(RigidTy::FnDef(_, ga )) => ga, + TyKind::RigidTy(RigidTy::FnDef(_, ga)) => ga, _ => panic!("Expected a function type"), - }; + }; let funcid = CharonFunIdOrTraitMethodRef::Fun(CharonFunId::Regular(fid)); let generics = self.translate_generic_args(genarg_resolve, def_id); println!("Func call genarg {:?}", generics); CharonFnPtr { func: funcid, // TODO: populate generics? - generics + generics, } } TyKind::RigidTy(RigidTy::FnPtr(..)) => todo!(), @@ -1635,7 +1649,8 @@ 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 = self.translate_generic_args(genarg, adt_def.def_id()); + let c_generic_args = + self.translate_generic_args(genarg, adt_def.def_id()); let c_agg_kind = CharonAggregateKind::Adt( c_type_id, c_variant_id, @@ -1650,7 +1665,8 @@ 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 = self.translate_generic_args(genarg, adt_def.def_id()); + let c_generic_args = + self.translate_generic_args(genarg, adt_def.def_id()); let c_agg_kind = CharonAggregateKind::Adt( c_type_id, c_variant_id, @@ -1714,7 +1730,10 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let defid = uc.def.def_id(); let c_defid = self.register_global_decl_id(defid); let c_genarg = self.translate_generic_args(uc.args.clone(), defid); - CharonRawConstantExpr::Global(CharonGlobalDeclRef{id: c_defid, generics: c_genarg}) + CharonRawConstantExpr::Global(CharonGlobalDeclRef { + id: c_defid, + generics: c_genarg, + }) } ConstantKind::Param(_) => todo!(), } @@ -1824,10 +1843,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { for prj in projection.iter() { match prj { ProjectionElem::Deref => { - match current_ty.kind() { - CharonTyKind::Ref(_,ty,_ , ) => current_ty = ty.clone(), - _ => (), - } + if let CharonTyKind::Ref(_, ty, _) = current_ty.kind() { current_ty = ty.clone() }; c_provec.push(CharonProjectionElem::Deref) } ProjectionElem::Field(fid, ty) => { @@ -1862,8 +1878,10 @@ impl<'a, 'tcx> Context<'a, 'tcx> { current_var = varid.to_index(); } ProjectionElem::Index(local) => { - let c_operand = - CharonOperand::Copy(CharonPlace::new(CharonVarId::from_usize(*local), current_ty.clone())); + let c_operand = CharonOperand::Copy(CharonPlace::new( + CharonVarId::from_usize(*local), + current_ty.clone(), + )); c_provec.push(CharonProjectionElem::Index { offset: Box::new(c_operand), from_end: false, @@ -1881,12 +1899,16 @@ impl<'a, 'tcx> Context<'a, 'tcx> { RegionKind::ReStatic => CharonRegion::Static, RegionKind::ReErased => CharonRegion::Erased, RegionKind::ReEarlyParam(_) => CharonRegion::Erased, - RegionKind::ReBound(var,boundregion) => //CharonRegion::Static, - { + RegionKind::ReBound(var, boundregion) => + //CharonRegion::Static, + { println!("region {:?}", boundregion.var.clone()); - let debr = CharonDeBruijnVar::bound(CharonDeBruijnId{index: var as usize}, CharonRegionId::from_usize(boundregion.var as usize)); + let debr = CharonDeBruijnVar::bound( + CharonDeBruijnId { index: var as usize }, + CharonRegionId::from_usize(boundregion.var as usize), + ); CharonRegion::Var(debr) - } + } RegionKind::RePlaceholder(_) => { todo!("Not yet implemented RegionKind: {:?}", region.kind) } From 0b7c527b1cc69d70873c1618a8a6e9642b358235 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Thu, 2 Jan 2025 09:11:45 -0800 Subject: [PATCH 32/51] update charon --- .../codegen_aeneas_llbc/compiler_interface.rs | 24 +++++++++++-------- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 24 +++++++++---------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs b/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs index 32c1a3cc9703..18b9583bc85b 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs @@ -35,7 +35,7 @@ use rustc_session::Session; use rustc_session::config::{CrateType, OutputFilenames, OutputType}; use rustc_session::output::out_filename; use rustc_smir::rustc_internal; -use stable_mir::mir::mono::{Instance, MonoItem}; +use stable_mir::mir::mono::{Instance, MonoItem, InstanceKind}; use stable_mir::{CrateDef, DefId}; use std::any::Any; use std::fs::File; @@ -109,16 +109,19 @@ impl LlbcCodegenBackend { // Translate all the items for item in &items { + println!("Translating: {item:?}"); match item { MonoItem::Fn(instance) => { - let mut fcx = Context::new( - tcx, - *instance, - &mut ccx.translated, - &mut id_map, - &mut ccx.errors, - ); - let _ = fcx.translate(); + if let InstanceKind::Item = instance.kind { + let mut fcx = Context::new( + tcx, + *instance, + &mut ccx.translated, + &mut id_map, + &mut ccx.errors, + ); + let _ = fcx.translate(); + } } MonoItem::Static(_def) => todo!(), MonoItem::GlobalAsm(_) => {} // We have already warned above @@ -392,7 +395,8 @@ fn create_charon_transformation_context(tcx: TyCtxt) -> TransformCtx { item_opacities: Vec::new(), }; let crate_name = tcx.crate_name(LOCAL_CRATE).as_str().into(); - let translated = TranslatedCrate { crate_name, ..TranslatedCrate::default() }; + let mut translated = TranslatedCrate { crate_name, ..TranslatedCrate::default() }; + translated.options.hide_marker_traits = true; let errors = ErrorCtx::new(true, false); TransformCtx { options, translated, errors } } 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 724c8d8b48aa..4df3dd8ec31b 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 @@ -992,17 +992,15 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let instancedef_internal = rustc_span::def_id::DefId::local( rustc_span::def_id::DefIndex::from_usize(def_id.index.as_usize()), ); - match self.tcx.impl_of_method(instancedef_internal) { - Some(impl_defid_internal) => { - let impl_defid = DefId::to_val(impl_defid_internal.index.as_usize()); - let impl_id = self.register_trait_impl_id(impl_defid); - let funcname = match name.pop().unwrap() { - CharonPathElem::Ident(name, _) => name + &impl_id.to_string(), - _ => panic!("Expected ident"), - }; - name.push(CharonPathElem::Ident(funcname, CharonDisambiguator::new(0))); - } - None => panic!("Expected impl"), + if let Some(impl_defid_internal) = self.tcx.impl_of_method(instancedef_internal) { + let impl_defid = DefId::to_val(impl_defid_internal.index.as_usize()); + let impl_id = self.register_trait_impl_id(impl_defid); + let funcname = match name.pop().unwrap() { + CharonPathElem::Ident(name, _) => name + &impl_id.to_string(), + _ => panic!("Expected ident"), + }; + name.push(CharonPathElem::Ident(funcname, CharonDisambiguator::new(0))); + }; trace!("{:?}", name); Ok(CharonName { name }) @@ -1296,7 +1294,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { TyKind::RigidTy(rigid_ty) => self.translate_rigid_ty(rigid_ty), TyKind::Param(paramty) => { let debr = - CharonDeBruijnVar::free(CharonTypeVarId::from_usize(paramty.index as usize)); + CharonDeBruijnVar::Bound(CharonDeBruijnId::new(0), CharonTypeVarId::from_usize(paramty.index as usize)); CharonTy::new(CharonTyKind::TypeVar(debr)) } /* @@ -1331,7 +1329,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { translate_constant_expr_to_const_generic(c_raw_constexpr).unwrap() } TyConstKind::Param(paramc) => { - let debr = CharonDeBruijnVar::free(CharonConstGenericVarId::from_usize( + let debr = CharonDeBruijnVar::Bound(CharonDeBruijnId::new(0),CharonConstGenericVarId::from_usize( paramc.index as usize, )); CharonConstGeneric::Var(debr) From d7c91f59146921b50c1f28678c696a7480121fe0 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Thu, 2 Jan 2025 09:40:40 -0800 Subject: [PATCH 33/51] update charon --- .../codegen_aeneas_llbc/compiler_interface.rs | 2 +- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 38 ++++++++++--------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs b/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs index 18b9583bc85b..0c7184284ec0 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs @@ -35,7 +35,7 @@ use rustc_session::Session; use rustc_session::config::{CrateType, OutputFilenames, OutputType}; use rustc_session::output::out_filename; use rustc_smir::rustc_internal; -use stable_mir::mir::mono::{Instance, MonoItem, InstanceKind}; +use stable_mir::mir::mono::{Instance, InstanceKind, MonoItem}; use stable_mir::{CrateDef, DefId}; use std::any::Any; use std::fs::File; 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 4df3dd8ec31b..418bb134a869 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 @@ -268,7 +268,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { body, is_global_initializer: None, }; - if self.translated.fun_decls.get(fid).is_none() { self.translated.fun_decls.set_slot(fid, fun_decl) }; + if self.translated.fun_decls.get(fid).is_none() { + self.translated.fun_decls.set_slot(fid, fun_decl) + }; println!("Complete Func name: {:?}", funcname); Ok(()) } @@ -484,17 +486,15 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } for inpty in input.iter() { - if let TyKind::RigidTy(RigidTy::Ref(r, _, _)) = inpty.kind() { + if let TyKind::RigidTy(RigidTy::Ref(r, _, _)) = inpty.kind() { if let RegionKind::ReBound(_, br) = r.kind { - let id = br.var as usize; - let c_region = CharonRegionVar { - index: CharonRegionId::from_usize(id), - name: None, - }; - c_regions.push(c_region); - } + let id = br.var as usize; + let c_region = + CharonRegionVar { index: CharonRegionId::from_usize(id), name: None }; + c_regions.push(c_region); } - } + } + } let trait_clauses = self.get_traitclauses_from_defid(fndef.def_id()); CharonGenericParams { regions: c_regions, @@ -1000,7 +1000,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { _ => panic!("Expected ident"), }; name.push(CharonPathElem::Ident(funcname, CharonDisambiguator::new(0))); - }; trace!("{:?}", name); Ok(CharonName { name }) @@ -1293,8 +1292,10 @@ impl<'a, 'tcx> Context<'a, 'tcx> { match ty.kind() { TyKind::RigidTy(rigid_ty) => self.translate_rigid_ty(rigid_ty), TyKind::Param(paramty) => { - let debr = - CharonDeBruijnVar::Bound(CharonDeBruijnId::new(0), CharonTypeVarId::from_usize(paramty.index as usize)); + let debr = CharonDeBruijnVar::Bound( + CharonDeBruijnId::new(0), + CharonTypeVarId::from_usize(paramty.index as usize), + ); CharonTy::new(CharonTyKind::TypeVar(debr)) } /* @@ -1329,9 +1330,10 @@ impl<'a, 'tcx> Context<'a, 'tcx> { translate_constant_expr_to_const_generic(c_raw_constexpr).unwrap() } TyConstKind::Param(paramc) => { - let debr = CharonDeBruijnVar::Bound(CharonDeBruijnId::new(0),CharonConstGenericVarId::from_usize( - paramc.index as usize, - )); + let debr = CharonDeBruijnVar::Bound( + CharonDeBruijnId::new(0), + CharonConstGenericVarId::from_usize(paramc.index as usize), + ); CharonConstGeneric::Var(debr) } _ => todo!(), @@ -1841,7 +1843,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { for prj in projection.iter() { match prj { ProjectionElem::Deref => { - if let CharonTyKind::Ref(_, ty, _) = current_ty.kind() { current_ty = ty.clone() }; + if let CharonTyKind::Ref(_, ty, _) = current_ty.kind() { + current_ty = ty.clone() + }; c_provec.push(CharonProjectionElem::Deref) } ProjectionElem::Field(fid, ty) => { From 215d11d5bbc5c145e6f5ab1f43b05957f03b7138 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Thu, 2 Jan 2025 10:14:58 -0800 Subject: [PATCH 34/51] fix small bugs --- .../src/codegen_aeneas_llbc/compiler_interface.rs | 4 +++- kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs b/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs index 0c7184284ec0..9d8b4986d5e6 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs @@ -106,10 +106,12 @@ impl LlbcCodegenBackend { // Create a Charon transformation context that will be populated with translation results let mut ccx = create_charon_transformation_context(tcx); let mut id_map: FxHashMap = FxHashMap::default(); + for item in &items { + println!("Translate {item:?}");} // Translate all the items for item in &items { - println!("Translating: {item:?}"); + //println!("Translating: {item:?}"); match item { MonoItem::Fn(instance) => { if let InstanceKind::Item = instance.kind { 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 418bb134a869..a0ff180c48d8 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 @@ -237,8 +237,13 @@ impl<'a, 'tcx> Context<'a, 'tcx> { // TODO: might want to populate `errors.dep_sources` to help with // debugging let instance_def = self.instance.def; + let is_builtin = self.is_builtin_fun(instance_def); + + println!("Func name: {:?}", self.instance.name()); let fid = self.register_fun_decl_id(self.instance.def.def_id()); + + let item_meta = match self.translate_item_meta_from_rid(self.instance) { Ok(item_meta) => item_meta, Err(_) => { @@ -246,8 +251,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } }; let funcname = item_meta.name.clone(); - println!("Func name: {:?}", funcname); - println!("Func def_id: {:?}", fid); let signature = self.translate_function_signature(self.instance); let body = if is_builtin { Err(CharonOpaque) From 5e3fd2370ba505d8c1b327298a622f17f58606e9 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Thu, 2 Jan 2025 14:11:39 -0800 Subject: [PATCH 35/51] save --- .../codegen_aeneas_llbc/compiler_interface.rs | 6 ++--- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 25 ++++++++++++++++--- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs b/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs index 9d8b4986d5e6..7f069261ce6d 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs @@ -106,15 +106,13 @@ impl LlbcCodegenBackend { // Create a Charon transformation context that will be populated with translation results let mut ccx = create_charon_transformation_context(tcx); let mut id_map: FxHashMap = FxHashMap::default(); - for item in &items { - println!("Translate {item:?}");} // Translate all the items for item in &items { //println!("Translating: {item:?}"); match item { MonoItem::Fn(instance) => { - if let InstanceKind::Item = instance.kind { + //if let InstanceKind::Item = instance.kind { let mut fcx = Context::new( tcx, *instance, @@ -123,7 +121,7 @@ impl LlbcCodegenBackend { &mut ccx.errors, ); let _ = fcx.translate(); - } + //} } MonoItem::Static(_def) => todo!(), MonoItem::GlobalAsm(_) => {} // We have already warned above 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 a0ff180c48d8..d49d083caa15 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 @@ -757,6 +757,17 @@ impl<'a, 'tcx> Context<'a, 'tcx> { || crate_name.starts_with("alloc") } + fn is_builtin_adt(&mut self, adtdef: AdtDef) -> bool { + let name = self.adtdef_to_name(adtdef).unwrap(); + let crate_name = match name.name.first().unwrap() { + CharonPathElem::Ident(cn, _) => cn, + _ => panic!("Imple name"), + }; + crate_name.starts_with("std") + || crate_name.starts_with("core") + || crate_name.starts_with("alloc") + } + fn is_marker_trait(&mut self, traitdef: TraitDef) -> bool { let name = self.defid_to_name(traitdef.def_id()).unwrap(); let crate_name = match name.name.first().unwrap() { @@ -992,9 +1003,12 @@ impl<'a, 'tcx> Context<'a, 'tcx> { name.push(CharonPathElem::Ident(crate_name, CharonDisambiguator::new(0))); } + let instancedef_internal = rustc_span::def_id::DefId::local( rustc_span::def_id::DefIndex::from_usize(def_id.index.as_usize()), ); + + //let impltrait = rustc_internal::internal(self.tcx, def_id); if let Some(impl_defid_internal) = self.tcx.impl_of_method(instancedef_internal) { let impl_defid = DefId::to_val(impl_defid_internal.index.as_usize()); let impl_id = self.register_trait_impl_id(impl_defid); @@ -1903,11 +1917,16 @@ impl<'a, 'tcx> Context<'a, 'tcx> { match region.kind { RegionKind::ReStatic => CharonRegion::Static, RegionKind::ReErased => CharonRegion::Erased, - RegionKind::ReEarlyParam(_) => CharonRegion::Erased, + RegionKind::ReEarlyParam(epr) => + { + let debr = CharonDeBruijnVar::bound( + CharonDeBruijnId { index: 0 as usize }, + CharonRegionId::from_usize(epr.index as usize), + ); + CharonRegion::Var(debr) + } RegionKind::ReBound(var, boundregion) => - //CharonRegion::Static, { - println!("region {:?}", boundregion.var.clone()); let debr = CharonDeBruijnVar::bound( CharonDeBruijnId { index: var as usize }, CharonRegionId::from_usize(boundregion.var as usize), From 103603f80381879e0e8d29ad88a65bcb4f52646c Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Fri, 3 Jan 2025 09:07:36 -0800 Subject: [PATCH 36/51] update projection --- .../codegen_aeneas_llbc/compiler_interface.rs | 2 - .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 37 ++++++++++--------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs b/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs index 7f069261ce6d..5448750a821d 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs @@ -112,7 +112,6 @@ impl LlbcCodegenBackend { //println!("Translating: {item:?}"); match item { MonoItem::Fn(instance) => { - //if let InstanceKind::Item = instance.kind { let mut fcx = Context::new( tcx, *instance, @@ -121,7 +120,6 @@ impl LlbcCodegenBackend { &mut ccx.errors, ); let _ = fcx.translate(); - //} } MonoItem::Static(_def) => todo!(), MonoItem::GlobalAsm(_) => {} // We have already warned above 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 d49d083caa15..7c9ac083dd4a 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 @@ -1002,18 +1002,13 @@ impl<'a, 'tcx> Context<'a, 'tcx> { if !found_crate_name { name.push(CharonPathElem::Ident(crate_name, CharonDisambiguator::new(0))); } - - - let instancedef_internal = rustc_span::def_id::DefId::local( - rustc_span::def_id::DefIndex::from_usize(def_id.index.as_usize()), - ); - //let impltrait = rustc_internal::internal(self.tcx, def_id); - if let Some(impl_defid_internal) = self.tcx.impl_of_method(instancedef_internal) { + if let Some(impl_defid_internal) = self.tcx.impl_of_method(def_id) { + let traitref = self.tcx.impl_trait_ref(impl_defid_internal).unwrap().skip_binder().args.first().unwrap().to_string(); let impl_defid = DefId::to_val(impl_defid_internal.index.as_usize()); let impl_id = self.register_trait_impl_id(impl_defid); let funcname = match name.pop().unwrap() { - CharonPathElem::Ident(name, _) => name + &impl_id.to_string(), + CharonPathElem::Ident(name, _) => name + traitref.as_str(), _ => panic!("Expected ident"), }; name.push(CharonPathElem::Ident(funcname, CharonDisambiguator::new(0))); @@ -1596,10 +1591,15 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } fn translate_place(&mut self, place: &Place) -> CharonPlace { - let (_projection, ty) = self.translate_projection(place, &place.projection); + let projection = self.translate_projection(place, &place.projection); let local = place.local; let var_id = CharonVarId::from_usize(local); - CharonPlace::new(var_id, ty) + let basetype = self.translate_ty(self.place_ty(&place)); + let mut prjplace = CharonPlace::new(var_id, basetype); + for (projelem, ty) in projection.iter() { + prjplace = prjplace.project(projelem.clone(), ty.clone()); + } + prjplace } fn place_ty(&self, place: &Place) -> Ty { @@ -1852,7 +1852,8 @@ impl<'a, 'tcx> Context<'a, 'tcx> { &mut self, place: &Place, projection: &[ProjectionElem], - ) -> (Vec, CharonTy) { + ) -> Vec<(CharonProjectionElem, CharonTy)> { + println!("translate_projection: {projection:?}"); 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(); @@ -1863,7 +1864,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { if let CharonTyKind::Ref(_, ty, _) = current_ty.kind() { current_ty = ty.clone() }; - c_provec.push(CharonProjectionElem::Deref) + c_provec.push((CharonProjectionElem::Deref, current_ty.clone())) } ProjectionElem::Field(fid, ty) => { let c_fieldid = CharonFieldId::from_usize(*fid); @@ -1874,21 +1875,21 @@ impl<'a, 'tcx> Context<'a, 'tcx> { match adttype.kind { CharonTypeDeclKind::Struct(_) => { let c_fprj = CharonFieldProjKind::Adt(*tdid, None); - c_provec.push(CharonProjectionElem::Field(c_fprj, c_fieldid)); current_ty = self.translate_ty(*ty); + c_provec.push((CharonProjectionElem::Field(c_fprj, c_fieldid), current_ty.clone())); } CharonTypeDeclKind::Enum(_) => { let c_fprj = CharonFieldProjKind::Adt(*tdid, Some(c_variantid)); - c_provec.push(CharonProjectionElem::Field(c_fprj, c_fieldid)); current_ty = self.translate_ty(*ty); + c_provec.push((CharonProjectionElem::Field(c_fprj, c_fieldid), current_ty.clone())); } _ => (), } } CharonTyKind::Adt(CharonTypeId::Tuple, genargs) => { let c_fprj = CharonFieldProjKind::Tuple(genargs.types.len()); - c_provec.push(CharonProjectionElem::Field(c_fprj, c_fieldid)); current_ty = self.translate_ty(*ty); + c_provec.push((CharonProjectionElem::Field(c_fprj, c_fieldid), current_ty.clone())); } _ => (), } @@ -1901,16 +1902,16 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonVarId::from_usize(*local), current_ty.clone(), )); - c_provec.push(CharonProjectionElem::Index { + c_provec.push((CharonProjectionElem::Index { offset: Box::new(c_operand), from_end: false, - }); + }, current_ty.clone())); } _ => continue, } } - (c_provec, current_ty) + c_provec } fn translate_region(&self, region: Region) -> CharonRegion { From f5853698ce33e9d8e1616d9e61bff2d2ff546d15 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Fri, 3 Jan 2025 12:05:04 -0800 Subject: [PATCH 37/51] fixed println --- Cargo.lock | 35 ++--- .../codegen_aeneas_llbc/compiler_interface.rs | 18 +-- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 122 +++++++----------- 3 files changed, 62 insertions(+), 113 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cd4b04fafde1..ef90c014f97a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -164,9 +164,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.11.2" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c94feba04f99cbce6558bbe1c18e38692a056981cb66c96f0878c2452aa28023" +checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" dependencies = [ "memchr", "regex-automata 0.4.9", @@ -229,9 +229,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.6" +version = "1.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" +checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" dependencies = [ "shlex", ] @@ -524,30 +524,18 @@ dependencies = [ [[package]] name = "derive_generic_visitor" -<<<<<<< HEAD -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0729a8f5d509da0c280502837a56a9d05c16866ae5b608ef34bd687e9f21af8" -======= version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3e1c241e4f464b614bd7650f1a7c4c0e20e5ef21564d6b916b4c51fd76f7688" ->>>>>>> origin dependencies = [ "derive_generic_visitor_macros", ] [[package]] name = "derive_generic_visitor_macros" -<<<<<<< HEAD -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c2b7f15bf93ca0d978ecb96792c71a43c629a1e18b2a5de7a35a5d218e6c85e" -======= version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "885f5274163b5b1720591c0c24b34350a0b05e4774351f9fb3d13c192d8c995b" ->>>>>>> origin dependencies = [ "convert_case", "darling", @@ -1680,15 +1668,9 @@ dependencies = [ [[package]] name = "syn" -<<<<<<< HEAD -version = "2.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" -======= version = "2.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "987bc0be1cdea8b10216bd06e2ca407d40b9543468fafd3ddfb02f36e77f71f3" ->>>>>>> origin dependencies = [ "proc-macro2", "quote", @@ -1703,12 +1685,13 @@ checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" [[package]] name = "tempfile" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" dependencies = [ "cfg-if", "fastrand", + "getrandom", "once_cell", "rustix", "windows-sys 0.59.0", @@ -2189,9 +2172,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.21" +version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f5bb5257f2407a5425c6e749bfd9692192a73e70a6060516ac04f889087d68" +checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980" dependencies = [ "memchr", ] diff --git a/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs b/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs index 5448750a821d..35cecc575ece 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs @@ -35,7 +35,7 @@ use rustc_session::Session; use rustc_session::config::{CrateType, OutputFilenames, OutputType}; use rustc_session::output::out_filename; use rustc_smir::rustc_internal; -use stable_mir::mir::mono::{Instance, InstanceKind, MonoItem}; +use stable_mir::mir::mono::{Instance, MonoItem}; use stable_mir::{CrateDef, DefId}; use std::any::Any; use std::fs::File; @@ -112,14 +112,14 @@ impl LlbcCodegenBackend { //println!("Translating: {item:?}"); match item { MonoItem::Fn(instance) => { - let mut fcx = Context::new( - tcx, - *instance, - &mut ccx.translated, - &mut id_map, - &mut ccx.errors, - ); - let _ = fcx.translate(); + let mut fcx = Context::new( + tcx, + *instance, + &mut ccx.translated, + &mut id_map, + &mut ccx.errors, + ); + let _ = fcx.translate(); } MonoItem::Static(_def) => todo!(), MonoItem::GlobalAsm(_) => {} // We have already warned above 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 a1d0cf1b4850..9244e62c3e59 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 @@ -123,7 +123,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { fn translate_traitdecl(&mut self, trait_def: TraitDef) -> CharonTraitDeclId { let trait_def_id = trait_def.def_id(); - //println!("Trait name {:?}", self.defid_to_name(trait_def_id)); let trait_decl_id = self.register_trait_decl_id(trait_def_id); match self.translated.trait_decls.get(trait_decl_id) { None => { @@ -178,7 +177,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { continue; }; let c_traitdecl_id = self.translate_traitdecl(trait_def); - let c_genarg = self.translate_generic_args_withouttrait(trait_ref.args().clone()); + let c_genarg = self.translate_generic_args_without_trait(trait_ref.args().clone()); let c_polytrait = CharonPolyTraitDeclRef { regions: CharonVector::new(), skip_binder: CharonTraitDeclRef { @@ -217,7 +216,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { continue; }; let c_traitdecl_id = self.translate_traitdecl(trait_def); - let c_genarg = self.translate_generic_args_withouttrait(trait_ref.args().clone()); + let c_genarg = self.translate_generic_args_without_trait(trait_ref.args().clone()); let c_polytrait = CharonPolyTraitDeclRef { regions: CharonVector::new(), skip_binder: CharonTraitDeclRef { trait_id: c_traitdecl_id, generics: c_genarg }, @@ -242,10 +241,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let is_builtin = self.is_builtin_fun(instance_def); - println!("Func name: {:?}", self.instance.name()); + debug!("Func name: {:?}", self.instance.name()); let fid = self.register_fun_decl_id(self.instance.def.def_id()); - let item_meta = match self.translate_item_meta_from_rid(self.instance) { Ok(item_meta) => item_meta, Err(_) => { @@ -271,12 +269,12 @@ impl<'a, 'tcx> Context<'a, 'tcx> { signature, kind: CharonItemKind::Regular, is_global_initializer: None, - body: Ok(body), + body, }; if self.translated.fun_decls.get(fid).is_none() { self.translated.fun_decls.set_slot(fid, fun_decl) }; - println!("Complete Func name: {:?}", funcname); + debug!("Complete Func name: {:?}", funcname); Ok(()) } @@ -330,7 +328,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } fn register_trait_impl_id(&mut self, def_id: DefId) -> CharonTraitImplId { - debug!("register_trait_decl_id: {:?}", def_id); + debug!("register_trait_impl_id: {:?}", def_id); let tid = match self.id_map.get(&def_id) { Some(tid) => *tid, None => { @@ -341,12 +339,12 @@ impl<'a, 'tcx> Context<'a, 'tcx> { tid } }; - debug!("register_trait_decl_id: {:?}", self.id_map); + debug!("register_trait_impl_id: {:?}", self.id_map); tid.try_into().unwrap() } fn register_global_decl_id(&mut self, def_id: DefId) -> CharonGlobalDeclId { - debug!("register_trait_decl_id: {:?}", def_id); + debug!("register_global_decl_id: {:?}", def_id); let tid = match self.id_map.get(&def_id) { Some(tid) => *tid, None => { @@ -759,17 +757,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { || crate_name.starts_with("alloc") } - fn is_builtin_adt(&mut self, adtdef: AdtDef) -> bool { - let name = self.adtdef_to_name(adtdef).unwrap(); - let crate_name = match name.name.first().unwrap() { - CharonPathElem::Ident(cn, _) => cn, - _ => panic!("Imple name"), - }; - crate_name.starts_with("std") - || crate_name.starts_with("core") - || crate_name.starts_with("alloc") - } - fn is_marker_trait(&mut self, traitdef: TraitDef) -> bool { let name = self.defid_to_name(traitdef.def_id()).unwrap(); let crate_name = match name.name.first().unwrap() { @@ -1004,11 +991,19 @@ impl<'a, 'tcx> Context<'a, 'tcx> { if !found_crate_name { name.push(CharonPathElem::Ident(crate_name, CharonDisambiguator::new(0))); } - + if let Some(impl_defid_internal) = self.tcx.impl_of_method(def_id) { - let traitref = self.tcx.impl_trait_ref(impl_defid_internal).unwrap().skip_binder().args.first().unwrap().to_string(); + let traitref = self + .tcx + .impl_trait_ref(impl_defid_internal) + .unwrap() + .skip_binder() + .args + .first() + .unwrap() + .to_string(); let impl_defid = DefId::to_val(impl_defid_internal.index.as_usize()); - let impl_id = self.register_trait_impl_id(impl_defid); + let _impl_id = self.register_trait_impl_id(impl_defid); let funcname = match name.pop().unwrap() { CharonPathElem::Ident(name, _) => name + traitref.as_str(), _ => panic!("Expected ident"), @@ -1113,15 +1108,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { self.translate_span(instance.def.span()) } - fn file_to_id(&mut self, filename: &CharonFileName) -> Option { - for (id, file) in self.translated.files.iter().enumerate() { - if file.name == *filename { - return Some(CharonFileId::from_usize(id)); - } - } - None - } - /// Compute the span information for MIR span fn translate_span(&mut self, span: Span) -> CharonSpan { let filename = CharonFileName::Local(PathBuf::from(span.get_filename())); @@ -1146,19 +1132,14 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } fn translate_function_signature(&mut self, instance: Instance) -> CharonFunSig { - //let instance = self.instance; let fndef = match instance.ty().kind() { TyKind::RigidTy(RigidTy::FnDef(fndef, _)) => fndef, _ => panic!("Expected a function type"), }; - //self.trait_clauses = c_genparam.trait_clauses.clone(); let value = fndef.fn_sig().value; let inputs = value.inputs().to_vec(); let c_genparam = self.generic_params_from_fndef(fndef, inputs.clone()); - //println!("generic param {:?}", c_genparam.clone()); - //println!("inp types {:?}", inputs.clone()); let c_inputs: Vec = inputs.iter().map(|ty| self.translate_ty(*ty)).collect(); - //println!("trans input type{:?}", c_inputs.clone()); let c_output = self.translate_ty(value.output()); // TODO: populate the rest of the information (`is_unsafe`, `is_closure`, etc.) CharonFunSig { @@ -1175,7 +1156,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { &mut self, instance: Instance, ) -> Result { - //let instance = self.instance; let fndef = match instance.ty().kind() { TyKind::RigidTy(RigidTy::FnDef(fndef, _)) => fndef, _ => panic!("Expected a function type"), @@ -1273,7 +1253,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } - fn translate_generic_args_withouttrait(&mut self, ga: GenericArgs) -> CharonGenericArgs { + fn translate_generic_args_without_trait(&mut self, ga: GenericArgs) -> CharonGenericArgs { let genvec = ga.0; let mut c_regions: CharonVector = CharonVector::new(); let mut c_types: CharonVector = CharonVector::new(); @@ -1314,27 +1294,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { ); CharonTy::new(CharonTyKind::TypeVar(debr)) } - /* - TyKind::Alias(akind, atype) => { - let tk_internal = rustc_internal::internal(self.tcx, ty).kind().clone(); - match tk_internal { - rustc_middle::ty::TyKind::Alias(akind,aty ) =>{ - match akind { - rustc_middle::ty::AliasTyKind::Opaque => { - let hiddentype = rustc_internal::stable(aty.to_ty(self.tcx)); - self.translate_ty(hiddentype) - } - rustc_middle::ty::AliasTyKind::Projection => { - let trait_ref = rustc_internal::stable(aty.trait_ref(self.tcx)); - - } - _ => panic - } - } - _=> panic - } - - }*/ x => todo!("Not yet implemented translation for TyKind: {:?}", x), } } @@ -1543,7 +1502,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } TerminatorKind::Call { func, args, destination, target, .. } => { debug!("translate_call: {func:?} {args:?} {destination:?} {target:?}"); - println!("Calling {:?}", func); let fn_ty = func.ty(self.instance.body().unwrap().locals()).unwrap(); let fn_ptr = match fn_ty.kind() { TyKind::RigidTy(RigidTy::FnDef(def, genarg)) => { @@ -1556,7 +1514,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { }; let funcid = CharonFunIdOrTraitMethodRef::Fun(CharonFunId::Regular(fid)); let generics = self.translate_generic_args(genarg_resolve, def_id); - println!("Func call genarg {:?}", generics); CharonFnPtr { func: funcid, // TODO: populate generics? @@ -1595,10 +1552,10 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } fn translate_place(&mut self, place: &Place) -> CharonPlace { - let (_projection, ty) = self.translate_projection(place, &place.projection); + let projection = self.translate_projection(place, &place.projection); let local = place.local; let var_id = CharonVarId::from_usize(local); - let basetype = self.translate_ty(self.place_ty(&place)); + let basetype = self.translate_ty(self.place_ty(&place)); let mut prjplace = CharonPlace::new(var_id, basetype); for (projelem, ty) in projection.iter() { prjplace = prjplace.project(projelem.clone(), ty.clone()); @@ -1857,7 +1814,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { place: &Place, projection: &[ProjectionElem], ) -> Vec<(CharonProjectionElem, CharonTy)> { - println!("translate_projection: {projection:?}"); 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(); @@ -1880,12 +1836,18 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonTypeDeclKind::Struct(_) => { let c_fprj = CharonFieldProjKind::Adt(*tdid, None); current_ty = self.translate_ty(*ty); - c_provec.push((CharonProjectionElem::Field(c_fprj, c_fieldid), current_ty.clone())); + c_provec.push(( + CharonProjectionElem::Field(c_fprj, c_fieldid), + current_ty.clone(), + )); } CharonTypeDeclKind::Enum(_) => { let c_fprj = CharonFieldProjKind::Adt(*tdid, Some(c_variantid)); current_ty = self.translate_ty(*ty); - c_provec.push((CharonProjectionElem::Field(c_fprj, c_fieldid), current_ty.clone())); + c_provec.push(( + CharonProjectionElem::Field(c_fprj, c_fieldid), + current_ty.clone(), + )); } _ => (), } @@ -1893,7 +1855,10 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonTyKind::Adt(CharonTypeId::Tuple, genargs) => { let c_fprj = CharonFieldProjKind::Tuple(genargs.types.len()); current_ty = self.translate_ty(*ty); - c_provec.push((CharonProjectionElem::Field(c_fprj, c_fieldid), current_ty.clone())); + c_provec.push(( + CharonProjectionElem::Field(c_fprj, c_fieldid), + current_ty.clone(), + )); } _ => (), } @@ -1906,32 +1871,33 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonVarId::from_usize(*local), current_ty.clone(), )); - c_provec.push((CharonProjectionElem::Index { - offset: Box::new(c_operand), - from_end: false, - }, current_ty.clone())); + c_provec.push(( + CharonProjectionElem::Index { + offset: Box::new(c_operand), + from_end: false, + }, + current_ty.clone(), + )); } _ => continue, } } - (c_provec, current_ty) + c_provec } fn translate_region(&self, region: Region) -> CharonRegion { match region.kind { RegionKind::ReStatic => CharonRegion::Static, RegionKind::ReErased => CharonRegion::Erased, - RegionKind::ReEarlyParam(epr) => - { + RegionKind::ReEarlyParam(epr) => { let debr = CharonDeBruijnVar::bound( CharonDeBruijnId { index: 0 as usize }, CharonRegionId::from_usize(epr.index as usize), ); CharonRegion::Var(debr) } - RegionKind::ReBound(var, boundregion) => - { + RegionKind::ReBound(var, boundregion) => { let debr = CharonDeBruijnVar::bound( CharonDeBruijnId { index: var as usize }, CharonRegionId::from_usize(boundregion.var as usize), From f336b0a722fd63b4e8d88bddefbaa61fcb86b578 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Fri, 3 Jan 2025 13:33:33 -0800 Subject: [PATCH 38/51] adding an expected test for trait --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 18 +++---- tests/expected/llbc/traitimpl/expected | 53 +++++++++++++++++++ tests/expected/llbc/traitimpl/test.rs | 36 +++++++++++++ 3 files changed, 98 insertions(+), 9 deletions(-) create mode 100644 tests/expected/llbc/traitimpl/expected create mode 100644 tests/expected/llbc/traitimpl/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 9244e62c3e59..b7725f2d752e 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 @@ -284,7 +284,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let tid = match self.id_map.get(&def_id) { Some(tid) => *tid, None => { - debug!("***Not found!"); + debug!("***Not found fun_decl_id!"); let tid = CharonAnyTransId::Fun(self.translated.fun_decls.reserve_slot()); self.id_map.insert(def_id, tid); self.translated.all_ids.insert(tid); @@ -300,7 +300,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let tid = match self.id_map.get(&def_id) { Some(tid) => *tid, None => { - debug!("***Not found!"); + debug!("***Not found type_decl_id!"); let tid = CharonAnyTransId::Type(self.translated.type_decls.reserve_slot()); self.id_map.insert(def_id, tid); self.translated.all_ids.insert(tid); @@ -316,7 +316,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let tid = match self.id_map.get(&def_id) { Some(tid) => *tid, None => { - debug!("***Not found!"); + debug!("***Not found trait_decl_id!"); let tid = CharonAnyTransId::TraitDecl(self.translated.trait_decls.reserve_slot()); self.id_map.insert(def_id, tid); self.translated.all_ids.insert(tid); @@ -332,7 +332,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let tid = match self.id_map.get(&def_id) { Some(tid) => *tid, None => { - debug!("***Not found!"); + debug!("***Not found trait_impl_id!"); let tid = CharonAnyTransId::TraitImpl(self.translated.trait_impls.reserve_slot()); self.id_map.insert(def_id, tid); self.translated.all_ids.insert(tid); @@ -348,7 +348,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let tid = match self.id_map.get(&def_id) { Some(tid) => *tid, None => { - debug!("***Not found!"); + debug!("***Not found global_decl_id!"); let tid = CharonAnyTransId::Global(self.translated.global_decls.reserve_slot()); self.id_map.insert(def_id, tid); self.translated.all_ids.insert(tid); @@ -750,7 +750,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let name = self.def_to_name(func_def).unwrap(); let crate_name = match name.name.first().unwrap() { CharonPathElem::Ident(cn, _) => cn, - _ => panic!("Imple name"), + _ => panic!("Expected function name"), }; crate_name.starts_with("std") || crate_name.starts_with("core") @@ -761,11 +761,11 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let name = self.defid_to_name(traitdef.def_id()).unwrap(); let crate_name = match name.name.first().unwrap() { CharonPathElem::Ident(cn, _) => cn, - _ => panic!("Imple name"), + _ => panic!("Expected crate name"), }; let marker = match name.name.get(1).unwrap() { CharonPathElem::Ident(cn, _) => cn, - _ => panic!("Imple name"), + _ => panic!("Expected trait name"), }; crate_name.starts_with("core") && marker.starts_with("marker") } @@ -1892,7 +1892,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { RegionKind::ReErased => CharonRegion::Erased, RegionKind::ReEarlyParam(epr) => { let debr = CharonDeBruijnVar::bound( - CharonDeBruijnId { index: 0 as usize }, + CharonDeBruijnId { index: 0_usize }, CharonRegionId::from_usize(epr.index as usize), ); CharonRegion::Var(debr) diff --git a/tests/expected/llbc/traitimpl/expected b/tests/expected/llbc/traitimpl/expected new file mode 100644 index 000000000000..a4c6d32f3b3d --- /dev/null +++ b/tests/expected/llbc/traitimpl/expected @@ -0,0 +1,53 @@ +struct main::B = +{ + index: i32, +} + +fn main::get_valB<'_0>(@1: &'_0 (@Adt0)) -> i32 +{ + let @0: i32; // return + let self@1: &'_ (@Adt0); // arg #1 + + @0 := copy ((*(self@1)).index) + return +} + +struct main::A = +{ + val: i32, +} + +fn main::get_valA<'_0>(@1: &'_0 (@Adt1)) -> i32 +{ + let @0: i32; // return + let self@1: &'_ (@Adt1); // arg #1 + + @0 := copy ((*(self@1)).val) + return +} + +fn main::main() +{ + let @0: (); // return + let e@1: @Adt1; // local + let k@2: @Adt0; // local + let i@3: i32; // local + let @4: &'_ (@Adt1); // anonymous local + let j@5: i32; // local + let @6: &'_ (@Adt0); // anonymous local + + e@1 := @Adt1 { val: const (3 : i32) } + k@2 := @Adt0 { index: const (3 : i32) } + @4 := &e@1 + i@3 := @Fun2(move (@4)) + drop @4 + @6 := &k@2 + j@5 := @Fun0(move (@6)) + drop @6 + drop j@5 + drop i@3 + drop k@2 + drop e@1 + @0 := () + return +} diff --git a/tests/expected/llbc/traitimpl/test.rs b/tests/expected/llbc/traitimpl/test.rs new file mode 100644 index 000000000000..20a7907d4fda --- /dev/null +++ b/tests/expected/llbc/traitimpl/test.rs @@ -0,0 +1,36 @@ +// 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 trait impl + +trait T { + fn get_val(&self) -> i32; +} +struct A { + val: i32, +} + +struct B { + index: i32, +} + +impl T for A { + fn get_val(&self) -> i32 { + self.val + } +} + +impl T for B { + fn get_val(&self) -> i32 { + self.index + } +} + +#[kani::proof] +fn main() { + let e = A { val: 3 }; + let k = B { index: 3 }; + let i = e.get_val(); + let j = k.get_val(); +} From 53983dd82eb7808ba6654654cae6805e75e9f3ef Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Fri, 3 Jan 2025 14:17:02 -0800 Subject: [PATCH 39/51] fixed the test --- tests/expected/llbc/traitimpl/expected | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/expected/llbc/traitimpl/expected b/tests/expected/llbc/traitimpl/expected index a4c6d32f3b3d..b45e1bb15c3a 100644 --- a/tests/expected/llbc/traitimpl/expected +++ b/tests/expected/llbc/traitimpl/expected @@ -1,9 +1,9 @@ -struct main::B = +struct test::B = { index: i32, } -fn main::get_valB<'_0>(@1: &'_0 (@Adt0)) -> i32 +fn test::get_valB<'_0>(@1: &'_0 (@Adt0)) -> i32 { let @0: i32; // return let self@1: &'_ (@Adt0); // arg #1 @@ -12,12 +12,12 @@ fn main::get_valB<'_0>(@1: &'_0 (@Adt0)) -> i32 return } -struct main::A = +struct test::A = { val: i32, } -fn main::get_valA<'_0>(@1: &'_0 (@Adt1)) -> i32 +fn test::get_valA<'_0>(@1: &'_0 (@Adt1)) -> i32 { let @0: i32; // return let self@1: &'_ (@Adt1); // arg #1 @@ -26,7 +26,7 @@ fn main::get_valA<'_0>(@1: &'_0 (@Adt1)) -> i32 return } -fn main::main() +fn test::main() { let @0: (); // return let e@1: @Adt1; // local From 3bc4e6d9e2116ea7605027d658e6385f982d18cd Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 6 Jan 2025 09:08:31 -0800 Subject: [PATCH 40/51] fix some comments --- kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 6 +----- 1 file changed, 1 insertion(+), 5 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 b7725f2d752e..895ba377d863 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 @@ -1514,11 +1514,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { }; let funcid = CharonFunIdOrTraitMethodRef::Fun(CharonFunId::Regular(fid)); let generics = self.translate_generic_args(genarg_resolve, def_id); - CharonFnPtr { - func: funcid, - // TODO: populate generics? - generics, - } + CharonFnPtr { func: funcid, generics } } TyKind::RigidTy(RigidTy::FnPtr(..)) => todo!(), x => unreachable!( From 7d28582efda19daa30485f93c18e697395ccc709 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Tue, 7 Jan 2025 11:34:55 -0800 Subject: [PATCH 41/51] add comments --- .../src/codegen_aeneas_llbc/compiler_interface.rs | 3 ++- kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 8 +++++++- tests/perf/s2n-quic | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs b/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs index 35cecc575ece..6fc462cbd42d 100644 --- a/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs +++ b/kani-compiler/src/codegen_aeneas_llbc/compiler_interface.rs @@ -109,7 +109,7 @@ impl LlbcCodegenBackend { // Translate all the items for item in &items { - //println!("Translating: {item:?}"); + debug!("Translating: {item:?}"); match item { MonoItem::Fn(instance) => { let mut fcx = Context::new( @@ -394,6 +394,7 @@ fn create_charon_transformation_context(tcx: TyCtxt) -> TransformCtx { }; let crate_name = tcx.crate_name(LOCAL_CRATE).as_str().into(); let mut translated = TranslatedCrate { crate_name, ..TranslatedCrate::default() }; + //This option setting is for Aeneas compatibility translated.options.hide_marker_traits = true; let errors = ErrorCtx::new(true, false); TransformCtx { options, translated, errors } 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 895ba377d863..ce80ffcbe02e 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 @@ -155,6 +155,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } + //This function extract the traitrefs and their span from a def_id + //Those information will be added into that def_id's generic args + //Note that Generic args of Charon contains trait_refs while those of stable_mir do not fn get_traitrefs_and_span_from_defid( &mut self, defid: DefId, @@ -373,6 +376,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { CharonScalarValue::from_bits(int_ty, discr_val) } + //Get the GenericParams for Trait Decl, which is neccessary in Trait Decl translation fn generic_params_from_traitdecl(&mut self, traitdecl: TraitDecl) -> CharonGenericParams { let genvec = traitdecl.generics_of().params; let mut c_regions: CharonVector = CharonVector::new(); @@ -430,6 +434,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } + //Get the GenericParams for Func Decl, which is neccessary in Func Decl translation fn generic_params_from_fndef(&mut self, fndef: FnDef, input: Vec) -> CharonGenericParams { let genvec = match fndef.ty().kind() { TyKind::RigidTy(RigidTy::FnDef(_, genarg)) => genarg.0, @@ -510,6 +515,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } + //Get the GenericParams for Adt Decl, which is neccessary in Adt Decl translation fn generic_params_from_adtdef(&mut self, adtdef: AdtDef) -> CharonGenericParams { let genvec = match adtdef.ty().kind() { TyKind::RigidTy(RigidTy::Adt(_, genarg)) => genarg.0, @@ -1747,7 +1753,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { let value = char::from_u32(alloc.read_uint().unwrap() as u32); CharonRawConstantExpr::Literal(CharonLiteral::Char(value.unwrap())) } - _ => todo!(), + _ => todo!("Not yet implement {:?}, {:?}", ty, alloc), } } diff --git a/tests/perf/s2n-quic b/tests/perf/s2n-quic index ac52a4805a62..a54686e4e1da 160000 --- a/tests/perf/s2n-quic +++ b/tests/perf/s2n-quic @@ -1 +1 @@ -Subproject commit ac52a4805a62ca4c7c9d1c17e86ba41c2afd308f +Subproject commit a54686e4e1daad2afbbc01fccaf4cc1a512c58bf From 54598100012529dff0cd0fdd655394d5967af19e Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Tue, 7 Jan 2025 11:43:19 -0800 Subject: [PATCH 42/51] add more comments --- kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 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 ce80ffcbe02e..74412d823859 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 @@ -156,7 +156,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } //This function extract the traitrefs and their span from a def_id - //Those information will be added into that def_id's generic args + //Those information will be added into generic args of the type or the func with the def_id //Note that Generic args of Charon contains trait_refs while those of stable_mir do not fn get_traitrefs_and_span_from_defid( &mut self, @@ -199,6 +199,8 @@ impl<'a, 'tcx> Context<'a, 'tcx> { (c_trait_refs, c_spans) } + //Get the trait clauses of an Adt or a Func from their def_id + //Those information will be added into GenericParams of the Type Decl or Func Decl fn get_traitclauses_from_defid( &mut self, defid: DefId, @@ -370,6 +372,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { tid.try_into().unwrap() } + //This function is implemented accordingto how Charon encode discriminant 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(); @@ -1565,6 +1568,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { prjplace } + //Get the Ty of the Place fn place_ty(&self, place: &Place) -> Ty { let body = self.instance.body().unwrap(); let ty = body.local_decl(place.local).unwrap().ty; From 1efa472886605f7a90ba6ffcd137132af8477472 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Tue, 7 Jan 2025 11:47:46 -0800 Subject: [PATCH 43/51] formating --- kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 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 74412d823859..d9b362ff230d 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 @@ -157,7 +157,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { //This function extract the traitrefs and their span from a def_id //Those information will be added into generic args of the type or the func with the def_id - //Note that Generic args of Charon contains trait_refs while those of stable_mir do not + //Note that Generic args of Charon contains trait_refs while those of stable_mir do not fn get_traitrefs_and_span_from_defid( &mut self, defid: DefId, @@ -1201,7 +1201,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> { 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); @@ -1209,7 +1208,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { GenericArgKind::Const(tc) => { let c_const_generic = self.tyconst_to_constgeneric(tc); c_const_generics.push(c_const_generic); - } //_ => (), + } } } let (gen_trait_refs, spans) = self.get_traitrefs_and_span_from_defid(defid); From bd884408c9e99c6c4b7db1d1269d0c1ce3bbbdab Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Tue, 7 Jan 2025 15:14:25 -0800 Subject: [PATCH 44/51] remove expected --- tests/expected/llbc/traitimpl/expected | 53 -------------------------- 1 file changed, 53 deletions(-) delete mode 100644 tests/expected/llbc/traitimpl/expected diff --git a/tests/expected/llbc/traitimpl/expected b/tests/expected/llbc/traitimpl/expected deleted file mode 100644 index b45e1bb15c3a..000000000000 --- a/tests/expected/llbc/traitimpl/expected +++ /dev/null @@ -1,53 +0,0 @@ -struct test::B = -{ - index: i32, -} - -fn test::get_valB<'_0>(@1: &'_0 (@Adt0)) -> i32 -{ - let @0: i32; // return - let self@1: &'_ (@Adt0); // arg #1 - - @0 := copy ((*(self@1)).index) - return -} - -struct test::A = -{ - val: i32, -} - -fn test::get_valA<'_0>(@1: &'_0 (@Adt1)) -> i32 -{ - let @0: i32; // return - let self@1: &'_ (@Adt1); // arg #1 - - @0 := copy ((*(self@1)).val) - return -} - -fn test::main() -{ - let @0: (); // return - let e@1: @Adt1; // local - let k@2: @Adt0; // local - let i@3: i32; // local - let @4: &'_ (@Adt1); // anonymous local - let j@5: i32; // local - let @6: &'_ (@Adt0); // anonymous local - - e@1 := @Adt1 { val: const (3 : i32) } - k@2 := @Adt0 { index: const (3 : i32) } - @4 := &e@1 - i@3 := @Fun2(move (@4)) - drop @4 - @6 := &k@2 - j@5 := @Fun0(move (@6)) - drop @6 - drop j@5 - drop i@3 - drop k@2 - drop e@1 - @0 := () - return -} From e28169ad60518ca631c0951978ca24b3d7d86e55 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Tue, 7 Jan 2025 16:47:25 -0800 Subject: [PATCH 45/51] Update kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs Co-authored-by: Zyad Hassan <88045115+zhassan-aws@users.noreply.github.com> --- 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 d9b362ff230d..e4097977082c 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 @@ -372,7 +372,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { tid.try_into().unwrap() } - //This function is implemented accordingto how Charon encode discriminant + //This function is implemented according to how Charon encodes discriminants 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(); From e80166b8a65c76a8a8d39dd0a6a273fc0d8e7e18 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Wed, 8 Jan 2025 10:46:57 -0800 Subject: [PATCH 46/51] add example test for option --- .../codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 8 ++++++- tests/expected/llbc/option/test.rs | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 tests/expected/llbc/option/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 e4097977082c..ba5abb11a9b7 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 @@ -257,6 +257,12 @@ impl<'a, 'tcx> Context<'a, 'tcx> { }; let funcname = item_meta.name.clone(); let signature = self.translate_function_signature(self.instance); + //We temporarily don't translate the body of built-in function + //because at the current step, we want to extend the amount of syntaxes + //and test each syntax we extended (in tests/expected/llbc). + //Enabling translation of dependent built-in functions now may make the + //translation of the tests fail because of not-yet-implemented syntaxes + //Example: let body = if is_builtin { Err(CharonOpaque) } else { @@ -1512,7 +1518,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { debug!("translate_call: {func:?} {args:?} {destination:?} {target:?}"); let fn_ty = func.ty(self.instance.body().unwrap().locals()).unwrap(); let fn_ptr = match fn_ty.kind() { - TyKind::RigidTy(RigidTy::FnDef(def, genarg)) => { + TyKind::RigidTy(RigidTy::FnDef(def, genarg)) => { let instance = Instance::resolve(def, &genarg).unwrap(); let def_id = instance.def.def_id(); let fid = self.register_fun_decl_id(def_id); diff --git a/tests/expected/llbc/option/test.rs b/tests/expected/llbc/option/test.rs new file mode 100644 index 000000000000..57fdfd4bca7a --- /dev/null +++ b/tests/expected/llbc/option/test.rs @@ -0,0 +1,22 @@ +// 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 trait clauses in generic args + +fn both_none(a: Option, b: Option)-> bool{ + match a { + None => match b { + None => true, + _ => false + }, + _ => false + } +} + +#[kani::proof] +fn main() { + let a = Some(1 as u32); + let b = Some(2); + let i = both_none(a, b); +} From 7930902e9e9cc67ee4db389bacc966d5ec739601 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Wed, 8 Jan 2025 10:49:12 -0800 Subject: [PATCH 47/51] comments --- 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 ba5abb11a9b7..90a009488406 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 @@ -262,7 +262,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { //and test each syntax we extended (in tests/expected/llbc). //Enabling translation of dependent built-in functions now may make the //translation of the tests fail because of not-yet-implemented syntaxes - //Example: + //Example: tests/expected/llbc/option test fails because of the function std::ptr::drop_in_place let body = if is_builtin { Err(CharonOpaque) } else { From 06d0525dd7bf55c98765ffe4c9e249523a51111a Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Wed, 8 Jan 2025 11:52:44 -0800 Subject: [PATCH 48/51] add tests/expected/llbc/option/expected --- tests/expected/llbc/option/expected | 0 tests/expected/llbc/option/test.rs | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 tests/expected/llbc/option/expected diff --git a/tests/expected/llbc/option/expected b/tests/expected/llbc/option/expected new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/expected/llbc/option/test.rs b/tests/expected/llbc/option/test.rs index 57fdfd4bca7a..d3fa1b8031ff 100644 --- a/tests/expected/llbc/option/test.rs +++ b/tests/expected/llbc/option/test.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 OR MIT // kani-flags: -Zlean --print-llbc -//! This test checks that Kani's LLBC backend handles trait clauses in generic args +//! This test checks that Kani's LLBC backend handles option in generic args fn both_none(a: Option, b: Option)-> bool{ match a { From 2a2a4628129eaa9acc756d664a37369c85eae0bc Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Wed, 8 Jan 2025 16:32:49 -0800 Subject: [PATCH 49/51] revert change to 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 a54686e4e1da..ac52a4805a62 160000 --- a/tests/perf/s2n-quic +++ b/tests/perf/s2n-quic @@ -1 +1 @@ -Subproject commit a54686e4e1daad2afbbc01fccaf4cc1a512c58bf +Subproject commit ac52a4805a62ca4c7c9d1c17e86ba41c2afd308f From 954317d8b40aee3fd153bcf848d36631dbfb1d85 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Thu, 9 Jan 2025 09:23:46 -0800 Subject: [PATCH 50/51] fixed formating --- kani-compiler/src/codegen_aeneas_llbc/mir_to_ullbc/mod.rs | 2 +- tests/expected/llbc/option/test.rs | 6 +++--- 2 files changed, 4 insertions(+), 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 90a009488406..58f7561b4fc9 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 @@ -1518,7 +1518,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { debug!("translate_call: {func:?} {args:?} {destination:?} {target:?}"); let fn_ty = func.ty(self.instance.body().unwrap().locals()).unwrap(); let fn_ptr = match fn_ty.kind() { - TyKind::RigidTy(RigidTy::FnDef(def, genarg)) => { + TyKind::RigidTy(RigidTy::FnDef(def, genarg)) => { let instance = Instance::resolve(def, &genarg).unwrap(); let def_id = instance.def.def_id(); let fid = self.register_fun_decl_id(def_id); diff --git a/tests/expected/llbc/option/test.rs b/tests/expected/llbc/option/test.rs index d3fa1b8031ff..ee2aa6083233 100644 --- a/tests/expected/llbc/option/test.rs +++ b/tests/expected/llbc/option/test.rs @@ -4,13 +4,13 @@ //! This test checks that Kani's LLBC backend handles option in generic args -fn both_none(a: Option, b: Option)-> bool{ +fn both_none(a: Option, b: Option) -> bool { match a { None => match b { None => true, - _ => false + _ => false, }, - _ => false + _ => false, } } From 6c76375a91c768bc2f7a6e344d45d4f27411aebb Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Thu, 9 Jan 2025 09:25:09 -0800 Subject: [PATCH 51/51] add expected for trait impl --- tests/expected/llbc/traitimpl/expected | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/expected/llbc/traitimpl/expected diff --git a/tests/expected/llbc/traitimpl/expected b/tests/expected/llbc/traitimpl/expected new file mode 100644 index 000000000000..e69de29bb2d1