Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lift clauses on associated types to be clauses on the whole trait #290

Merged
merged 1 commit into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions charon-ml/src/GAst.ml
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ type trait_decl = {
generics : generic_params;
parent_clauses : trait_clause list;
consts : (trait_item_name * (ty * global_decl_id option)) list;
types : (trait_item_name * (trait_clause list * ty option)) list;
types : (trait_item_name * ty option) list;
required_methods : (trait_item_name * fun_decl_id) list;
provided_methods : (trait_item_name * fun_decl_id option) list;
}
Expand All @@ -172,7 +172,7 @@ type trait_impl = {
generics : generic_params;
parent_trait_refs : trait_ref list;
consts : (trait_item_name * (ty * global_decl_id)) list;
types : (trait_item_name * (trait_ref list * ty)) list;
types : (trait_item_name * ty) list;
required_methods : (trait_item_name * fun_decl_id) list;
provided_methods : (trait_item_name * fun_decl_id) list;
}
Expand Down
10 changes: 4 additions & 6 deletions charon-ml/src/GAstOfJson.ml
Original file line number Diff line number Diff line change
Expand Up @@ -459,12 +459,6 @@ and trait_instance_id_of_json (js : json) : (trait_instance_id, string) result =
let* x1 = trait_decl_id_of_json x1 in
let* x2 = trait_clause_id_of_json x2 in
Ok (ParentClause (x0, x1, x2))
| `Assoc [ ("ItemClause", `List [ x0; x1; x2; x3 ]) ] ->
let* x0 = trait_instance_id_of_json x0 in
let* x1 = trait_decl_id_of_json x1 in
let* x2 = trait_item_name_of_json x2 in
let* x3 = trait_clause_id_of_json x3 in
Ok (ItemClause (x0, x1, x2, x3))
| `String "SelfId" -> Ok Self
| `Assoc [ ("BuiltinOrAuto", builtin_or_auto) ] ->
let* builtin_or_auto = trait_decl_ref_of_json builtin_or_auto in
Expand Down Expand Up @@ -1241,6 +1235,7 @@ let gglobal_decl_of_json (bodies : 'body gexpr_body option list)
Ok global
| _ -> Error "")

(* Defined by hand because we discard the empty list of item clauses *)
and trait_decl_of_json (id_to_file : id_to_file_map) (js : json) :
(trait_decl, string) result =
combine_error_msgs js __FUNCTION__
Expand Down Expand Up @@ -1279,6 +1274,7 @@ and trait_decl_of_json (id_to_file : id_to_file_map) (js : json) :
(option_of_json ty_of_json)))
types
in
let types = List.map (fun (name, (_, ty)) -> (name, ty)) types in
let* required_methods =
list_of_json
(pair_of_json trait_item_name_of_json fun_decl_id_of_json)
Expand All @@ -1303,6 +1299,7 @@ and trait_decl_of_json (id_to_file : id_to_file_map) (js : json) :
}
| _ -> Error "")

