Skip to content

Commit af86315

Browse files
authored
Merge pull request #1559 from Nadrieril/upstream-pr
Merge frontend improvements
2 parents 155c125 + 44f041c commit af86315

File tree

22 files changed

+1935
-1178
lines changed

22 files changed

+1935
-1178
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ Changes to the Rust Engine:
1515
expressions, pattern-matching) (#1623)
1616
- Update name rendering infrastructure in the Lean backend (#1623, #1624)
1717

18+
Changes to the frontend:
19+
- Add an explicit `Self: Trait` clause to trait methods and consts (#1559)
20+
- Fix `ImplExpr::Builtin` that had some type errors (#1559)
21+
- Improve the translation of `Drop` information (#1559)
22+
- Add variance information to type parameters (#1559)
23+
- Cleanup the `State` infrastructure a little bit (#1559)
24+
- Add information about the metadata to use in unsize coercions (#1559)
25+
- Resolve `dyn Trait` predicates (#1559)
26+
- Many improvements to `FullDef` (#1559)
27+
- Add infrastructure to get a monomorphized `FullDef`; this is used in charon to monomorphize a crate graph (#1559)
28+
1829
Miscellaneous:
1930
- A lean tutorial has been added to the hax website.
2031

engine/backends/fstar/fstar_backend.ml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2003,6 +2003,42 @@ let unsize_as_identity =
20032003
in
20042004
visitor#visit_item ()
20052005

2006+
(** Rewrites, in trait, local bounds refereing to `Self` into the impl expr of
2007+
kind `Self`. *)
2008+
let local_self_bound_as_self (i : AST.item) : AST.item =
2009+
match i.v with
2010+
| Trait { name; generics; _ } ->
2011+
let generic_eq (param : generic_param) (value : generic_value) =
2012+
(let* id =
2013+
match (param.kind, value) with
2014+
| GPConst _, GConst { e = LocalVar id } -> Some id
2015+
| GPType, GType (TParam id) -> Some id
2016+
| GPLifetime _, GLifetime _ -> Some param.ident
2017+
| _ -> None
2018+
in
2019+
Some ([%eq: local_ident] id param.ident))
2020+
|> Option.value ~default:false
2021+
in
2022+
let generics_eq params values =
2023+
match List.for_all2 ~f:generic_eq params values with
2024+
| List.Or_unequal_lengths.Ok v -> v
2025+
| List.Or_unequal_lengths.Unequal_lengths -> false
2026+
in
2027+
(object
2028+
inherit [_] U.Visitors.map as super
2029+
2030+
method! visit_impl_expr () ie =
2031+
match ie with
2032+
| { kind = LocalBound _; goal = { args; trait } }
2033+
when [%eq: concrete_ident] trait name
2034+
&& generics_eq generics.params args ->
2035+
{ ie with kind = Self }
2036+
| _ -> ie
2037+
end)
2038+
#visit_item
2039+
() i
2040+
| _ -> i
2041+
20062042
let apply_phases (bo : BackendOptions.t) (items : Ast.Rust.item list) :
20072043
AST.item list =
20082044
let items =
@@ -2022,6 +2058,7 @@ let apply_phases (bo : BackendOptions.t) (items : Ast.Rust.item list) :
20222058
TransformToInputLanguage.ditems items
20232059
|> List.map ~f:unsize_as_identity
20242060
|> List.map ~f:unsize_as_identity
2061+
|> List.map ~f:local_self_bound_as_self
20252062
|> List.map ~f:U.Mappers.add_typ_ascription
20262063
in
20272064
items

engine/lib/import_thir.ml

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,8 @@ end) : EXPR = struct
547547
{
548548
item =
549549
{
550-
value = { def_id = id; generic_args; impl_exprs; in_trait };
550+
value =
551+
{ def_id = id; generic_args; impl_exprs; in_trait; _ };
551552
_;
552553
};
553554
_;
@@ -1025,7 +1026,7 @@ end) : EXPR = struct
10251026
| ClosureFnPointer Safe | ReifyFnPointer ->
10261027
(* we have arrow types, we do not distinguish between top-level functions and closures *)
10271028
(c_expr source).e
1028-
| Unsize ->
1029+
| Unsize _ ->
10291030
(* https://doc.rust-lang.org/std/marker/trait.Unsize.html *)
10301031
(U.call Rust_primitives__unsize [ c_expr source ] span typ).e
10311032
(* let source = c_expr source in *)
@@ -1114,21 +1115,25 @@ end) : EXPR = struct
11141115
| Error ->
11151116
assertion_failure [ span ]
11161117
"got type `Error`: Rust compilation probably failed."
1117-
| Dynamic (predicates, _region, Dyn) -> (
1118+
| Dynamic (_, predicates, _region) -> (
11181119
let goals, non_traits =
11191120
List.partition_map
1120-
~f:(fun pred ->
1121-
match pred.value with
1122-
| Trait { args; def_id } ->
1121+
~f:(fun ((clause, _span) : Types.clause * _) ->
1122+
match clause.kind.value with
1123+
| Trait { trait_ref; _ } ->
11231124
let goal : dyn_trait_goal =
11241125
{
1125-
trait = Concrete_ident.of_def_id ~value:false def_id;
1126-
non_self_args = List.map ~f:(c_generic_value span) args;
1126+
trait =
1127+
Concrete_ident.of_def_id ~value:false
1128+
trait_ref.value.def_id;
1129+
non_self_args =
1130+
List.map ~f:(c_generic_value span)
1131+
(List.tl_exn trait_ref.value.generic_args);
11271132
}
11281133
in
11291134
First goal
11301135
| _ -> Second ())
1131-
predicates
1136+
predicates.predicates
11321137
in
11331138
match non_traits with
11341139
| [] -> TDyn { witness = W.dyn; goals }
@@ -1150,7 +1155,7 @@ end) : EXPR = struct
11501155

11511156
and c_impl_expr (span : Thir.span) (ie : Thir.impl_expr) : impl_expr =
11521157
let goal = c_trait_ref span ie.trait.value in
1153-
let impl = { kind = c_impl_expr_atom span ie.impl; goal } in
1158+
let impl = { kind = c_impl_expr_atom span ie.impl goal; goal } in
11541159
match ie.impl with
11551160
| Concrete { value = { impl_exprs = []; _ }; _ } -> impl
11561161
| Concrete { value = { impl_exprs; _ }; _ } ->
@@ -1163,7 +1168,7 @@ end) : EXPR = struct
11631168
let args = List.map ~f:(c_generic_value span) tr.value.generic_args in
11641169
{ trait; args }
11651170

1166-
and c_impl_expr_atom (span : Thir.span) (ie : Thir.impl_expr_atom) :
1171+
and c_impl_expr_atom (span : Thir.span) (ie : Thir.impl_expr_atom) goal :
11671172
impl_expr_kind =
11681173
let browse_path (item_kind : impl_expr_kind)
11691174
(chunk : Thir.impl_expr_path_chunk) =
@@ -1196,8 +1201,7 @@ end) : EXPR = struct
11961201
List.fold ~init ~f:browse_path path
11971202
| Dyn -> Dyn
11981203
| SelfImpl { path; _ } -> List.fold ~init:Self ~f:browse_path path
1199-
| Builtin { trait; _ } -> Builtin (c_trait_ref span trait.value)
1200-
| Drop _ -> failwith @@ "impl_expr_atom: Drop"
1204+
| Builtin _ -> Builtin goal
12011205
| Error str -> failwith @@ "impl_expr_atom: Error " ^ str
12021206

12031207
and c_generic_value (span : Thir.span) (ty : Thir.generic_arg) : generic_value

frontend/exporter/src/body.rs

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ mod module {
1313
def_id::{DefId as RDefId, LocalDefId as RLocalDefId},
1414
hir_id::OwnerId as ROwnerId,
1515
};
16+
use rustc_middle::ty;
1617

1718
mod store {
1819
//! This module helps at store bodies to avoid stealing.
@@ -97,7 +98,7 @@ mod module {
9798
}
9899
pub use store::*;
99100

100-
pub fn get_thir<'tcx, S: UnderOwnerState<'tcx>>(
101+
pub fn get_thir<'tcx, S: BaseState<'tcx>>(
101102
did: RLocalDefId,
102103
s: &S,
103104
) -> (
@@ -122,7 +123,11 @@ mod module {
122123
}
123124

124125
pub trait IsBody: Sized + std::fmt::Debug + Clone + 'static {
125-
fn body<'tcx, S: UnderOwnerState<'tcx>>(did: RDefId, s: &S) -> Option<Self>;
126+
fn body<'tcx, S: UnderOwnerState<'tcx>>(
127+
s: &S,
128+
did: RDefId,
129+
instantiate: Option<ty::GenericArgsRef<'tcx>>,
130+
) -> Option<Self>;
126131

127132
/// Reuse a MIR body we already got. Panic if that's impossible.
128133
fn from_mir<'tcx, S: UnderOwnerState<'tcx>>(
@@ -133,7 +138,7 @@ mod module {
133138
}
134139
}
135140

136-
pub fn make_fn_def<'tcx, Body: IsBody, S: UnderOwnerState<'tcx>>(
141+
pub fn make_fn_def<'tcx, Body: IsBody, S: BaseState<'tcx>>(
137142
fn_sig: &rustc_hir::FnSig,
138143
body_id: &rustc_hir::BodyId,
139144
s: &S,
@@ -142,11 +147,11 @@ mod module {
142147
let ldid = hir_id.owner.def_id;
143148

144149
let (thir, expr_entrypoint) = get_thir(ldid, s);
145-
let s = &with_owner_id(s.base(), thir.clone(), (), ldid.to_def_id());
150+
let s = &s.with_owner_id(ldid.to_def_id()).with_thir(thir.clone());
146151
FnDef {
147152
params: thir.params.raw.sinto(s),
148153
ret: thir.exprs[expr_entrypoint].ty.sinto(s),
149-
body: Body::body(ldid.to_def_id(), s).s_unwrap(s),
154+
body: Body::body(s, ldid.to_def_id(), None).s_unwrap(s),
150155
sig_span: fn_sig.span.sinto(s),
151156
header: fn_sig.header.sinto(s),
152157
}
@@ -161,13 +166,17 @@ mod module {
161166
// be local. It is safe to do so, because if we have access to HIR objects,
162167
// it necessarily means we are exploring a local item (we don't have
163168
// access to the HIR of external objects, only their MIR).
164-
Body::body(s.base().tcx.hir_body_owner_def_id(id).to_def_id(), s).s_unwrap(s)
169+
Body::body(s, s.base().tcx.hir_body_owner_def_id(id).to_def_id(), None).s_unwrap(s)
165170
}
166171

167172
mod implementations {
168173
use super::*;
169174
impl IsBody for () {
170-
fn body<'tcx, S: UnderOwnerState<'tcx>>(_did: RDefId, _s: &S) -> Option<Self> {
175+
fn body<'tcx, S: UnderOwnerState<'tcx>>(
176+
_s: &S,
177+
_did: RDefId,
178+
_instantiate: Option<ty::GenericArgsRef<'tcx>>,
179+
) -> Option<Self> {
171180
Some(())
172181
}
173182
fn from_mir<'tcx, S: UnderOwnerState<'tcx>>(
@@ -178,9 +187,15 @@ mod module {
178187
}
179188
}
180189
impl IsBody for ThirBody {
181-
fn body<'tcx, S: UnderOwnerState<'tcx>>(did: RDefId, s: &S) -> Option<Self> {
190+
fn body<'tcx, S: BaseState<'tcx>>(
191+
s: &S,
192+
did: RDefId,
193+
instantiate: Option<ty::GenericArgsRef<'tcx>>,
194+
) -> Option<Self> {
182195
let did = did.as_local()?;
183196
let (thir, expr) = get_thir(did, s);
197+
assert!(instantiate.is_none(), "monomorphized thir isn't supported");
198+
let s = &s.with_owner_id(did.to_def_id());
184199
Some(if *CORE_EXTRACTION_MODE {
185200
let expr = &thir.exprs[expr];
186201
Decorated {
@@ -191,36 +206,41 @@ mod module {
191206
span: expr.span.sinto(s),
192207
}
193208
} else {
194-
expr.sinto(&with_owner_id(s.base(), thir, (), did.to_def_id()))
209+
expr.sinto(&s.with_thir(thir))
195210
})
196211
}
197212
}
198213

199214
impl<A: IsBody, B: IsBody> IsBody for (A, B) {
200-
fn body<'tcx, S: UnderOwnerState<'tcx>>(did: RDefId, s: &S) -> Option<Self> {
201-
Some((A::body(did, s)?, B::body(did, s)?))
215+
fn body<'tcx, S: UnderOwnerState<'tcx>>(
216+
s: &S,
217+
did: RDefId,
218+
instantiate: Option<ty::GenericArgsRef<'tcx>>,
219+
) -> Option<Self> {
220+
Some((A::body(s, did, instantiate)?, B::body(s, did, instantiate)?))
202221
}
203222
}
204223

205224
impl<MirKind: IsMirKind + Clone + 'static> IsBody for MirBody<MirKind> {
206-
fn body<'tcx, S: UnderOwnerState<'tcx>>(did: RDefId, s: &S) -> Option<Self> {
207-
MirKind::get_mir(s.base().tcx, did, |body| {
208-
let body = Rc::new(body.clone());
209-
body.sinto(&with_owner_id(s.base(), (), body.clone(), did))
225+
fn body<'tcx, S: UnderOwnerState<'tcx>>(
226+
s: &S,
227+
did: RDefId,
228+
instantiate: Option<ty::GenericArgsRef<'tcx>>,
229+
) -> Option<Self> {
230+
let tcx = s.base().tcx;
231+
let typing_env = s.typing_env();
232+
MirKind::get_mir(tcx, did, |body| {
233+
let body = substitute(tcx, typing_env, instantiate, body.clone());
234+
let body = Rc::new(body);
235+
body.sinto(&s.with_mir(body.clone()))
210236
})
211237
}
212238
fn from_mir<'tcx, S: UnderOwnerState<'tcx>>(
213239
s: &S,
214240
body: rustc_middle::mir::Body<'tcx>,
215241
) -> Option<Self> {
216242
let body = Rc::new(body.clone());
217-
let s = &State {
218-
base: s.base(),
219-
owner_id: s.owner_id(),
220-
mir: body.clone(),
221-
binder: (),
222-
thir: (),
223-
};
243+
let s = &s.with_mir(body.clone());
224244
Some(body.sinto(s))
225245
}
226246
}

frontend/exporter/src/id_table.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use std::{
2424

2525
/// Unique IDs in a ID table.
2626
#[derive_group(Serializers)]
27-
#[derive(Default, Clone, Debug, JsonSchema, Hash, PartialEq, Eq, PartialOrd, Ord)]
27+
#[derive(Default, Clone, Copy, Debug, JsonSchema, Hash, PartialEq, Eq, PartialOrd, Ord)]
2828
#[serde(transparent)]
2929
pub struct Id {
3030
id: u32,
@@ -88,7 +88,7 @@ impl SupportedType<Value> for ItemRefContents {
8888
}
8989

9090
/// A node is a bundle of an ID with a value.
91-
#[derive(Deserialize, Serialize, Debug, JsonSchema, PartialEq, Eq, PartialOrd, Ord)]
91+
#[derive(Deserialize, Serialize, Debug, JsonSchema, PartialOrd, Ord)]
9292
#[serde(into = "serde_repr::NodeRepr<T>")]
9393
#[serde(try_from = "serde_repr::NodeRepr<T>")]
9494
pub struct Node<T: 'static + SupportedType<Value>> {
@@ -111,6 +111,12 @@ impl<T: SupportedType<Value> + Hash> Hash for Node<T> {
111111
self.value.as_ref().hash(state);
112112
}
113113
}
114+
impl<T: SupportedType<Value> + Eq> Eq for Node<T> {}
115+
impl<T: SupportedType<Value> + PartialEq> PartialEq for Node<T> {
116+
fn eq(&self, other: &Self) -> bool {
117+
self.value == other.value
118+
}
119+
}
114120

115121
/// Manual implementation of `Clone` that doesn't require a `Clone`
116122
/// bound on `T`.
@@ -203,6 +209,10 @@ impl<T: Sync + Send + 'static + SupportedType<Value>> Node<T> {
203209
pub fn inner(&self) -> &Arc<T> {
204210
&self.value
205211
}
212+
213+
pub fn id(&self) -> Id {
214+
self.id
215+
}
206216
}
207217

208218
/// Wrapper for a type `T` that creates a bundle containing both a ID

0 commit comments

Comments
 (0)