Skip to content

(WIP) Trait specs#127

Draft
Aurel300 wants to merge 22 commits intorewrite-2023from
feature/trait-specs
Draft

(WIP) Trait specs#127
Aurel300 wants to merge 22 commits intorewrite-2023from
feature/trait-specs

Conversation

@Aurel300
Copy link
Owner

@Aurel300 Aurel300 commented Jan 26, 2026

For each trait:

  • const generics
  • For each of its associated functions (with or without a default impl):
    • symbolic/abstract pre, post functions
    • same for pledges
    • (later?) separate functions to combine the full base pre/postconditions
    • axioms to connect symbolic functions to base specs
    • stub method which uses symbolic functions
    • pure functions
  • For associated functions with a default implementation:
    • method to show the base specs hold for this implementation
      • (method emitted, make sure base specs are used)

For each trait impl:

  • const generics
  • For each associated function (with a refined spec?)
    • axioms to connect symbolic functions to refined specs
    • methods to verify behavioural subtyping holds (separate for pre, post, pledges for precise error tracking)
    • method to show the refined? specs hold for this implementation
      • (method emitted, but need to use refined specs)

If using generic encoding:

  • call stub method instead of trait method
  • pure functions?

If monomorphising (which gets us better error tracking):

let trait_method_substs = ty::List::identity_for_item(tcx, trait_method_def_id);
let trait_method_substs =
impl_method_substs.rebase_onto(tcx, trait_def_id, trait_method_substs);
let call_trait_substs =
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zgrannan I think you changed this last? Any chance you remember why if so? I'm not sure if the version using rebase_onto was already introduced in v2 at any point otherwise. V1 uses the version I reverted to.

(The issue was that resolving a trait method call resulted in reporting [Self/#0] as the trait substs instead of [Impl] (the implementor of the trait) as expected.)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My recollection is that the V1 logic did not do the correct substitution. For example, if we have:

trait Trait<T> {
    fn f<U>(self)
}

impl<X,Y> Trait<X> for Impl<X, Y> {
  fn f<U>(self){}
}

impl Impl<u8, u32> {
    fn baz<U>(self){
        self.f()
    }
}

and we called this method with the def id / substs for the call to self.f() in baz, then we'd have
the identity of Trait::f is [Self, T, U]
the args for the call are [Impl<u8,u32>,u8,u32,U]
the identity of Trait::f is [Self, T, U]
this method would be expected to return the substitution [Impl<u8, u32>, u8, U], corresponding to Self=Impl<u8,u32>, T = u8, U=U

However, with the current logic I think the output would try to instantiate
[Self, T, U] with the substs [Impl<u8,u32>,u8,u32,U]. I'm not sure if that works due to the arity mismatch but even ignoring that the result would I think be [Impl<u8,u32>, u8, u32].

My understanding is that rebase_onto implements what find_trait_method_substs is intended to do: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.GenericArgs.html#method.rebase_onto

@Aurel300 Aurel300 force-pushed the feature/trait-specs branch from 21e3688 to a7c4fb4 Compare February 2, 2026 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants