Skip to content

Commit b153ce1

Browse files
authored
Merge pull request #1431 from Nadrieril/clarify-parent-impl-exprs
Consistently translate impl exprs for parent items
2 parents aba1338 + 7f6d083 commit b153ce1

File tree

6 files changed

+26
-112
lines changed

6 files changed

+26
-112
lines changed

frontend/exporter/src/constant_utils/uneval.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,11 @@ pub fn translate_constant_reference<'tcx>(
114114
if assoc.trait_item_def_id.is_some() {
115115
// This must be a trait declaration constant
116116
let name = assoc.name.to_string();
117-
let impl_expr = self_clause_for_item(s, &assoc, ucv.args).unwrap();
117+
let impl_expr = self_clause_for_item(s, ucv.def, ucv.args).unwrap();
118118
ConstantExprKind::TraitConst { impl_expr, name }
119119
} else {
120120
// Constant appearing in an inherent impl block.
121-
let parent_def_id = tcx.parent(ucv.def);
122-
let trait_refs = solve_item_required_traits(s, parent_def_id, ucv.args);
121+
let trait_refs = solve_item_required_traits(s, ucv.def, ucv.args);
123122
ConstantExprKind::GlobalName {
124123
id: ucv.def.sinto(s),
125124
generics: ucv.args.sinto(s),

frontend/exporter/src/traits.rs

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -185,25 +185,14 @@ pub fn solve_trait<'tcx, S: BaseState<'tcx> + HasOwnerId>(
185185
}
186186

187187
/// Solve the trait obligations for a specific item use (for example, a method call, an ADT, etc.)
188-
/// in the current context.
188+
/// in the current context. Just like generic args include generics of parent items, this includes
189+
/// impl exprs for parent items.
189190
#[cfg(feature = "rustc")]
190191
#[tracing::instrument(level = "trace", skip(s), ret)]
191192
pub fn solve_item_required_traits<'tcx, S: UnderOwnerState<'tcx>>(
192193
s: &S,
193194
def_id: RDefId,
194195
generics: ty::GenericArgsRef<'tcx>,
195-
) -> Vec<ImplExpr> {
196-
let predicates = required_predicates(s.base().tcx, def_id);
197-
solve_item_traits_inner(s, generics, predicates)
198-
}
199-
200-
/// Like `solve_item_required_traits`, but also includes predicates coming from the parent items.
201-
#[cfg(feature = "rustc")]
202-
#[tracing::instrument(level = "trace", skip(s), ret)]
203-
pub fn solve_item_and_parents_required_traits<'tcx, S: UnderOwnerState<'tcx>>(
204-
s: &S,
205-
def_id: RDefId,
206-
generics: ty::GenericArgsRef<'tcx>,
207196
) -> Vec<ImplExpr> {
208197
fn accumulate<'tcx, S: UnderOwnerState<'tcx>>(
209198
s: &S,
@@ -220,7 +209,8 @@ pub fn solve_item_and_parents_required_traits<'tcx, S: UnderOwnerState<'tcx>>(
220209
}
221210
_ => {}
222211
}
223-
impl_exprs.extend(solve_item_required_traits(s, def_id, generics));
212+
let predicates = required_predicates(tcx, def_id);
213+
impl_exprs.extend(solve_item_traits_inner(s, generics, predicates));
224214
}
225215
let mut impl_exprs = vec![];
226216
accumulate(s, def_id, generics, &mut impl_exprs);
@@ -272,13 +262,13 @@ fn solve_item_traits_inner<'tcx, S: UnderOwnerState<'tcx>>(
272262
#[cfg(feature = "rustc")]
273263
pub fn self_clause_for_item<'tcx, S: UnderOwnerState<'tcx>>(
274264
s: &S,
275-
assoc: &rustc_middle::ty::AssocItem,
265+
def_id: RDefId,
276266
generics: rustc_middle::ty::GenericArgsRef<'tcx>,
277267
) -> Option<ImplExpr> {
278268
use rustc_middle::ty::EarlyBinder;
279269
let tcx = s.base().tcx;
280270

281-
let tr_def_id = tcx.trait_of_item(assoc.def_id)?;
271+
let tr_def_id = tcx.trait_of_item(def_id)?;
282272
// The "self" predicate in the context of the trait.
283273
let self_pred = self_predicate(tcx, tr_def_id);
284274
// Substitute to be in the context of the current item.

frontend/exporter/src/traits/utils.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,6 @@ pub fn required_predicates<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> GenericPre
7676
| TraitAlias
7777
| TyAlias
7878
| Union => predicates_defined_on(tcx, def_id),
79-
// The tuple struct/variant constructor functions inherit the generics and predicates from
80-
// their parents.
81-
Variant | Ctor(..) => return required_predicates(tcx, tcx.parent(def_id)),
8279
// We consider all predicates on traits to be outputs
8380
Trait => Default::default(),
8481
// `predicates_defined_on` ICEs on other def kinds.

frontend/exporter/src/types/mir.rs

Lines changed: 15 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
use crate::prelude::*;
66
#[cfg(feature = "rustc")]
77
use rustc_middle::{mir, ty};
8-
#[cfg(feature = "rustc")]
9-
use tracing::trace;
108

119
#[derive_group(Serializers)]
1210
#[derive(AdtInto, Clone, Debug, JsonSchema)]
@@ -342,58 +340,20 @@ pub struct Terminator {
342340
}
343341

344342
#[cfg(feature = "rustc")]
345-
pub(crate) fn get_function_from_def_id_and_generics<'tcx, S: BaseState<'tcx> + HasOwnerId>(
343+
/// Compute the
344+
pub(crate) fn get_function_from_def_id_and_generics<'tcx, S: UnderOwnerState<'tcx>>(
346345
s: &S,
347346
def_id: rustc_hir::def_id::DefId,
348347
generics: rustc_middle::ty::GenericArgsRef<'tcx>,
349348
) -> (DefId, Vec<GenericArg>, Vec<ImplExpr>, Option<ImplExpr>) {
350-
let tcx = s.base().tcx;
351-
352-
// Retrieve the trait requirements for the **method**.
353-
// For instance, if we write:
354-
// ```
355-
// fn foo<T : Bar>(...)
356-
// ^^^
357-
// ```
358-
let mut trait_refs = solve_item_required_traits(s, def_id, generics);
349+
// Retrieve the trait requirements for the item.
350+
let trait_refs = solve_item_required_traits(s, def_id, generics);
359351

352+
// If this is a trait method call, retreive the impl expr information for that trait.
360353
// Check if this is a trait method call: retrieve the trait source if
361-
// it is the case (i.e., where does the method come from? Does it refer
362-
// to a top-level implementation? Or the method of a parameter? etc.).
363-
// At the same time, retrieve the trait obligations for this **trait**.
364-
// Remark: the trait obligations for the method are not the same as
365-
// the trait obligations for the trait. More precisely:
366-
//
367-
// ```
368-
// trait Foo<T : Bar> {
369-
// ^^^^^
370-
// trait level trait obligation
371-
// fn baz(...) where T : ... {
372-
// ... ^^^
373-
// method level trait obligation
374-
// }
375-
// }
376-
// ```
377-
//
378-
// Also, a function doesn't need to belong to a trait to have trait
379-
// obligations:
380-
// ```
381-
// fn foo<T : Bar>(...)
382-
// ^^^
383-
// method level trait obligation
384-
// ```
385-
let (generics, source) = if let Some(assoc) = tcx.opt_associated_item(def_id) {
386-
// There is an associated item.
387-
use tracing::*;
388-
trace!("def_id: {:?}", def_id);
389-
trace!("assoc: def_id: {:?}", assoc.def_id);
390-
// Retrieve the `DefId` of the trait declaration or the impl block.
391-
let container_def_id = match assoc.container {
392-
rustc_middle::ty::AssocItemContainer::Trait => tcx.trait_of_item(assoc.def_id).unwrap(),
393-
rustc_middle::ty::AssocItemContainer::Impl => tcx.impl_of_method(assoc.def_id).unwrap(),
394-
};
395-
// The generics are split in two: the arguments of the container (trait decl or impl block)
396-
// and the arguments of the method.
354+
let (generics, trait_impl) = if let Some(tinfo) = self_clause_for_item(s, def_id, generics) {
355+
// The generics are split in two: the arguments of the container (trait decl or impl
356+
// block) and the arguments of the method.
397357
//
398358
// For instance, if we have:
399359
// ```
@@ -408,44 +368,16 @@ pub(crate) fn get_function_from_def_id_and_generics<'tcx, S: BaseState<'tcx> + H
408368
// ```
409369
// The generics for the call to `baz` will be the concatenation: `<T, u32, U>`, which we
410370
// split into `<T, u32>` and `<U>`.
411-
//
412-
// If we have:
413-
// ```
414-
// impl<T: Ord> Map<T> {
415-
// pub fn insert<U: Clone>(&mut self, x: U) { ... }
416-
// }
417-
// pub fn test(mut tree: Map<u32>) {
418-
// tree.insert(false);
419-
// }
420-
// ```
421-
// The generics for `insert` are `<u32>` for the impl and `<bool>` for the method.
422-
match assoc.container {
423-
rustc_middle::ty::AssocItemContainer::Trait => {
424-
let num_container_generics = tcx.generics_of(container_def_id).own_params.len();
425-
// Retrieve the trait information
426-
let impl_expr = self_clause_for_item(s, &assoc, generics).unwrap();
427-
// Return only the method generics; the trait generics are included in `impl_expr`.
428-
let method_generics = &generics[num_container_generics..];
429-
(method_generics.sinto(s), Some(impl_expr))
430-
}
431-
rustc_middle::ty::AssocItemContainer::Impl => {
432-
// Solve the trait constraints of the impl block.
433-
let container_generics = tcx.generics_of(container_def_id);
434-
let container_generics = generics.truncate_to(tcx, container_generics);
435-
// Prepend the container trait refs.
436-
let mut combined_trait_refs =
437-
solve_item_required_traits(s, container_def_id, container_generics);
438-
combined_trait_refs.extend(std::mem::take(&mut trait_refs));
439-
trait_refs = combined_trait_refs;
440-
(generics.sinto(s), None)
441-
}
442-
}
371+
let num_trait_generics = tinfo.r#trait.hax_skip_binder_ref().generic_args.len();
372+
// Return only the method generics; the trait generics are included in `trait_impl_expr`.
373+
let method_generics = &generics[num_trait_generics..];
374+
(method_generics.sinto(s), Some(tinfo))
443375
} else {
444376
// Regular function call
445377
(generics.sinto(s), None)
446378
};
447379

448-
(def_id.sinto(s), generics, trait_refs, source)
380+
(def_id.sinto(s), generics, trait_refs, trait_impl)
449381
}
450382

451383
#[cfg(feature = "rustc")]
@@ -965,7 +897,8 @@ pub enum AggregateKind {
965897
generics.sinto(s),
966898
trait_refs,
967899
annot.sinto(s),
968-
fid.sinto(s))
900+
fid.sinto(s),
901+
)
969902
})]
970903
Adt(
971904
DefId,

frontend/exporter/src/types/thir.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ pub enum ExprKind {
627627
let tcx = gstate.base().tcx;
628628
r#trait = (|| {
629629
let assoc_item = tcx.opt_associated_item(*def_id)?;
630-
let impl_expr = self_clause_for_item(gstate, &assoc_item, generics)?;
630+
let impl_expr = self_clause_for_item(gstate, assoc_item.def_id, generics)?;
631631
let assoc_generics = tcx.generics_of(assoc_item.def_id);
632632
let assoc_generics = translated_generics.drain(0..assoc_generics.parent_count).collect();
633633
Some((impl_expr, assoc_generics))
@@ -881,12 +881,7 @@ pub enum ExprKind {
881881
args: Vec<GenericArg>,
882882
user_ty: Option<CanonicalUserType>,
883883
#[not_in_source]
884-
#[value({
885-
let tcx = gstate.base().tcx;
886-
tcx.opt_associated_item(*def_id).as_ref().and_then(|assoc| {
887-
self_clause_for_item(gstate, assoc, args)
888-
})
889-
})]
884+
#[value(self_clause_for_item(gstate, *def_id, args))]
890885
r#impl: Option<ImplExpr>,
891886
},
892887
ConstParam {

frontend/exporter/src/types/ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1327,7 +1327,7 @@ impl ClosureArgs {
13271327
parent_trait_refs: {
13281328
let parent = tcx.generics_of(def_id).parent.unwrap();
13291329
let parent_generics_ref = tcx.mk_args(from.parent_args());
1330-
solve_item_and_parents_required_traits(s, parent, parent_generics_ref)
1330+
solve_item_required_traits(s, parent, parent_generics_ref)
13311331
},
13321332
tupled_sig: sig.sinto(s),
13331333
untupled_sig: tcx

0 commit comments

Comments
 (0)