Stream: t-compiler

Topic: substitutions question


Nora (Oct 24 2018 at 15:16, on Zulip):

Example: f<T:Trait>(a:T) {a.m()}. If I have a substitution T → A for f, and substitution Self → T (rustc::ty::subst::Substs) for the call to Trait::a from f. How can I combine the two substitutions to end up with a.m substitution (Self → A)?

Wesley Wiser (Oct 24 2018 at 15:37, on Zulip):

I think you want Substs::rebase_onto() but I'm not sure https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/subst/type.Substs.html#method.rebase_onto

Nora (Oct 24 2018 at 15:58, on Zulip):

I thought about that too, but I can't figure out what to put in source_ancestor and target_substs.

nikomatsakis (Oct 24 2018 at 16:02, on Zulip):

@Nora I'm a bit confused by your question

nikomatsakis (Oct 24 2018 at 16:02, on Zulip):

rebase_onto is used when you have the substitutions from a trait call and you know the substitutions from the specific impl that is implementing the trait

nikomatsakis (Oct 24 2018 at 16:02, on Zulip):

is that the situation you have?

Nora (Oct 24 2018 at 16:07, on Zulip):

@nikomatsakis I don't think that is my situation, I have the substitutions of f from its caller, and I have the substitutions of callee m inside f.
I want to get the substitutions of m in the context of the f with the given substitutions from its caller. Does this make sense?

nikomatsakis (Oct 24 2018 at 16:21, on Zulip):

that is much easier

nikomatsakis (Oct 24 2018 at 16:22, on Zulip):

you just need to apply one set of substitutions to the other

Nora (Oct 24 2018 at 16:23, on Zulip):

How?

nikomatsakis (Oct 24 2018 at 16:23, on Zulip):

@Nora e.g.,

let (callee, caller_subst) = ...;
let (value, callee_subst) = get_value(callee);

// now we have the type of `value` expressed in terms of its *own* generic parameters
let value_ty = tcx.type_of(value);

// now we have the type of `value` expressed in terms of the *callee's* generic parameters
let value_ty = value_ty.subst(callee_subst);

// now we have it in terms of the *caller's* generic parameters
let value_ty = value_ty.subst(caller_subst);
nikomatsakis (Oct 24 2018 at 16:24, on Zulip):

or you could compose the substitutions first

nikomatsakis (Oct 24 2018 at 16:24, on Zulip):

e.g.,

// callee_subst was (ValueType -> CalleeType)
// caller_subst is (CalleeType -> CallerType)
// composed_subst is (ValueType -> CallerType)
let composed_subst = callee_subst.subst(caller_subst);
nikomatsakis (Oct 24 2018 at 16:25, on Zulip):

hopefully I got that order right :)

nikomatsakis (Oct 24 2018 at 16:25, on Zulip):

I find the first easier to see

Nora (Oct 24 2018 at 16:32, on Zulip):

Thank you! The second one works.

Nora (Nov 04 2018 at 19:43, on Zulip):

@nikomatsakis I need a little more help with the substitution. I have the def_id if a method implementation, and I need to get all substitutions coming from the impl.
Consider the code:
pub trait RngCore {
fn next_u32(&mut self);
}
pub trait BlockRngCore {
type Item;
fn generate(&mut self);
}
pub struct BlockRng<R: BlockRngCore> {
pub core: R,
}

impl<R: BlockRngCore> BlockRng<R> {
pub fn generate_and_set(&mut self) {
self.core.generate();
}
}

impl<R: BlockRngCore<Item=u32>> RngCore for BlockRng<R>
{
fn next_u32(&mut self) {
self.generate_and_set();
}
}

I have the def_id of next_u32, I need to find somehow the substition R--> BlockRngCore<Item=u32>, so I can propagate it. I looked around for a while and I can't figure it out.

DPC (Nov 04 2018 at 21:49, on Zulip):

you can use markdown to paste code (wrap it in 3 backticks)

Nora (Nov 05 2018 at 10:40, on Zulip):

Here is the code properly displayed:

pub trait RngCore {
    fn next_u32(&mut self);
}
pub trait BlockRngCore {
    type Item;
    fn generate(&mut self);
}
pub struct BlockRng<R: BlockRngCore> {
    pub core: R,
}

impl<R: BlockRngCore> BlockRng<R> {
    pub fn generate_and_set(&mut self) {
        self.core.generate();
    }
}

impl<R: BlockRngCore<Item=u32>> RngCore for BlockRng<R>
{
    fn next_u32(&mut self)  {
        self.generate_and_set();
    }
}
Last update: Nov 22 2019 at 04:40UTC