Stream: wg-traits

Topic: weekly meeting 2018-11-19


nikomatsakis (Nov 19 2018 at 19:01, on Zulip):

:wave: @WG-compiler-traits

nikomatsakis (Nov 19 2018 at 19:02, on Zulip):

Some quick notes:

nikomatsakis (Nov 19 2018 at 19:03, on Zulip):

Planning meeting document

nikomatsakis (Nov 19 2018 at 19:07, on Zulip):

PS @scalexm I see you r+'d #55517 — thanks =) I was thinking in the meantime that maybe I should add something to try and give a "This behavior recently changed" note on the new coherence errors

scalexm (Nov 19 2018 at 19:08, on Zulip):

@nikomatsakis yes seems good

nikomatsakis (Nov 19 2018 at 19:08, on Zulip):

I'm not 100% sure how to do that :)

nikomatsakis (Nov 19 2018 at 19:09, on Zulip):

I guess I could probably skim over the pending region obligations

nikomatsakis (Nov 19 2018 at 19:09, on Zulip):

(which we just drop on the floor presently)

nikomatsakis (Nov 19 2018 at 19:09, on Zulip):

and look for any that involve a placeholder

nikomatsakis (Nov 19 2018 at 19:09, on Zulip):

@Alexander Regueiro, btw, you around? I wanted to sync up with you at some point

nikomatsakis (Nov 19 2018 at 19:10, on Zulip):

so @scalexm in terms of "how to actually integrate"

nikomatsakis (Nov 19 2018 at 19:10, on Zulip):

how's that going?

scalexm (Nov 19 2018 at 19:11, on Zulip):

@nikomatsakis I think I'm going to hit some coherence problems actually

scalexm (Nov 19 2018 at 19:11, on Zulip):

because the TraitEngine trait is defined in librustc, and the chalk types are defined in librustc_traits

nikomatsakis (Nov 19 2018 at 19:11, on Zulip):

bah

nikomatsakis (Nov 19 2018 at 19:11, on Zulip):

we could just move them

nikomatsakis (Nov 19 2018 at 19:12, on Zulip):

or we can do the "bridge trick" I guess

nikomatsakis (Nov 19 2018 at 19:12, on Zulip):

well, I'm not sure I know what the problem is yet

scalexm (Nov 19 2018 at 19:12, on Zulip):

ok so I have some additional questions for that work anyway :p

nikomatsakis (Nov 19 2018 at 19:13, on Zulip):

carry on :)

Josh Huber (Nov 19 2018 at 19:14, on Zulip):

I've had some personal stuff come up in the past couple weeks, and it's been eating all of my free-time and brain space. If someone needs to steal #55097 to make progress, that's totally great. If I manage to get back to it before then, also great. I am not worried about finding more things to work on... :)

nikomatsakis (Nov 19 2018 at 19:15, on Zulip):

@uberjay thanks for mentioning :)

scalexm (Nov 19 2018 at 19:15, on Zulip):

well basically this is about how long the ChalkContext will live

scalexm (Nov 19 2018 at 19:15, on Zulip):

since it carries a TyCtxt<'cx, 'gcx, 'gcx>, I guess it will live only as long as a call to e.g. TraitEngine::select_all_or_error?

nikomatsakis (Nov 19 2018 at 19:17, on Zulip):

presumably

nikomatsakis (Nov 19 2018 at 19:17, on Zulip):

this is at least how I imagined it initially

nikomatsakis (Nov 19 2018 at 19:18, on Zulip):

but I guess longer term we would like it to persist

nikomatsakis (Nov 19 2018 at 19:18, on Zulip):

so we can leverage the tables for caching

nikomatsakis (Nov 19 2018 at 19:19, on Zulip):

TBH, I hadn't really planned this part out precisely. I considered either creating a "global" ChalkContext, or maybe trying to factor out the persistent part ...

nikomatsakis (Nov 19 2018 at 19:19, on Zulip):

I guess refactor such that it doesn't need to carry a TyCtxt

tmandry (Nov 19 2018 at 19:21, on Zulip):

on rustc guide stuff, I just need to set a date to knock out a bunch of the smaller tasks

nikomatsakis (Nov 19 2018 at 19:21, on Zulip):

but I think I figured that for the first version we'd just recreate context all the time

tmandry (Nov 19 2018 at 19:21, on Zulip):

I have interviews going on, so not sure when exactly it will happen, but it will :D

tmandry (Nov 19 2018 at 19:22, on Zulip):

