Skip to content

Commit

Permalink
Merge pull request #1122 from Nadrieril/tweaks
Browse files Browse the repository at this point in the history
Various tweaks
  • Loading branch information
Nadrieril authored Nov 26, 2024
2 parents e4c6c2b + a8dfb6f commit 01e7ecd
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 133 deletions.
2 changes: 1 addition & 1 deletion frontend/exporter/src/traits/resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ fn initial_search_predicates<'tcx>(
use DefKind::*;
match tcx.def_kind(def_id) {
// These inherit some predicates from their parent.
AssocTy | AssocFn | AssocConst | Closure => {
AssocTy | AssocFn | AssocConst | Closure | Ctor(..) | Variant => {
let parent = tcx.parent(def_id);
acc_predicates(tcx, parent, predicates, pred_id);
}
Expand Down
13 changes: 12 additions & 1 deletion frontend/exporter/src/types/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,18 @@ pub struct FnHeader {
pub abi: Abi,
}

sinto_todo!(rustc_target::spec::abi, Abi);
/// Reflects [`rustc_target::spec::abi::Abi`]
#[derive_group(Serializers)]
#[derive(AdtInto, Clone, Debug, JsonSchema, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[args(<'tcx, S: BaseState<'tcx>>, from: rustc_target::spec::abi::Abi, state: S as s)]
pub enum Abi {
Rust,
C {
unwind: bool,
},
#[todo]
Other(String),
}

/// Function definition
#[derive_group(Serializers)]
Expand Down
83 changes: 24 additions & 59 deletions frontend/exporter/src/types/mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ pub(crate) fn get_function_from_def_id_and_generics<'tcx, S: BaseState<'tcx> + H
let impl_expr = self_clause_for_item(s, &assoc, generics).unwrap();
// Return only the method generics; the trait generics are included in `impl_expr`.
let method_generics = &generics[num_container_generics..];
(method_generics.sinto(s), Option::Some(impl_expr))
(method_generics.sinto(s), Some(impl_expr))
}
rustc_middle::ty::AssocItemContainer::ImplContainer => {
// Solve the trait constraints of the impl block.
Expand All @@ -399,86 +399,51 @@ pub(crate) fn get_function_from_def_id_and_generics<'tcx, S: BaseState<'tcx> + H
let container_trait_refs =
solve_item_required_traits(s, container_def_id, container_generics);
trait_refs.extend(container_trait_refs);
(generics.sinto(s), Option::None)
(generics.sinto(s), None)
}
}
} else {
// Regular function call
(generics.sinto(s), Option::None)
(generics.sinto(s), None)
};

(def_id.sinto(s), generics, trait_refs, source)
}

