Skip to content

Commit 13ac8f9

Browse files
committed
Add an explicit Self: Trait clause to trait assoc items
This way, the special `ImplExpr::SelfImpl` is only valid within a trait declaration.
1 parent c70fa4a commit 13ac8f9

File tree

4 files changed

+41
-12
lines changed

4 files changed

+41
-12
lines changed

frontend/exporter/src/traits.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,9 @@ pub fn translate_item_ref<'tcx, S: UnderOwnerState<'tcx>>(
290290
let num_trait_generics = trait_ref.generic_args.len();
291291
generic_args.drain(0..num_trait_generics);
292292
let num_trait_trait_clauses = trait_ref.impl_exprs.len();
293-
impl_exprs.drain(0..num_trait_trait_clauses);
293+
// Associated items take a `Self` clause as first clause, we skip that one too. Note: that
294+
// clause is the same as `tinfo`.
295+
impl_exprs.drain(0..num_trait_trait_clauses + 1);
294296
}
295297

296298
let content = ItemRefContents {
@@ -386,15 +388,14 @@ pub fn self_clause_for_item<'tcx, S: UnderOwnerState<'tcx>>(
386388
def_id: RDefId,
387389
generics: rustc_middle::ty::GenericArgsRef<'tcx>,
388390
) -> Option<ImplExpr> {
389-
use rustc_middle::ty::EarlyBinder;
390391
let tcx = s.base().tcx;
391392

392393
let tr_def_id = tcx.trait_of_item(def_id)?;
393394
// The "self" predicate in the context of the trait.
394395
let self_pred = self_predicate(tcx, tr_def_id);
395396
// Substitute to be in the context of the current item.
396397
let generics = generics.truncate_to(tcx, tcx.generics_of(tr_def_id));
397-
let self_pred = EarlyBinder::bind(self_pred).instantiate(tcx, generics);
398+
let self_pred = ty::EarlyBinder::bind(self_pred).instantiate(tcx, generics);
398399

399400
// Resolve
400401
Some(solve_trait(s, self_pred))

frontend/exporter/src/traits/resolution.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ fn initial_search_predicates<'tcx>(
154154
tcx: TyCtxt<'tcx>,
155155
def_id: rustc_span::def_id::DefId,
156156
add_drop: bool,
157+
include_self_pred: bool,
157158
predicates: &mut Vec<AnnotatedTraitPred<'tcx>>,
158159
pred_id: &mut usize,
159160
) {
@@ -165,11 +166,22 @@ fn initial_search_predicates<'tcx>(
165166
use DefKind::*;
166167
match tcx.def_kind(def_id) {
167168
// These inherit some predicates from their parent.
168-
AssocTy | AssocFn | AssocConst | Closure | Ctor(..) | Variant => {
169+
dk @ (AssocTy | AssocFn | AssocConst | Closure | Ctor(..) | Variant) => {
169170
let parent = tcx.parent(def_id);
170-
acc_predicates(tcx, parent, add_drop, predicates, pred_id);
171+
// Hack: we don't support GATs well so for now we let assoc types refer to the
172+
// implicit trait `Self` clause. Other associated items get an explicit `Self:
173+
// Trait` clause passed to them so they don't need that.
174+
let include_self_pred = include_self_pred && matches!(dk, AssocTy);
175+
acc_predicates(
176+
tcx,
177+
parent,
178+
add_drop,
179+
include_self_pred,
180+
predicates,
181+
pred_id,
182+
);
171183
}
172-
Trait | TraitAlias => {
184+
Trait | TraitAlias if include_self_pred => {
173185
let self_pred = self_predicate(tcx, def_id).upcast(tcx);
174186
predicates.push(AnnotatedTraitPred {
175187
origin: BoundPredicateOrigin::SelfPred,
@@ -192,7 +204,7 @@ fn initial_search_predicates<'tcx>(
192204
}
193205

194206
let mut predicates = vec![];
195-
acc_predicates(tcx, def_id, add_drop, &mut predicates, &mut 0);
207+
acc_predicates(tcx, def_id, add_drop, true, &mut predicates, &mut 0);
196208
predicates
197209
}
198210

frontend/exporter/src/traits/utils.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ pub fn required_predicates<'tcx>(
8686
// `predicates_defined_on` ICEs on other def kinds.
8787
_ => Default::default(),
8888
};
89+
// For associated items in trait definitions, we add an explicit `Self: Trait` clause.
90+
if let Some(trait_def_id) = tcx.trait_of_item(def_id) {
91+
let self_clause = self_predicate(tcx, trait_def_id).upcast(tcx);
92+
predicates.to_mut().insert(0, (self_clause, DUMMY_SP));
93+
}
8994
if add_drop {
9095
// Add a `T: Drop` bound for every generic, unless the current trait is `Drop` itself, or
9196
// `Sized`.

test-harness/src/snapshots/toolchain__traits into-fstar.snap

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -661,9 +661,18 @@ class t_Foo (v_Self: Type0) = {
661661
f_method_f_post:v_Self -> Prims.unit -> Type0;
662662
f_method_f:x0: v_Self
663663
-> Prims.Pure Prims.unit (f_method_f_pre x0) (fun result -> f_method_f_post x0 result);
664-
f_assoc_type_pre:{| i2: Core.Marker.t_Copy f_AssocType |} -> f_AssocType -> Type0;
665-
f_assoc_type_post:{| i2: Core.Marker.t_Copy f_AssocType |} -> f_AssocType -> Prims.unit -> Type0;
666-
f_assoc_type:{| i2: Core.Marker.t_Copy f_AssocType |} -> x0: f_AssocType
664+
f_assoc_type_pre:
665+
{| i2: Core.Marker.t_Copy v_5081411602995720689.f_AssocType |} ->
666+
v_5081411602995720689.f_AssocType
667+
-> Type0;
668+
f_assoc_type_post:
669+
{| i2: Core.Marker.t_Copy v_5081411602995720689.f_AssocType |} ->
670+
v_5081411602995720689.f_AssocType ->
671+
Prims.unit
672+
-> Type0;
673+
f_assoc_type:
674+
{| i2: Core.Marker.t_Copy v_5081411602995720689.f_AssocType |} ->
675+
x0: v_5081411602995720689.f_AssocType
667676
-> Prims.Pure Prims.unit
668677
(f_assoc_type_pre #i2 x0)
669678
(fun result -> f_assoc_type_post #i2 x0 result)
@@ -672,9 +681,11 @@ class t_Foo (v_Self: Type0) = {
672681
class t_Lang (v_Self: Type0) = {
673682
f_Var:Type0;
674683
f_s_pre:v_Self -> i32 -> Type0;
675-
f_s_post:v_Self -> i32 -> (v_Self & f_Var) -> Type0;
684+
f_s_post:v_Self -> i32 -> (v_Self & v_178762381425797165.f_Var) -> Type0;
676685
f_s:x0: v_Self -> x1: i32
677-
-> Prims.Pure (v_Self & f_Var) (f_s_pre x0 x1) (fun result -> f_s_post x0 x1 result)
686+
-> Prims.Pure (v_Self & v_178762381425797165.f_Var)
687+
(f_s_pre x0 x1)
688+
(fun result -> f_s_post x0 x1 result)
678689
}
679690

680691
let f (#v_T: Type0) (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: t_Foo v_T) (x: v_T) : Prims.unit =

0 commit comments

Comments
 (0)