also on the guide, I am thinking more about how to _reduce dependence_ between sections

tmandry (Nov 19 2018 at 19:22, on Zulip):

i.e. it would be great if you could go to a random section in the traits chapter, and the beginning introduces the problem enough to where you can understand it with minimal context

nikomatsakis (Nov 19 2018 at 19:23, on Zulip):

yeah, that can be a challenge

tmandry (Nov 19 2018 at 19:23, on Zulip):

I'm not sure how feasible it is, but my feeling is that it would make it dramatically easier to get started / pick things up after awhile

tmandry (Nov 19 2018 at 19:24, on Zulip):

anyway, something to be thinking about perhaps

tmandry (Nov 19 2018 at 19:24, on Zulip):

I'm not too worried about "adding noise" for everyone who already knows it, because you can just skim the intro and it gives you a slight confidence boost for the rest of the section :)

nikomatsakis (Nov 19 2018 at 19:25, on Zulip):

yeah

nikomatsakis (Nov 19 2018 at 19:25, on Zulip):

I think that's a really good point

nikomatsakis (Nov 19 2018 at 19:25, on Zulip):

at minimum, if we can kind of "chart out" the things you need to read

nikomatsakis (Nov 19 2018 at 19:25, on Zulip):

i.e., provide a few links to a the most important places

nikomatsakis (Nov 19 2018 at 19:25, on Zulip):

vs just assuming you've read everything

scalexm (Nov 19 2018 at 19:26, on Zulip):

@nikomatsakis ok so second thing I'm not sure to understand is when you currently call tcx.param_env(def_id) where def_id refers to a function say fn foo<'a, T>() where T: 'a, in the ParamEnv you get as a result, the 'a lifetime is referred to with an ReEarlyBound right?

tmandry (Nov 19 2018 at 19:26, on Zulip):

yeah, that helps. but if we are linking to several blog-post-length sections, it can be intimidating :)

nikomatsakis (Nov 19 2018 at 19:27, on Zulip):

@scalexm yes that is correct

nikomatsakis (Nov 19 2018 at 19:27, on Zulip):

more generally, there are a set of early-bound things (which include all types)

nikomatsakis (Nov 19 2018 at 19:27, on Zulip):

those are identified by the generics_of(def_id)

scalexm (Nov 19 2018 at 19:28, on Zulip):

ok but then in typeck_tables_of the code first gets the param_env for the fn with def-if def_id and signature fn_sig, and then calls tcx.liberate_late_bound_regions(def_id, &fn_sig);

scalexm (Nov 19 2018 at 19:28, on Zulip):

so what I don't understand it that there seems to be ReEarlyBound regions in the param_env, but ReFree regions in the fn_sig

nikomatsakis (Nov 19 2018 at 19:29, on Zulip):

right

nikomatsakis (Nov 19 2018 at 19:29, on Zulip):

so

nikomatsakis (Nov 19 2018 at 19:29, on Zulip):

I actually forget if we changed this, I guess not

nikomatsakis (Nov 19 2018 at 19:29, on Zulip):

let me quickly review the code :)

nikomatsakis (Nov 19 2018 at 19:30, on Zulip):

ok so

nikomatsakis (Nov 19 2018 at 19:30, on Zulip):

we have this split (iirc)

nikomatsakis (Nov 19 2018 at 19:30, on Zulip):

early-bound things (types, regions) we don't change, we just know from context

nikomatsakis (Nov 19 2018 at 19:30, on Zulip):

if something is bound or not

nikomatsakis (Nov 19 2018 at 19:31, on Zulip):

basically, when we first access a term (e.g., the signature), it contains references to early-bound things in it (ReEarlyBound, TyParam). If those should be instantiated existentially, then the first thing we do is to substitute

nikomatsakis (Nov 19 2018 at 19:31, on Zulip):

when otoh we are type-checking the function (or impl, whatever), we leave them in place

nikomatsakis (Nov 19 2018 at 19:31, on Zulip):

and then they are treated as placeholders

nikomatsakis (Nov 19 2018 at 19:31, on Zulip):

does that sound right so far, @scalexm ?

scalexm (Nov 19 2018 at 19:32, on Zulip):

@nikomatsakis yes that sounds right

nikomatsakis (Nov 19 2018 at 19:32, on Zulip):

otoh, for late-bound things, we sort of do the opposite :)

nikomatsakis (Nov 19 2018 at 19:32, on Zulip):