/// Get a `FunOperand` from an `Operand` used in a function call.
/// Return the [DefId] of the function referenced by an operand, with the
/// parameters substitution.
/// The [Operand] comes from a [TerminatorKind::Call].
/// Only supports calls to top-level functions (which are considered as constants
/// by rustc); doesn't support closures for now.
#[cfg(feature = "rustc")]
fn get_function_from_operand<'tcx, S: UnderOwnerState<'tcx> + HasMir<'tcx>>(
s: &S,
func: &rustc_middle::mir::Operand<'tcx>,
op: &rustc_middle::mir::Operand<'tcx>,
) -> (FunOperand, Vec<GenericArg>, Vec<ImplExpr>, Option<ImplExpr>) {
use std::ops::Deref;
// Match on the func operand: it should be a constant as we don't support
// closures for now.
use rustc_middle::mir::{Const, Operand};
use rustc_middle::mir::Operand;
use rustc_middle::ty::TyKind;
match func {
Operand::Constant(c) => {
// Regular function case
let c = c.deref();
let (def_id, generics) = match &c.const_ {
Const::Ty(c_ty, _c) => {
// The type of the constant should be a FnDef, allowing
// us to retrieve the function's identifier and instantiation.
assert!(c_ty.is_fn());
match c_ty.kind() {
TyKind::FnDef(def_id, generics) => (*def_id, *generics),
_ => {
unreachable!();
}
}
}
Const::Val(_, c_ty) => {
// Same as for the `Ty` case above
assert!(c_ty.is_fn());
match c_ty.kind() {
TyKind::FnDef(def_id, generics) => (*def_id, *generics),
_ => {
unreachable!();
}
}
}
Const::Unevaluated(_, _) => {
unimplemented!();
}
};

let (fun_id, generics, trait_refs, trait_info) =
get_function_from_def_id_and_generics(s, def_id, generics);
(FunOperand::Id(fun_id), generics, trait_refs, trait_info)
let ty = op.ty(&s.mir().local_decls, s.base().tcx);
trace!("type: {:?}", ty);
// If the type of the value is one of the singleton types that corresponds to each function,
// that's enough information.
if let TyKind::FnDef(def_id, generics) = ty.kind() {
let (fun_id, generics, trait_refs, trait_info) =
get_function_from_def_id_and_generics(s, *def_id, *generics);
return (FunOperand::Id(fun_id), generics, trait_refs, trait_info);
}
match op {
Operand::Constant(_) => {
unimplemented!("{:?}", op);
}
Operand::Move(place) => {
// Closure case.
// The closure can not have bound variables nor trait references,
// so we don't need to extract generics, trait refs, etc.
let body = s.mir();
let ty = func.ty(&body.local_decls, s.base().tcx);
trace!("type: {:?}", ty);
trace!("type kind: {:?}", ty.kind());
let sig = match ty.kind() {
rustc_middle::ty::TyKind::FnPtr(sig, ..) => sig,
_ => unreachable!(),
};
trace!("FnPtr: {:?}", sig);
// Function pointer. A fn pointer cannot have bound variables or trait references, so
// we don't need to extract generics, trait refs, etc.
let place = place.sinto(s);

(FunOperand::Move(place), Vec::new(), Vec::new(), None)
}
Operand::Copy(_place) => {
unimplemented!("{:?}", func);
unimplemented!("{:?}", op);
}
}
}
Expand Down Expand Up @@ -978,13 +943,13 @@ pub enum AggregateKind {
let closure = generics.as_closure();
let sig = closure.sig().sinto(s);
// Solve the predicates from the parent (i.e., the function which calls the closure).
// Solve the predicates from the parent (i.e., the item which defines the closure).
let tcx = s.base().tcx;
let parent_generics = closure.parent_args();
let generics = tcx.mk_args(parent_generics);
let parent_generics_ref = tcx.mk_args(parent_generics);
// TODO: does this handle nested closures?
let parent = tcx.generics_of(rust_id).parent.unwrap();
let trait_refs = solve_item_required_traits(s, parent, generics);
let trait_refs = solve_item_required_traits(s, parent, parent_generics_ref);
AggregateKind::Closure(def_id, parent_generics.sinto(s), trait_refs, sig)
})]
Expand Down
39 changes: 37 additions & 2 deletions frontend/exporter/src/types/new/full_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,15 @@ pub enum FullDefKind<Body> {
// ADT parts
/// Refers to the variant definition, [`DefKind::Ctor`] refers to its constructor if it exists.
Variant,
/// Refers to the struct or enum variant's constructor.
Ctor(CtorOf, CtorKind),
/// The constructor function of a tuple/unit struct or tuple/unit enum variant.
#[custom_arm(RDefKind::Ctor(ctor_of, _) => get_ctor_contents(s, ctor_of.sinto(s)),)]
Ctor {
adt_def_id: DefId,
ctor_of: CtorOf,
variant_id: VariantIdx,
fields: IndexVec<FieldIdx, FieldDef>,
output_ty: Ty,
},
/// A field in a struct, enum or union. e.g.
/// - `bar` in `struct Foo { bar: u8 }`
/// - `Foo::Bar::0` in `enum Foo { Bar(u8) }`
Expand Down Expand Up @@ -762,6 +769,34 @@ where
}
}

#[cfg(feature = "rustc")]
fn get_ctor_contents<'tcx, S, Body>(s: &S, ctor_of: CtorOf) -> FullDefKind<Body>
where
S: UnderOwnerState<'tcx>,
Body: IsBody + TypeMappable,
{
let tcx = s.base().tcx;
let def_id = s.owner_id();

// The def_id of the adt this ctor belongs to.
let adt_def_id = match ctor_of {
CtorOf::Struct => tcx.parent(def_id),
CtorOf::Variant => tcx.parent(tcx.parent(def_id)),
};
let adt_def = tcx.adt_def(adt_def_id);
let variant_id = adt_def.variant_index_with_ctor_id(def_id);
let fields = adt_def.variant(variant_id).fields.sinto(s);
let generic_args = ty::GenericArgs::identity_for_item(tcx, adt_def_id);
let output_ty = ty::Ty::new_adt(tcx, adt_def, generic_args).sinto(s);
FullDefKind::Ctor {
adt_def_id: adt_def_id.sinto(s),
ctor_of,
variant_id: variant_id.sinto(s),
fields,
output_ty,
}
}

/// This normalizes trait clauses before calling `sinto` on them. This is a bit of a hack required
/// by charon for now. We can't normalize all clauses as this would lose region information in
/// outlives clauses.
Expand Down
Loading

0 comments on commit 01e7ecd

Please sign in to comment.