(* Defined by hand because we discard the empty list of item clauses *)
and trait_impl_of_json (id_to_file : id_to_file_map) (js : json) :
(trait_impl, string) result =
combine_error_msgs js __FUNCTION__
Expand Down Expand Up @@ -1339,6 +1336,7 @@ and trait_impl_of_json (id_to_file : id_to_file_map) (js : json) :
(pair_of_json (list_of_json trait_ref_of_json) ty_of_json))
types
in
let types = List.map (fun (name, (_, ty)) -> (name, ty)) types in
let* required_methods =
list_of_json
(pair_of_json trait_item_name_of_json fun_decl_id_of_json)
Expand Down
22 changes: 5 additions & 17 deletions charon-ml/src/PrintGAst.ml
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,10 @@ let trait_decl_to_string (env : ('a, 'b) fmt_env) (indent : string)
in
let types =
List.map
(fun (name, (clauses, opt_ty)) ->
let clauses = List.map (trait_clause_to_string env) clauses in
let clauses = clauses_to_string indent1 indent_incr 0 clauses in
(fun (name, opt_ty) ->
match opt_ty with
| None -> indent1 ^ "type " ^ name ^ clauses ^ "\n"
| Some ty ->
indent1 ^ "type " ^ name ^ " = " ^ ty_to_string ty ^ clauses
^ "\n")
| None -> indent1 ^ "type " ^ name ^ "\n"
| Some ty -> indent1 ^ "type " ^ name ^ " = " ^ ty_to_string ty ^ "\n")
def.types
in
let required_methods =
Expand Down Expand Up @@ -261,16 +257,8 @@ let trait_impl_to_string (env : ('a, 'b) fmt_env) (indent : string)
in
let types =
List.map
(fun (name, (trait_refs, ty)) ->
let trait_refs =
if trait_refs <> [] then
" where ["
^ String.concat ", "
(List.map (trait_ref_to_string env) trait_refs)
^ "]"
else ""
in
indent1 ^ "type " ^ name ^ " = " ^ ty_to_string ty ^ trait_refs ^ "\n")
(fun (name, ty) ->
indent1 ^ "type " ^ name ^ " = " ^ ty_to_string ty ^ "\n")
def.types
in
let env_method (name, f) =
Expand Down
4 changes: 0 additions & 4 deletions charon-ml/src/PrintTypes.ml
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,6 @@ and trait_instance_id_to_string (env : ('a, 'b) fmt_env)
let inst_id = trait_instance_id_to_string env inst_id in
let clause_id = trait_clause_id_to_string env clause_id in
"parent(" ^ inst_id ^ ")::" ^ clause_id
| ItemClause (inst_id, _decl_id, item_name, clause_id) ->
let inst_id = trait_instance_id_to_string env inst_id in
let clause_id = trait_clause_id_to_string env clause_id in
"(" ^ inst_id ^ ")::" ^ item_name ^ "::[" ^ clause_id ^ "]"
| FnPointer ty -> "fn_ptr(" ^ ty_to_string env ty ^ ")"
| Closure (fid, generics) ->
"closure("
Expand Down
2 changes: 0 additions & 2 deletions charon-ml/src/Types.ml
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,6 @@ and trait_instance_id =
| BuiltinOrAuto of trait_decl_ref
| Clause of trait_clause_id
| ParentClause of trait_instance_id * trait_decl_id * trait_clause_id
| ItemClause of
trait_instance_id * trait_decl_id * trait_item_name * trait_clause_id
| FnPointer of ty
| Closure of fun_decl_id * generic_args
| Dyn of trait_decl_ref
Expand Down
9 changes: 7 additions & 2 deletions charon/src/ast/gast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,10 @@ pub struct TraitDecl {
///
/// The optional id is for the default value.
pub consts: Vec<(TraitItemName, (Ty, Option<GlobalDeclId>))>,
/// The associated types declared in the trait.
/// The associated types declared in the trait. The `Vector` is a list of trait clauses that
/// apply to this item. This is used during translation, but the `lift_associated_item_clauses`
/// pass moves them to be parent clauses later. Hence this is empty after that pass.
/// TODO: Do this as we translate to avoid the need to store this vector.
pub types: Vec<(
TraitItemName,
(Vector<TraitClauseId, TraitClause>, Option<Ty>),
Expand Down Expand Up @@ -287,7 +290,9 @@ pub struct TraitImpl {
pub parent_trait_refs: Vector<TraitClauseId, TraitRef>,
/// The associated constants declared in the trait.
pub consts: Vec<(TraitItemName, (Ty, GlobalDeclId))>,
/// The associated types declared in the trait.
/// The associated types declared in the trait. The `Vec` corresponds to the same `Vector` in
/// `TraitDecl.types`. In the same way, this is empty after the `lift_associated_item_clauses`
/// pass.
pub types: Vec<(TraitItemName, (Vec<TraitRef>, Ty))>,
/// The implemented required methods
pub required_methods: Vec<(TraitItemName, FunDeclId)>,
Expand Down
11 changes: 9 additions & 2 deletions charon/src/ast/krate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,22 +78,29 @@ pub enum AnyTransItem<'ctx> {
}

/// The data of a translated crate.
#[derive(Default)]
#[derive(Default, Drive, DriveMut)]
pub struct TranslatedCrate {
/// The name of the crate.
pub crate_name: String,

/// File names to ids and vice-versa
#[drive(skip)]
pub file_to_id: HashMap<FileName, FileId>,
#[drive(skip)]
pub id_to_file: HashMap<FileId, FileName>,
#[drive(skip)]
pub real_file_counter: Generator<LocalFileId>,
#[drive(skip)]
pub virtual_file_counter: Generator<VirtualFileId>,

/// All the ids, in the order in which we encountered them
#[drive(skip)]
pub all_ids: LinkedHashSet<AnyTransId>,
/// The map from rustc id to translated id.
#[drive(skip)]
pub id_map: HashMap<DefId, AnyTransId>,
/// The reverse map of ids.
#[drive(skip)]
pub reverse_id_map: HashMap<AnyTransId, DefId>,

/// The translated type definitions
Expand All @@ -109,6 +116,7 @@ pub struct TranslatedCrate {
/// The translated trait declarations
pub trait_impls: Vector<TraitImplId, TraitImpl>,
/// The re-ordered groups of declarations, initialized as empty.
#[drive(skip)]
pub ordered_decls: Option<DeclarationsGroups>,
}

Expand All @@ -126,7 +134,6 @@ impl TranslatedCrate {
pub fn all_items(&self) -> impl Iterator<Item = AnyTransItem<'_>> {
self.all_items_with_ids().map(|(_, item)| item)
}

pub fn all_items_with_ids(&self) -> impl Iterator<Item = (AnyTransId, AnyTransItem<'_>)> {
self.all_ids
.iter()
Expand Down
7 changes: 3 additions & 4 deletions charon/src/ast/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,8 @@ pub enum TraitRefKind {
/// ```
ParentClause(Box<TraitRefKind>, TraitDeclId, TraitClauseId),

/// A clause bound in a trait item (typically a trait clause in an
/// associated type).
/// A clause defined on an associated type. This variant is only used during translation; after
/// the `lift_associated_item_clauses` pass, clauses on items become `ParentClause`s.
///
/// Remark: the [TraitDeclId] gives the trait declaration which is
/// implemented by the trait implementation from which we take the item
Expand All @@ -202,8 +202,7 @@ pub enum TraitRefKind {
/// local clause 0 implements Foo
/// }
/// ```
///
///
#[charon::opaque]
ItemClause(Box<TraitRefKind>, TraitDeclId, TraitItemName, TraitClauseId),

/// Self, in case of trait declarations/implementations.
Expand Down
1 change: 1 addition & 0 deletions charon/src/ast/types_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ impl GenericArgs {
}

/// Check whether this matches the given `GenericParams`.
/// TODO: check more things, e.g. that the trait refs use the correct trait and generics.
pub fn matches(&self, params: &GenericParams) -> bool {
params.regions.len() == self.regions.len()
&& params.types.len() == self.types.len()
Expand Down
2 changes: 2 additions & 0 deletions charon/src/bin/charon-driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ pub fn translate(tcx: TyCtxt, internal: &mut CharonCallbacks) -> export::CrateDa

// Run the micro-passes that clean up bodies.
for pass in ULLBC_PASSES.iter() {
trace!("# Starting pass {}", pass.name());
pass.transform_ctx(&mut ctx)
}

Expand All @@ -269,6 +270,7 @@ pub fn translate(tcx: TyCtxt, internal: &mut CharonCallbacks) -> export::CrateDa

// Run the micro-passes that clean up bodies.
for pass in LLBC_PASSES.iter() {
trace!("# Starting pass {}", pass.name());
pass.transform_ctx(&mut ctx)
}

Expand Down
126 changes: 126 additions & 0 deletions charon/src/bin/generate-ml/GAstOfJson.template.ml
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,132 @@ let gglobal_decl_of_json (bodies : 'body gexpr_body option list)
Ok global
| _ -> Error "")

(* Defined by hand because we discard the empty list of item clauses *)
and trait_decl_of_json (id_to_file : id_to_file_map) (js : json) :
(trait_decl, string) result =
combine_error_msgs js __FUNCTION__
(match js with
| `Assoc
[
("def_id", def_id);
("item_meta", item_meta);
("generics", generics);
("parent_clauses", parent_clauses);
("consts", consts);
("types", types);
("required_methods", required_methods);
("provided_methods", provided_methods);
] ->
let* def_id = trait_decl_id_of_json def_id in
let* item_meta = item_meta_of_json id_to_file item_meta in
let* generics = generic_params_of_json id_to_file generics in
let* parent_clauses =
vector_of_json trait_clause_id_of_json
(trait_clause_of_json id_to_file)
parent_clauses
in
let* consts =
list_of_json
(pair_of_json trait_item_name_of_json
(pair_of_json ty_of_json (option_of_json global_decl_id_of_json)))
consts
in
let* types =
list_of_json
(pair_of_json trait_item_name_of_json
(pair_of_json
(vector_of_json trait_clause_id_of_json
(trait_clause_of_json id_to_file))
(option_of_json ty_of_json)))
types
in
let types = List.map (fun (name, (_, ty)) -> (name, ty)) types in
let* required_methods =
list_of_json
(pair_of_json trait_item_name_of_json fun_decl_id_of_json)
required_methods
in
let* provided_methods =
list_of_json
(pair_of_json trait_item_name_of_json
(option_of_json fun_decl_id_of_json))
provided_methods
in
Ok
{
def_id;
item_meta;
generics;
parent_clauses;
consts;
types;
required_methods;
provided_methods;
}
| _ -> Error "")

(* Defined by hand because we discard the empty list of item clauses *)
and trait_impl_of_json (id_to_file : id_to_file_map) (js : json) :
(trait_impl, string) result =
combine_error_msgs js __FUNCTION__
(match js with
| `Assoc
[
("def_id", def_id);
("item_meta", item_meta);
("impl_trait", impl_trait);
("generics", generics);
("parent_trait_refs", parent_trait_refs);
("consts", consts);
("types", types);
("required_methods", required_methods);
("provided_methods", provided_methods);
] ->
let* def_id = trait_impl_id_of_json def_id in
let* item_meta = item_meta_of_json id_to_file item_meta in
let* impl_trait = trait_decl_ref_of_json impl_trait in
let* generics = generic_params_of_json id_to_file generics in
let* parent_trait_refs =
vector_of_json trait_clause_id_of_json trait_ref_of_json
parent_trait_refs
in
let* consts =
list_of_json
(pair_of_json trait_item_name_of_json
(pair_of_json ty_of_json global_decl_id_of_json))
consts
in
let* types =
list_of_json
(pair_of_json trait_item_name_of_json
(pair_of_json (list_of_json trait_ref_of_json) ty_of_json))
types
in
let types = List.map (fun (name, (_, ty)) -> (name, ty)) types in
let* required_methods =
list_of_json
(pair_of_json trait_item_name_of_json fun_decl_id_of_json)
required_methods
in
let* provided_methods =
list_of_json
(pair_of_json trait_item_name_of_json fun_decl_id_of_json)
provided_methods
in
Ok
{
def_id;
item_meta;
impl_trait;
generics;
parent_trait_refs;
consts;
types;
required_methods;
provided_methods;
}
| _ -> Error "")

(* __REPLACE5__ *)

let type_declaration_group_of_json (js : json) :
Expand Down
2 changes: 1 addition & 1 deletion charon/src/bin/generate-ml/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ fn main() -> Result<()> {
"GExprBody",
"ItemKind",
],
&["TraitDecl", "TraitImpl", "GDeclarationGroup"],
&["GDeclarationGroup"],
];
let template_path = dir.join("GAstOfJson.template.ml");
let mut template = fs::read_to_string(&template_path)
Expand Down
Loading
Loading