they are stored in "bound form"

nikomatsakis (Nov 19 2018 at 19:32, on Zulip):

so when you reference, you get back a Binder<Term>, which you can just use "as is"

nikomatsakis (Nov 19 2018 at 19:33, on Zulip):

but when you want to type-check the fn, we invoke liberate_late_bound_regions, which basically replaces the bound regions with placeholders (making them "free", in some sense -- "liberating" them)

nikomatsakis (Nov 19 2018 at 19:33, on Zulip):

they are free in the sense that they are not bound in the term, anyway

nikomatsakis (Nov 19 2018 at 19:34, on Zulip):

I'm not wild about this scheme, but it reflects the "essence" of the early- vs late-bound distinction:

nikomatsakis (Nov 19 2018 at 19:34, on Zulip):

early-bound things are always fully instantiated when you reference something, so they never appear bound in a type

nikomatsakis (Nov 19 2018 at 19:34, on Zulip):

but late-bound things do appear bound in the resulting type, and are instantiated later (e.g., at the point of calling a function)

scalexm (Nov 19 2018 at 19:35, on Zulip):

mmh ok so if I have a function say

fn foo<'a>() {
    let x: &'a i32 = ...;
}

then the type of x as seen from inside the body of foo will use an ReEarlyBound?

scalexm (Nov 19 2018 at 19:36, on Zulip):

I mean during typecheck

nikomatsakis (Nov 19 2018 at 19:36, on Zulip):

well

nikomatsakis (Nov 19 2018 at 19:37, on Zulip):

that particular example is I think going to be late-bound

nikomatsakis (Nov 19 2018 at 19:37, on Zulip):

let me give you a canonical example :)

nikomatsakis (Nov 19 2018 at 19:37, on Zulip):
fn foo<'early, 'late>(x: &'late Foo, y: &'early Bar) -> &'late u32
where Bar: SomeTrait<'early> { ... }
nikomatsakis (Nov 19 2018 at 19:37, on Zulip):

in this case, 'early will (in typeck) be represented by an ReEarlyBound

nikomatsakis (Nov 19 2018 at 19:38, on Zulip):

fn_sig(foo) will give back a Binder<FnSig>, where the FnSig references 'early represented using an ReEarlyBound, but references 'late with a debruijn depth of INNERMOST

nikomatsakis (Nov 19 2018 at 19:39, on Zulip):

when type-checking the body then, the ReBound for 'late would be converted to a ReFree

nikomatsakis (Nov 19 2018 at 19:40, on Zulip):

The rule for what is early vs late is something like this: we prefer late, but we use early if:

tmandry (Nov 19 2018 at 19:40, on Zulip):

relevant docs for those trying to follow along.. free-vs-bound, RegionKind (early vs late bound), Binder, chalk Context :)

scalexm (Nov 19 2018 at 19:41, on Zulip):

@nikomatsakis ok I see, then why couldn't we just eagerly replace all parameter regions with placeholders or something during typeck?

nikomatsakis (Nov 19 2018 at 19:41, on Zulip):

one way to think about it is, if you were to write a

impl<'early, 'late> FnMut<ArgumentTypes> for SomeFunctionType
where WC {
    type Output = ...;
}

would the 'early have to be appear in the SomeFunctionType for this to be legal?

nikomatsakis (Nov 19 2018 at 19:41, on Zulip):

(if so, it is early)

nikomatsakis (Nov 19 2018 at 19:42, on Zulip):

@scalexm we actually used to do that, we used to use ReFree for all regions

nikomatsakis (Nov 19 2018 at 19:42, on Zulip):

it was effectively a U0 "placeholder", in this role

nikomatsakis (Nov 19 2018 at 19:42, on Zulip):

@eddyb refactored it some time back

nikomatsakis (Nov 19 2018 at 19:42, on Zulip):

I'd like to eventually move back to that scheme, but treating types + regions analogously

scalexm (Nov 19 2018 at 19:43, on Zulip):

it seems that now that we have Placeholder types we could do that

nikomatsakis (Nov 19 2018 at 19:43, on Zulip):

yeah, plausibly

nikomatsakis (Nov 19 2018 at 19:43, on Zulip):

it'd be good to revisit the PR where @eddyb made the change

nikomatsakis (Nov 19 2018 at 19:43, on Zulip):

to try and remember the motivations

nikomatsakis (Nov 19 2018 at 19:43, on Zulip):

there might be some runtime cost

nikomatsakis (Nov 19 2018 at 19:43, on Zulip):

er, compile-time

nikomatsakis (Nov 19 2018 at 19:43, on Zulip):

from doing more substitutions etc

scalexm (Nov 19 2018 at 19:44, on Zulip):

(in my environment query which returns a traits::Environment, the traits::Environment just refers to BoundVar things so that we could substitute them with anything we want)

nikomatsakis (Nov 19 2018 at 19:44, on Zulip):

(in general, I am not super happy with the whole early vs late distinction; though removing it altogether is not entirely backwards compatible)

nikomatsakis (Nov 19 2018 at 19:44, on Zulip):

(but maybe something we could get away with)

nikomatsakis (Nov 19 2018 at 19:44, on Zulip):

in short, once we have higher-ranked trait-bounds over types, everything could plausibly become late-bound

nikomatsakis (Nov 19 2018 at 19:45, on Zulip):

(er, is this true...maybe not...)

nikomatsakis (Nov 19 2018 at 19:45, on Zulip):

that may not be true actually :)

nikomatsakis (Nov 19 2018 at 19:46, on Zulip):

e.g., fn foo<'a>() -> &'a usize, I believe this cannot be late-bound -- if you go back to my impl, it would be

impl<'a> Fn<()> for Foo {
    type Output = &'a usize;
}

which is illegal. The 'a must be "constrained" by some input type to the trait

nikomatsakis (Nov 19 2018 at 19:46, on Zulip):

otherwise, you could "project" <Foo as Fn>::Output to different types each time

nikomatsakis (Nov 19 2018 at 19:47, on Zulip):

(does that make sense? I'm not sure if that impl analogy is clear to others :)

scalexm (Nov 19 2018 at 19:47, on Zulip):

it makes sense to me at least

nikomatsakis (Nov 19 2018 at 19:48, on Zulip):

anyway I'd still think we might be able to erase the distinction in some sense, such that they are treated more analogously. i.e., there is one set of parameters (as you would have on the impl...) but only some of them are "constrained" to be part of the resulting self type, and hence cannot be higher-ranked

nikomatsakis (Nov 19 2018 at 19:48, on Zulip):

I haven't really thought hard about this

nikomatsakis (Nov 19 2018 at 19:48, on Zulip):

well I guess you could imagine that the resulting type of a function has all its parameters

nikomatsakis (Nov 19 2018 at 19:49, on Zulip):

but maybe has a for binder in it

nikomatsakis (Nov 19 2018 at 19:49, on Zulip):

anyway

nikomatsakis (Nov 19 2018 at 19:49, on Zulip):

way far afield

nikomatsakis (Nov 19 2018 at 19:49, on Zulip):

tl;dr I think @scalexm there is room to represent things better, but that's how it works today...

scalexm (Nov 19 2018 at 19:50, on Zulip):

@nikomatsakis ok then I think I won't try to do anything clever for now and just use the same lifetimes in traits::Environment as it would be in the ty::ParamEnv analog

nikomatsakis (Nov 19 2018 at 19:50, on Zulip):

seems good

nikomatsakis (Nov 19 2018 at 19:52, on Zulip):

gotta run to another meeting :)

Alexander Regueiro (Nov 19 2018 at 20:08, on Zulip):

hey @scalexm

Alexander Regueiro (Nov 19 2018 at 20:09, on Zulip):

how's your work going? started on serious integration of chalk stuff yet?

Alexander Regueiro (Nov 19 2018 at 20:22, on Zulip):

ooh, I see in the notes you've been doing some work on that on your local branch :-)

Alexander Regueiro (Nov 19 2018 at 20:22, on Zulip):

super

Alexander Regueiro (Nov 19 2018 at 21:15, on Zulip):

@nikomatsakis gone for the day?

Alexander Regueiro (Nov 20 2018 at 16:02, on Zulip):

@nikomatsakis let me know when you're around for a catch-up

DPC (Nov 20 2018 at 19:06, on Zulip):

@nikomatsakis if you are looking for someone to continue the work on #55097, I'm available :grinning:

nikomatsakis (Nov 20 2018 at 19:08, on Zulip):

@DPC go for it! Unless @scalexm has already done it

scalexm (Nov 20 2018 at 19:10, on Zulip):

@DPC yeah I’ve done it in a local branch :p

DPC (Nov 20 2018 at 20:29, on Zulip):

Ah no problems

Last update: Nov 12 2019 at 15:30UTC