Const generics

This is a new const generics RFC which addresses the issues around equality between const variables that were raised in this internals thread.
Rendered

nits:

I didn't actually talk about the compilation model in this RFC, should probably specify that these params are monomorphized.
Consts as inputs to traits? Unclear to me what the compilation is for that. Monomorphize the traits into distinct traits?

Consts as inputs to traits? Unclear to me what the compilation is for that. Monomorphize the traits into distinct traits?

What does it mean to "monomorphize" a trait? If const parameters don't match the behavior of type parameters in some context then something has gone wrong with the semantics.

I'm not sure what I was thinking, its the same as multiparameter traits - we just need to create a new instance during trans for every product of types and consts. That is <T as Foo<0>>::foo generates a different from from <T as Foo<1>>::foo, but this is no different from <T as Foo>::fooand<T as Foo>::foo`.

Also, where does MIRI fit into this? Is it just that when MIRI comes around consts will suddenly gain a lot of functionality?

Also, where does MIRI fit into this? Is it just that when MIRI comes around consts will suddenly gain a lot of functionality?

Yes, MIRI is orthogonal. The RFC has a comment in it which says that for the sake of this RFC we just assume integer arithmetic works; we're drawing a distinction between the range of expressions that can be evaluated at compile time (MIRI and const fn) and making types depend on constants (const generics).

:+1: :tada:  Big support for this RFC and that it tries to not solve every issue related to const generics, but instead goes the slim but faster path, by avoiding to do anything about orthogonal issues.
I too would like to see many of the proposed extensions happen (like unifying {1+N} with {N+1}), but if they were added with this RFC it would increase chance for this RFC to be merged at a later time, and the RFC to hang in unstable limbo for longer, because of some little edge case or because it would require MIRI. I rather have the main functionality merged now, and stabilized fast, and the orthogonal issues looked at separately. Therefore, I'm very glad of the direction this RFC is going!
:heart: Many thanks @withoutboats for championing this RFC!

Question: does N - 1 unify with usize::MAX?

@clarcharr where do you see that?

@clarcharr Do you mean 0 - 1? It errors today.

@mark-i-m (and probably many others)

Why do you say that [attempting to unify abstract const expressions will hopefully not be all that common]?

I guess what I meant to say is that right now we're targeting a much more conservative use case than one in which you would need to unify abstract const expressions frequently.
I'm certain, since its permissible, that people will be writing signatures like fn(T<N>) -> T<{N + 1}>, and find themselves frustrated by the limitations. But because its so limited, people won't get far enough to produce libraries that people are actually trying to use and then running into these issues. That is, you'll get these issues as you're experimenting with the feature, but I am hopeful they won't be rippling around the ecosystem frustrating people who are just trying to do bog standard things in Rust.
Obviously a lot of people have use cases in which they'd like this to be able to use this feature in that more advanced way, and I believe we'll probably get there eventually. But right now we need a solution to making basic things like arrays a first class part of the language, and we don't want to bite off too much at once.

Summary of the outstanding issues AFAIK:

Exact wording on when we unify abstract const expressions right now.
How do we handle when names in both the const and type kind namespaces are in scope right now.
Default parameters & ordering rules.

@withoutboats
Thanks! That makes sense. But in that case, is there a compelling use case for including expressions in this RFC at all? It seems that they add non-trivial complexity without significant benefits in their current form. Moreover, I expect that a lot of people will try to do more advanced stuff and be disappointed...

@mark-i-m You can't not have them because array types already have them and they'd get abused instead.

@mark-i-m I didn't clarify that well enough; basically, I'm asking about a few of the edge cases for instantiating constant generics (e.g. N + 1) with actual constants.
If we have a definition like this:
struct Test<const N: usize>;
impl<const N: usize> Test<{N - 1}> {
    fn val(&self) -> usize { N }
}

then would this be valid?
let test: Test<usize::MAX> = Test;
println!("{}", test.val());

what would it print? Does this sort of arithmetic wrap, saturate, or generate an error?

@clarcharr I forgot to call this out in the RFC, but it follows from the treating expressions like that as "projections" that that impl is invalid, it would be like writing impl<I: Iterator> Test<I::Item> today.

But because its so limited, people won't get far enough to produce libraries that people are actually trying to use and then running into these issues.

I feel like you're underestimating people's willingness to pick at crumbs to make the compiler do things it's not supposed to be capable of :)
But it can't be helped.  Starting conservative is the right approach.

@eddyb

You can't not have them because array types already have them and they'd get abused instead.

Can't we just reject abstract const expressions other than identity expressions? Arrays don't have abstract const expressions today because there are no abstract const expressions. I wonder if that wouldn't be a better UX than allowing them but making them essentially useless?
Possibly we could just feature gate it separately so some people could keep experimenting with it as we improe the unification logic.

@withoutboats @eddyb  That's more in the line of what I was thinking of...

Arrays don't have abstract const expressions today because there are no abstract const expressions.

You want to back down on making associated constants with type parameters work? FWIW from an implementation perspective, all expressions (even non-abstract ones upon inspection) have to be made abstract in order for bounds-in-scope in them to be computable.

To expand on my previous comments, these have identical implementation requirements (short of parsing, I suppose) and are equivalent in power:
type Y<const N: usize> = X<{N + 1}>;

type Y<const N: usize> = X<[(); N + 1]>;

trait Add1<const N: usize> {
    const OUT: usize = N + 1;
}
impl<const N: usize> Add1<N> for () {}
type Y<const N: usize> = X<[(); <() as Add1<N>>::OUT]>;

@eddyb I'm just trying to get a good UX. Basically I think we inevitably have to make sure that {X + 1} unifies with another {X + 1} (that is, if they are AST-identical expressions at least). From what I've understand that you've said, neither of these things would work:
// This would be a 'different' return type:
fn foo<const N: usize>(_: X<N>) -> X<{N + 1}> {
     X::<{N + 1}>::default()
}

// No impl could ever meet this bound
T: Add<N, OUT = {N + 1}>

Am I wrong? This is clearly a terrible UX and so yes, I suspect it would be better to restrict these expressions until they actually work the way users expect them to.
When it comes to also implementing transforms on the basis of the properties of these operations - that may be equally easy to implement, but it has significantly more major UX concerns because of the cliff of functionality represented by user defined types. Since obviously we can only guarantee that Add is associative and commutative for built-in addition operations, wether N + 1 unifies with 1 + N depends on the type of N, which is troubling.
Users will them probably want us to provide them with a way to declare their impls are associative, commutative, reflexive, transitive, etc, which raise huge UX questions of their own.
My point is that performing transforms that go beyond evaluating non-abstract subexpressions is a sort of Pandora's Box of language complexity and I'd rather avoid settling that, but I do feel that two different {N + 1} expressions ought to unify if we're going to allow you to instantiate variables in that way.

@withoutboats Okay, I just checked, and the MIR for N + 1 would look like this:
    let mut _0: usize;                   // return pointer
    let mut _1: (usize, bool);

    bb0: {
        _1 = CheckedAdd(N, const 1usize);
        assert(!(_1.1: bool), "attempt to add with overflow") -> bb1;
    }

    bb1: {
        _0 = (_1.0: usize);
        return;
    }

So it is plausible that we could "unify" MIR, only "recursing" on constant paths (N or T::X).
However, that would let you unify {N / 2} with {M / 2}, resulting in N = M.
That seems risky IMO, as N = 2k and M = 2k + 1 is also a valid solution, but I think we do something similar for associated types. I really want @nikomatsakis to comment on this.

I think we're speaking past each other to some extent; I don't want to be able to move backwards from a projection, I just want to be able to unify two projections that are identical if we've already unified the variables they're dependent on. I'd like these to behave the same as a T::Assoc projection; you never use T::Assoc == U::Assoc to unify T == U.
Stepping back from the implementation, in my mental model you treat every expression as equivalent to an anonymous constraint, and recognize that two expressions that form the same syntax tree are the same constraint. Possibly we make this a recursive construction, so N + (1 + 1) is roughly:
<N as Add<1 as Add<1>::Out>>::Out

Then we are able to 'normalize' 1 as Add<1>::Out to 2 and therefore this is <N as Add<2>>::Out, which unifies with any other N + 2 expression.
However even that seems unnecessary as the first pass, and I'd be happy to only unify N + (1 + 1) with other expressions that are parsed identically to N + (1 + 1) (so modulo whitespace). But if we don't at least do that I'm concerned users won't be able to form a mental model.

you never use T::Assoc == U::Assoc to unify T == U.

Hmm, I wasn't sure about this, that's why I pinged @nikomatsakis.

I just want to be able to unify two projections that are identical if we've already unified the variables they're dependent on

There seems to be some confusion here: the question isn't about unifying const parameter "names" ({N / 2}</*N=*/N> and {M / 2}</*M=*/M>) - but rather unifying const inference variables  ({N / 2}</*N=*/$1> and {M / 2}</*M=*/$2>).
Should $1 = $2? Clearly N = M is unknowable a generic context (we don't have = bounds).
But inference variables don't have the same "fixed identity" to take advantage of.

Unifying constants

I think a decent compromise would be to only allow non-closed const expressions in associated constants, and not let them occur in code.
So you could write
trait UsizeAdd<const N: usize, const M: usize> {
    const Out: usize;
}

impl<const N: usize, const M: usize> UsizeAdd for usize {
    const Out: usize = N + M;
}

fn foo<N>(n: N) -> <usize as UsizeAdd<N, 1>>::Out { /* .. */ }
```? (Also, some form of aliases to allow making this `UsizeAdd<N, M>?`)?

That "solves" the unification problem - an instance of an associated constant only unifies with itself.

@arielb1 On IRC I accidentally stumbled upon what I think @nikomatsakis calls "nominal associated types" - that is, how <T as Trait>::Assoc (where T is specifically a type parameter) is an "unique type".

In his original Pi-types RFCs here and here @ticki had formally specified the typing rules for abstract const expressions (IIUC). I don't know anything about the implementation of the compiler's inference system, but would it not help to define exactly what/how we want to unify these expressions in a similar way? It would at least give a very well specified set of things that we want to do in this RFC.

@mark-i-m I don't believe the algorithm for unifying the expressions themselves should be done at the AST level, but rather MIR (which expresses the entire computational content of the expression more accurately), and unifying parametrized uses of expressions has to be done like associated types to be sound.

@withoutboats i sort of wish you'd expand on the alt. syntax a bit: why not separate consts from types with a ;? it would be more like array syntax.
Also, the How We Teach This section doesn't have any explanation of How We Teach This. The first paragraph says "it's a big feature and needs docs in the usual places", and the second paragraph says "it's an advanced feature, and we shouldn't introduce it to newbies". OK, but we still need documentation; so, what should that look like?

@mrhota

why not separate consts from types with a ;? it would be more like array syntax.

I was originally in favor of the ; too, but doesn't it strike you as a bit ugly if consts are separated with a ; but lifetime parameters are not? Another alternative is to make all const generics start with some prefix (like lifetimes are preceded with an apostrophe), but then we get to bikeshedding about what the best syntax is... My guess is this was probably discussed at length on the IRC thread..

OK, but we still need documentation; so, what should that look like?

:+1: I agree... I imagine this would end up being a chapter in the book or something, right?

@withoutboats very exited! I'm wondering about kind polymorphism. I assume full kind polymorphism won't be available, but a lang-item struct PhantomConstData<T, const x: T>(); would be nice.

@Ericson2314 what are the use cases you have in mind for that?
It reminds me that there's an unresolved question about variance here. For lifetimes and types we require that thery appear in the body of the type so we can use that for variance; should we do the same thing here (in case consts ever have a subtyping relationship between them)? I don't think we should, @eddyb thought otherwise, but it would introduce a need for PhantomData

Ah variance, and I forget why we had phantom data in the first place.
It occurred to be that if T <: U and x != y, we should not
conclude PhantomConstData<T, x> != PhantomConstData<U, y> because
upcasted x might in fact equal y. OTOH, I'm not sure if we could every arrive at the T <: U so this might be a non-issue.
I suppose requiring the phantom data would be conservative, and symmetric with the rest of the language.

@withoutboats Do you have any example in mind of two constants which we might someday want to have a subtyping relationship between? Constants are values, not types, and it seems to me that values are basically always distinct from one another, but maybe I'm not thinking hard enough.

@glaebhoerl I don't, I think @eddyb might. I'm very wary of the idea, which is why I sort of favor just ruling it out.

I don't think I had an example, not even with full-on refinement types. If nobody else minds treating value subtyping as impossible, then I don't either.

Identity relation is a trivial subtyping relation, isn't it? Other than identity, no, can't think of anything either.

0..5 could be reasonably treated as a subtype of 0..4. ([0, 5) is [0, 4) "and more", just as Cat is Animal "and more").
To what end you would apply this, I could not say. I guess you could hack the type system to do bounds checks for you...? Generally seems like a bad idea.

I feel very confident that we will never do something like this. I won't add any support for future variance extensions to the RFC.

@Gankro That's the refinement types I was talking about and it still applies to types, not values.
That is, 3usize could be considered the refinement of usize, which has one value, 3, and is a subtype of 0..5usize which is a subtype of usize.
The values are still elements of usize, and there is no subtyping relationship between them.

Question about monomorphisation; let's say that we make a generic version of SmallVec like this:
pub struct SmallVec<T: Copy, const N: usize> {
    len: usize,
    buf: [T; N],
}
impl<T, const N: usize> {
    fn push(&mut self, val: T) -> bool {
        if self.len < self.buf.len() {
            self.buf[self.len] = val;
            self.len += 1;
            true
        } else {
            false
        }
    }
}

Would a version of push be monomorphised for every N that's used?

@clarcharr That was my impression, but I imagine in most cases it wouldn't be that bad. Do you have a particularly problematic use case in mind?

@mark-i-m I guess part of my hope is that there could be some way to use const generics to instantiate custom ZSTs, but I suppose that that's probably far out of scope.

Hmm.... Could you give an example?
On Jun 9, 2017 11:32 PM, "Clar"<EMAIL_ADDRESS>wrote:

@mark-i-m https://github.com/mark-i-m I guess part of my hope is that
there could be some way to use const generics to instantiate custom ZSTs,
but I suppose that that's probably far out of scope.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/rust-lang/rfcs/pull/2000#issuecomment-307539001, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AIazwGPY3nuyvZQ7efhEuvMtt8nRtIgTks5sCg47gaJpZM4NYoOH
.

Ditto on example. It's already possible to have custom DSTs by composition (having DST as last struct member). It would be great if it didn't have to be just the last member, and even greater to have the possibility of DST enums, but how would a parametric type be better than the old DST array in a struct?

Wait, I get it. One could create a value with static constant parameter and then upcast the reference to DST by stripping the constant from the type. Interesting.

Basically I'm wondering if you could make this:
pub struct Dst<T> {
    len: usize,
    buf: [T],
}

Somehow arrive from this:
pub struct St<T, const N: usize> {
    len: usize,
    buf: [T; N],
}

@clarcharr I'm not really a fan of converting the static value into a dynamic one. One of the big advantages of knowing the value at compile time is that you know it at compile time. Monomophizing it may make the optimizer do cool tricks which it otherwise may not. Like it may unroll a small loop of 2 iterations or something or do vectorisations. Or, most importantly, it might remove bounds checks which it might not do in the re-dynamicized case.
Sure, it might have an impact on executable size, but maybe we can have a more general RFC for that one, which also puts type level generics onto the dynamic level with an optional compiler flag? Then you can get really small executables in the case you need them. Or one could have a #[dynamicize] flag on generic functions...

@clarcharr That's what's called an "existential over a value", i.e. Dst<T> exists<N: usize> St<T, N>, or, in another syntax (both are hypothetical anyway), a (N: usize, [T; N]) pair.
In such a model, [T] is nothing more than exists<N: usize> [T; N] although we allow distinct impls on both [T; N] and [T] so we probably can never "go the full way" in that direction.

In general, a const variable can be used where a const can. There is one significant exception: const variables cannot be used in the construction of consts, statics, functions, or types inside a function body.

I do still run into this error often, and even though now I always know exactly what's wrong with my design. This is not specific to this RFC, but:

Why is it this way?
Is there something that can be done about this in general? (as part of another RFC).

Because consts must have the structural match property, and this property cannot be enforced for a type variable, it is not possible to introduce a const parameter which is ascribed to a type variable (Foo<T, const N: T> is not valid).

This means one cannot create types like C++'s std::integral_constant<T, VALUE: T> (among many many others) in Rust.

Why can't we have a constraint to denote those types so that we can write Foo<T: ConstStructuralEquality, const N: T>?

So this seems like the current const generics RFC (there's so many I don't even know at this point), so sorry if this is out of place, but will this enable something like RangeFrom to return an array with size - N (start of range), e.g.:
let arr4: [u8; 4] = [0; 4];
let arr3: [u8; 3] = arr4[1..];

?

@m4b No, because that range value is just passed to a method, it's not const generic parameter.

@eddyb ah yea; so reading through this, it seems this would also be disallowed because N + 1 is now barred, is that correct?  (assuming we could somehow specialize const cases in RangeFrom method)

On that note, would one be able to specialize method params with const? I think this would be extremely useful

@m4b Indexing is done through the Index and IndexMut traits and they don't have const parameters - maybe you're thinking of the same value refinement I came up with a while ago?
No RFC AFAICT had anything like that - e.g. an 1usize type that had only one value (1), which meant you could have impl<A, B> Index<1usize> for (A, B) which would give you type B from pair[1] (and 0usize as the index type would allow pair[0], of type A).

Indexing is done through the Index and IndexMut traits and they don't have const parameters

Yea I know, but I'm asking if specialization could allow one to use const for the index value, would RangeFrom and Index, etc., also then be retrofitted via specializable to allow the kind of array logic I showed above; unfortunately, as expressions are not evaluated, this seems like a moot point in this particular case (above).
However, whether one can specialize a method argument with const is very interesting to me, and also very valuable imho, e.g., here, if I could specialize on a const offset (which happens all the time, usually 0), then I could pass this constant offset to a further specialized const version of Index for arrays, which would eventually return another array (instead of a slice), iiuc

maybe you're thinking of the same value refinement I came up with a while ago
I don't know about a value refinement RFC but if it does above, I would be keenly interested ! :)

@m4b that's definitely not in scope for this RFC

@withoutboats what isn't?

@m4b Any kind of "specializing" from a type param to a specific const value. More generally, this RFC will not enable what you want to do.

Ah yes, as I said array slicing won't work due to expressions being barred. But I do think it's within scope to ask how this would interact with specialized methods. E.g. would a specialized version with const conflict/even be allowed ?
This will likely be some of the first questions people will have when/if either of these lands so I think it's reasonable to ask how it will behave.

E.g. would a specialized version with const conflict/even be allowed ?

Can you post a code example? You would need ot have a const parameter to specialize on a const, something like Index doesn't have a const parameter.
You can't just specialize on arbitrary method arguments.

So this is not exactly what @m4b is proposing but I do hope we can do something like this:
impl<T> [T] {
  fn split_at_const<const Mid: usize>(&self) -> (&[T; Mid], &[T])
}

@jethrogb Yes though it would need to return an Option and I believe it would require unsafe to transform a slice into a ref to an array

@jethrogb thank you, that is an excellent example of what I had in mind!
I believe the same kind of optimization can also be allowed for IndexFrom<Range<usize>> when the range is const (modulo some variation, would need to tinker with the exact sequence necessary for my example), no?
Such that we could ultimately return an array with bounds equal to the bounds given in a const range.
It's this kind of interaction through various layers of trait stacks that I think const + specialization will be a really killer feature of Rust
While it's ultimately out of scope, once/if expr evaluation is possible in consts + specialization, will be truly amazing, and will (I believe) allow for compile time array math/logic as I originally hoped above.

As a beginner, I think that the How We Teach This section could be improved to be slightly less vague. I think that mentioning documentation is important, but it might be more useful to explain what the new section in the book would look like. The questions ‘What would an outline of a new section in the book look like? What should the reader be able to understand by the end of the section in the book?’ were recently added to the How We Teach This template and I think are useful guidelines for this.
I also think it could be useful to further explain why this is an advanced feature. What do new users need to go through and understand first before getting to this new feature? I think that this should be separate from the outline of the chapter, as the chapter would be directly concerning the feature, while this explanation would be what to understand before reading the feature chapter in the book.
You state that const generics should be treated as an advanced feature, so perhaps you should then go into how this would be introduced and taught to existing users. What are the main aspects that would change for a current Rust user, if anything? Perhaps provide a code example of how this feature could impact a current Rust user.
I realize that these questions may already be answered previously in the RFC, but as a new user/someone not familiar with the concept I find that the main body of the RFC becomes intimidatingly complicated with technical jargon. This is no doubt the whole point, but I personally haven’t the foggiest what you’re trying to convey about this new feature. I’m worried that this could be translated directly into a document for teaching, resulting in an explanation too technical and not incredibly useful. Perhaps part of this section could be used to think about how to introduce this topic in less technical terms, but still have the meaty explanation really detailing the technical points.
Again, you may have answered these questions already previously in the RFC. I’m more looking for what concepts this feature is building upon, giving some context in a short, concise manner.

I think that Euclidean geometry and const generics could play well with each other, so maybe one can find inspiration there to find an example for the book. What follows is such an example but is unfished, and dry.

(disclaimer: this has been compiled by an imperfect Rust implementation running inside my brain; mistakes follow)
A recurrent problem in Rust is implementing types that represent some geometry, for example, a 2D point (note: the floating point type is fixed to f32 since the point of this is to show const generics), and to compute the distance between two points:
struct Point2D { x: [f32; 2] }

impl Point2D {
  fn distance(&self, other: Point2D) -> f32
  {
    ((self.x[0] - other.x[0]).powf(2f32)
      + (self.x[1] - other.x[1]).powf(2f32)).sqrt()
  }
}

Afterwards we might want to compute the distance between 3D points as well. We could write a struct Point3D type, re-implement the Point2D methods on it and move on. But later on we also need to do the same on 1D points, and three structs? For some reason that's to much, so we decide to use const generics to implement an n-dimensional point:
// this shows using const generics on structs
struct Point<const DIM: usize> { x: [f32; DIM] }

// this shows how to implement methods on generic structs using const generics
impl<const DIM: usize> Point<DIM> {
  fn distance(&self, other: Point2D) -> f32
  {
    let mut dist = f32 = 0.0;
    for d in 0..DIM {  // this shows how to use const parameters on the body
        dist += (self.x[0] - other.x[0]).powf(2f32);
    }
    dist.sqrt()
  }
}

Now we want to store a color in some of our points. We could use some new Point type, but then we would need to reimplement all the methods, and computing the distance between two point does not depend on their color! We decide to delete our Point implementations and move them to a const generic trait:
// shows const generics in traits
trait<const DIM: usize> SpatialPoint {
  fn coordinate(&self, d: usize) -> f32;
  // and in where clauses
  fn distance<P>(&self, other: P) where P: SpatialPoint<DIM> {
    let mut dist = f32 = 0.0;
    for d in 0..DIM {  // we can use const generics in expression
        dist += (self.coordinate(0) - other.coordinate(0)).powf(2f32);
    }
    dist.sqrt()
  }
}

// shows how to implement the const generic trait for a const generic type
impl<const DIM: usize> SpatialPoint<DIM> for Point<DIM> {
  fn coordinate(&self, d: usize) -> f32 { self.x[d] }
}

We now move to implement our point with a color:
struct PointWithColor<const DIM: usize, P: SpatialPoint<DIM>> {
  point: P, // which works for any point, because we can
  color: f32
}

impl<const DIM: usize, P: SpatialPoint<DIM>> SpatialPoint<DIM> for PointWithColor<P> {
  fn coordinate(&self, d: usize) -> f32 {
     // something that looks like this (rustc cannot help me in space):
     <self.point as SpatialPoint<DIM>>.coordinate(d)
  }
}

So obviously we are still not finished, because we haven't shown {2 * 2} nor associated constants yet. So what comes next? Let's implement a point array:
struct<const DIM: usize, const N: usize> PointArray {
  points: [Point<DIM>; N]
}

and now use it to store all points in an n-dimensional hypercube (line in 1D, square in 2D, cube in 3D, etc.) and make it an associated type from an Hypercube trait:
// and a trait to abstract over different types of points:
trait<const DIM: usize> Hypercube {
    type Points = PointArray<DIM, {2.ipow(DIM)}>;
}

Now suppose that we wanted to have as associated types of an n-dimensional hypercube the types of its "m-dimensional edges": points, edges, faces, ... up to DIM-1 dimensions? Just make the associated type it self const generic:
trait<const DIM: usize> Hypercube {
    // Type of the m-dimensional edge of the Hypercube (const generic associated type)
    type<const M: usize> Edge where M < DIM, Edge<M>: HypercubeEdge<D, M>;
    // Number of m-dimensional edges (const generic associated const)
    const<const M: usize> NoEdges = 2.ipow(DIM - M) * binomial_coefficient(DIM, M);
}

Oh wait, how did I get here? This is not part of the RFC, I guess this is why I cannot have nice things :D

dist += (self.coordinate(0) - other.coordinate(0)).powf(2f32);

The 0s should be ds (also in the snippet before).
:)

Ping. Last comment was more than a month ago.  What is the current status?

It'd be good to have this RFC resolved prior to the impl period; @withoutboats or @eddyb, can you summarize the state of play?

@eddyb and I talked about this RFC a bit last night. I'm hoping next week to be able to make some revisions & propose a merge. There's nothing here that's controversial, just some questions that will need to be resolved in implementation.
One thing we discussed last night was the well formedness of constant expressions. In particular, consider these two functions
fn foo<const N: usize>() -> [i32; N + 1] {
     [0; N + 1]
}

fn bar<const N: usize>() {
     [0; N + 1];
}

What happens if you try to instantiate either of these with usize::MAX? Clearly, that is an error, because it would overflow (and const overflow currently is considered a compiler error).
But the big difference between these is that N + 1 appears in the signature of foo and not the signature of bar. We do not allow wellformedness to depend on the internal details of functions - we require you to annotate your requirements in the function header somehow. (For example, you can't just call T::default(), you have to add where T: Default to the header first.) This is important for backwards compatibility, local reasoning, etc.
For this reason, bar has to be a hard error. You can't use N + 1 in the function body without N + 1 appearing in the function signature somewhere. Immediately, there will be this hack available:
fn bar<const N: usize>() where [(); N + 1]: Sized {
    [0; N + 1];
}

But it seems clear this will lead us down the path toward boolean or pattern conditionals, like where N < usize::MAX.
One thing that isn't clear to me is if we can limit this restriction to const expressions which could panic, and if so what the mechanism for that is.

I would actually be OK with that hack until there is a better canonical way to express such things.

I feel like using fixed-size integers at the type level doesn't even make that much sense in the first place?  But in a logical sense you still tend to treat them as unbounded (except when you use wrapping_add and friends) - with panics on overflow, that is: whenever the unboundedness illusion would be broken. But for use in types I suspect you'd really just want actual, honest-to-god natural numbers.
So a few questions for my edification:

What use case is there for fixed numeric types other than usize at the type level? (Is there any?)

Could we maybe say that usize, being of platform-dependent size, is of unbounded size at compile time, and (whatever size it normally is) at runtime? And insert a panic where, when using it as a runtime value, it would be out of range? (And presumably emit a compile-time warning as well in that case, like we already do for overflows during constant evaluation.)

Can we maybe do that for all of the others as well? So that e.g. u8 is an unbounded type at compile time, but when its value is used at runtime, it's translated as a panic if it would be outside the range 0..256?

Or just in general, could we translate any runtime expression whose type contains an overflow as a panic?

Basically, having to manually thread around constraints in our types just to make sure that our type-level arithmetic doesn't overflow feels like a bunch of self-imposed busywork that's not actually buying us anything useful, and it would be really nice to avoid it in any possible way.

Could we maybe say that usize, being of platform-dependent size, is of unbounded size at compile time, and (whatever size it normally is) at runtime?

That feels like a bit of a hack, though... Maybe it's just me as a systems programmer, but integers are not unbounded and saying they are makes me wince a bit :smile:

I think that in this case instead of making barfail to compile (in the meantime) is a good response. We can add options later for modifying the type signature to make it work, but that's a good compromise for getting this out there.
Perhaps allowing numerical bounds in type signatures will be an eventual requirement to getting this working properly.

@withoutboats

We do not allow wellformedness to depend on the internal details of
functions

We do still have, in some cases, monomirphization time errors.
I know we shouldn't be adding more of these cases to the language, but
maybe you could explain the pros and cons of doing so here?
Having to add bounds to the type signature for every single constant
expression used within a function that depends on a type level const looks
to me like a lot of redundant boilerplate, and at the end of the day, when
passed some type level values, we are still going to error.
The difference would be that in one case you get the error in the type
signature, and then have to inspect the function to reason about whether it
is correct, whether in the later case you get an error directly in the
expression that e.g. Overflows inside the function (a potentially huge
error though, since this can happen deep down the stack).
Anyhow, I feel like I don't quite understand the trade offs here yet. But I
like the example.
On Thu 24. Aug 2017 at 05:47, Clar Roʒe<EMAIL_ADDRESS>wrote:

I think that in this case instead of making barfail to compile (in the
meantime) is a good response. We can add options later for modifying the
type signature to make it work, but that's a good compromise for getting
this out there.
Perhaps allowing numerical bounds in type signatures will be an eventual
requirement to getting this working properly.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/rust-lang/rfcs/pull/2000#issuecomment-324525082, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AA3NpgjeSRDLahOmSmEVts0jvhnw6Buoks5sbPJCgaJpZM4NYoOH
.

Having to add bounds to the type signature for every single constant expression used within a function that depends on a type level const looks to me like a lot of redundant boilerplate, and at the end of the day, when passed some type level values, we are still going to error.

This only applies to expressions using the const in types. Use in regular expressions will not be an error.

We do still have, in some cases, monomorphization time errors.

Do you have some examples? The only one I can think of is asm!, and that's because it depends on LLVM optimizations. We could arguably eventually analyze inline assembly, polymorphically.
We used to have e.g. errors from SIMD shuffle indices arguments not being constant. We fixed that by performing a transformation at const-checking type (so polymorphically) which is similar to what you'd have if const generics were used by SIMD shuffles instead of function arguments.

I may be missing something, but does the following not compile as well according to this proposal?
fn bar<const N: usize>() {
     [0; std::mem::size_of::<[u8; N]>];
}

@WiSaGaN No, we're only talking about expressions other than identity expressions (and only those that appear in types).

Sure, using the const in types is what I expect to use type-level const the
most. In other contexts I can already work around type-level consts by
using associated consts.
That is, I expect to be doing something like this a lot: let x: [T;
foo::<N,M>()]; where N,M are type-level const integers and foo a const fn
that might do something that overflows. How do I bound the function
containing  that? Do I need to inspect foo, figure out the constraints, and
add it to any function that uses foo?
On Thu 24. Aug 2017 at 08:28, boats<EMAIL_ADDRESS>wrote:

Having to add bounds to the type signature for every single constant
expression used within a function that depends on a type level const looks
to me like a lot of redundant boilerplate, and at the end of the day, when
passed some type level values, we are still going to error.
This only applies to expressions using the const in types. Use in
regular expressions will not be an error.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/rust-lang/rfcs/pull/2000#issuecomment-324545578, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AA3Npkwu0FVixPt_kEv-BlK2apghy846ks5sbRgFgaJpZM4NYoOH
.

Do I need to inspect foo, figure out the constraints, and add it to any function that uses foo?

Yes, the same way that if you did this, you would need to bound T by the same bounds that foo has:
fn bar<T>() {
    foo::<T>();
}

I think bar is one case where throwing the error after monomorphization is a good trade-off, like we have runtime-checked arithmetic.
This would mean we need to run miri/const-folding once more after monomorphization in order to discover that [(); usize::MAX + 1] is ill-formed when you instantiate bar (*cough* post-monomorphization MIR pass *cough*).
That said, if we consider the primary impact of this RFC on the standard library, which is to enable impl<T, const N: usize> Everything for [T; N], I don't think this check is necessary for the first version of const generic — just make [T; N+1] (and any compile-time arithmetic involving const generic) always an error.

I think bar is one case where throwing the error after monomorphization is a good trade-off, like we have runtime-checked arithmetic.

It's not the same kind of trade-off. The similar trade-off would be to panic at runtime and emit only a warning when compiling.

This would mean we need to run miri/const-folding once more after monomorphization in order to discover that

No, you discover the error when you try to evaluate that const expression - although, in my current implementation, it just fails to normalize, so you'd most likely get an "unknown type [T; N+1]" layout error (i.e. there's no way to know the size of that type).

just make [T; N+1] (and any type-level arithmetic involving const generic) always an error.

That's more or less what the initial implementation does - the well-formed guarantee of function arguments is a small bonus on top of that (i.e. a pre-existing system that allows slightly more).
Keep in mind none of this has anything to do with const generics in particular. Associated constants expose the exact same problem, and are stable today.

@eddyb
The last ones I got where while implementing bitintr, so they must have
been intrinsics related. I'm traveling right now but IIRC they happened
while using link_llvm_intrinsics or platform_intrinsics features possibly
combined with target_features (so... it was my own fault for using these,
which will probably meet be stable anyways).
So.. I thought that monomorphization errors were just bound to happen. I
haven't gotten one in a while, and they are indeed very very rare for me. I
also think that if we can guarantee their absence in stable rust, that goal
is worth pursuing.
On Thu 24. Aug 2017 at 08:45, kennytm<EMAIL_ADDRESS>wrote:

I think bar is one case where throwing the error after monomorphization
is a good trade-off, like we have runtime-checked arithmetic.
This would mean we need to run miri/const-folding once more after
monomorphization in order to discover that [(); usize::MAX + 1] is
ill-formed when you instantiate bar (cough post-monomorphization MIR
pass cough).
That said, if we consider the primary impact of this RFC on the standard
library, which is to enable impl<T, const N: usize> Everything for [T; N],
I don't think this check is necessary for the first version of const
generic — just make [T; N+1] (and any compile-time arithmetic involving
const generic) always an error.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/rust-lang/rfcs/pull/2000#issuecomment-324548451, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AA3NphuRC_LT_AjhpuAmJ_EeQPi1SBaVks5sbRwdgaJpZM4NYoOH
.

@withoutboats
Would it make sense or be possible to "infer" the bounds or to pursue this
as a future extension?
On Thu 24. Aug 2017 at 08:57, Gonzalo BG<EMAIL_ADDRESS>wrote:

@eddyb
The last ones I got where while implementing bitintr, so they must have
been intrinsics related. I'm traveling right now but IIRC they happened
while using link_llvm_intrinsics or platform_intrinsics features possibly
combined with target_features (so... it was my own fault for using these,
which will probably meet be stable anyways).
So.. I thought that monomorphization errors were just bound to happen. I
haven't gotten one in a while, and they are indeed very very rare for me. I
also think that if we can guarantee their absence in stable rust, that goal
is worth pursuing.
On Thu 24. Aug 2017 at 08:45, kennytm<EMAIL_ADDRESS>wrote:

I think bar is one case where throwing the error after monomorphization
is a good trade-off, like we have runtime-checked arithmetic.
This would mean we need to run miri/const-folding once more after
monomorphization in order to discover that [(); usize::MAX + 1] is
ill-formed when you instantiate bar (cough post-monomorphization MIR
pass cough).
That said, if we consider the primary impact of this RFC on the standard
library, which is to enable impl<T, const N: usize> Everything for [T; N],
I don't think this check is necessary for the first version of const
generic — just make [T; N+1] (and any compile-time arithmetic involving
const generic) always an error.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/rust-lang/rfcs/pull/2000#issuecomment-324548451, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AA3NphuRC_LT_AjhpuAmJ_EeQPi1SBaVks5sbRwdgaJpZM4NYoOH
.

I also think that if we can guarantee their absence in stable rust, that goal is worth pursuing.

It has been a guarantee for many minor versions now (although I don't remember what 1.0 did).
If you see a post-monomorphization compiler error in stable Rust code (other than a recursion limit error, which is not unlike running out of RAM during compilation), please report it as a bug.

I've never seen monomorphization errors on stable rust, only in nightly
using the features I mentioned.
On Thu 24. Aug 2017 at 09:00, Eduard-Mihai Burtescu <
<EMAIL_ADDRESS>wrote:

I also think that if we can guarantee their absence in stable rust, that
goal is worth pursuing.
It has been a guarantee for many minor versions now (although I don't
remember what 1.0 did).
If you see a post-monomorphization compiler error in stable Rust code
(other than a recursion limit error, which is not unlike running out of RAM
during compilation), please report it as a bug.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/rust-lang/rfcs/pull/2000#issuecomment-324551165, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AA3Npucb_gn1rTNM33KfL3zURRfWiAjWks5sbR-egaJpZM4NYoOH
.

Would it make sense or be possible to "infer" the bounds or to pursue this as a future extension?

Keep in mind you can only do this from the signature (which we already infer some bounds from).
If you look at the body, that's "global inference" and it will take a lot of convincing to make that happen - even if it happens, it'll take a lot of compiler refactoring and always be opt-in, at least when writing libraries, as it's basically a backwards compatibility hazard generator.
That said: there is the semver comparison tool, which (since it uses the compiler) would be able to point out the new bounds - or, more generally, when dealing with global inference situations, different inferred results for different versions, as the compiler sees them.

I think @glaebhoerl 's suggestion is actually appealing. What if we use an abstract unbounded int type for compile time? Explicit cast operator is required from abstract int type to runtime integer types (i8 isize).

@F001 I think it's outside of the scope of this RFC. Currently we type-check and interpret constant expressions with the target semantics. That is, miri only abstracts away the allocation a pointer points into, but everything else is the runtime memory representation, byte-for-byte.

I wasnt thinking about global inference, but rather, for the body of a
"leaf" function, infer the bounds of its body from the body only. Non-leaf
functions just propagate these bounds.
The consequence would be that changing the implementation of a function can
break an arbitrary large amount of code, but otoh users can write the
bounds manually anyways.
On Thu 24. Aug 2017 at 09:04, Eduard-Mihai Burtescu <
<EMAIL_ADDRESS>wrote:

Would it make sense or be possible to "infer" the bounds or to pursue this
as a future extension?
Keep in mind you can only do this from the signature (which we already
infer some bounds from).
If you look at the body, that's "global inference" and it will take a lot
of convincing to make that happen - even if it happens, it'll take a lot of
compiler refactoring and always be opt-in, at least when writing
libraries, as it's basically a backwards compatibility hazard generator.
That said: there is the semver comparison tool
https://github.com/ibabushkin/rust-semverver/, which (since it uses the
compiler) would be able to point out the new bounds - or, more generally,
when dealing with global inference situations, different inferred results
for different versions, as the compiler sees them.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/rust-lang/rfcs/pull/2000#issuecomment-324551831, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AA3NpsQih21-IUoNzUWACi_KxnpQcso2ks5sbSCDgaJpZM4NYoOH
.

The consequence would be that changing the implementation of a function can break an arbitrary large amount of code, but otoh users can write the bounds manually anyways.

The difference is that, right now, the body of the function doesn't matter for backwards compatibility, only the signature (including bounds) does. Both documentation and the semver-checking tool would have to expose any inferred information and thus its backwards compatibility implications.

@eddyb

It's not the same kind of trade-off. The similar trade-off would be to panic at runtime and emit only a warning when compiling.

I made the comparison because N is unknown pre-monomorphization, and N is known post-monomorphization. This is similar to the normal expression a + 1 where a is unknown at compile-time, and a is known at runtime.
The trade-off is you emit error after N is known when you compute N+1, like checked arithmetic where you panic after a is known when you compute a+1.
Once N is known, you can be sure whether N + 1 overflows or not, thus it can throw an error at that stage. Further delaying the error by inserting a panic makes no sense.

No, you discover the error when you try to evaluate that const expression - although, in my current implementation, it just fails to normalize, so you'd most likely get an "unknown type [T; N+1]" layout error (i.e. there's no way to know the size of that type).
That's more or less what the initial implementation does - the well-formed guarantee of function arguments is a small bonus on top of that (i.e. a pre-existing system that allows slightly more). Keep in mind none of this has anything to do with const generics in particular. Associated constants expose the exact same problem, and are stable today.

I believe we are talking about the same thing.
In the current implementation, you cannot evaluate the const expression at all during the MIR-based const-folding pass because N is totally unknown before monomorphization, which is why we have rust-lang/rust#43408 and the associated-const problem.
Thus I suggest if we want to support N + 1 without it appearing in the signature, there have to be a new const-folding pass after monomorphization where you can evaluate N + 1 because now N is known. The pre-monomorphized const-folding pass should keep N+1 and associated consts unevaluated.

Post monomorphization errors seem to have very serious backwards compatibility hazards. I can add what amounts to a silent well formedness clause without noticing it and break a downstream crate.

@kennytm The "const-folding" pass you talk of does not exist. We evaluate the constant, i.e. like const-folding but total, not partial. And we have to do this all the time.

rust-lang/rust#43408 and the associated-const problem

These are the same problem. I have a branch that fixes it - the real issue is that we can't do the naive thing because then array lengths in certain positions cause cycles (between bounds which are in scope of the constant expression and thus must be available when the constant expression is type-checked which is before evaluation, and the type the constant expression is part of, e.g. array length).
Thus you end up with deferred evaluation, which makes every array length (yes, including plain literals) behave as complex constant expression that require monomorphization, and thus the WF requirement is the best place to put "this expression evaluates successfully".

Also, maybe we should stop talking about overflow? There's an obvious solution there: do the wrapping behavior. Better examples are N / M (always panics for M == 0) and ARRAY[X].

@withoutboats Sure, and that's the trade-off I'd take, given that instantiating bar::<usize::MAX> should be rare unless you're attacking the type system. The alternatives I can think of:

Don't support it (← my stance for 1.0)

Add a bunch of checking clause at the signature like where [(); N+1]: Sized or with N < usize::MAX (#1932) (and that makes the signature pretty tedious)
I think we should get this eventually for compile-time bounds checking, but using this for checked arithmetic is just pushing details to the documentation

Infer the checking clause from the function body (please no)

Treat the integer types as infinite, or make all compile-time overflowing ops wrapping/saturating/unreachable!() (please no)

Post-monorphization check (← my stance for 2.0)

Support ranged integer type, i.e. <const N: usize[0 .. usize::MAX]>.

Just don't check, let it ICE (please no)

@kennytm 3, 5 and 7 are functionally equivalent.

I like this RFC a lot. I think it fails to address the details of the typing rules though like my original, bloateed RFC did. (I don't mind you stealing the rules from it)

it implies you add a where 0 <= f(N) && f(N) <= usize::MAX clause to the function's body.

That expression is always true (because f(N) is necessarily of usize type) - and unnecessarily so, I prefer using where (expr, true).1 for [T; expr] if someone wants the desugaring.

I've kind of last track of the discussion, but perhaps one solution is to introduce type-aliasing/const declarations when defining generics in the signature:
fn foo<const N: usize>() -> [i32; N + 1] {
     [0; N + 1]
}

fn bar<const N: usize, const: M usize>()
where
    const M: usize = N + 1;
{
     [0; N + 1];
}

@mark-i-m Did you mean M == N + 1 in the where clause?

@mark-i-m perhaps we could just use the equality syntax that doesn't work in where clauses? i.e. <const N: usize, const M: usize = N + 1> ?
At the moment we don't allow type equality in where so I think that it's fair to just use the builtin stuff until we have something better.

@eddyb I think your suggestion is subtly (theoretically) different, though they may turn out to be equivalent. I am defining a new constant that refers to the functions type/const params and lives only in the body and is defined to be N+1. If I understand you correctly, you are suggesting defining a const parameter and adding a type-checker constraint that M == N + 1...
In retrospect, maybe both my and @clarcharr 's syntaxes are a bit misleading... perhaps something like this would be clearer:
fn bar<T, const N: usize>()
where
    T: MyTrait
with // I don't think this makes the syntax ambiguous...
    const M: usize = N + 1; // _NOT_ a const param, just a const
{
     [0; M]; // EDIT: should use M here, which is defined in the signature
}

This seems like it would be a major addition to the RFC, though... Perhaps the problem is not bad enough that it merits complicating the current proposal?

To clarify, the benefit of that suggestion is that it would allow us to continue this:

We do not allow wellformedness to depend on the internal details of functions - we require you to annotate your requirements in the function header somehow.

@mark-i-m Ah I see yes that'd probably work (and the compiler would know that all uses of M refer to the same expression, so that's a bonus) - it's just not something I see accepted in that form.
There was similar talk of impl Trait having a form like that and it didn't end up being the case.

To counter that syntax, I think that doing this would be against the spirit of a where clause, because defining type aliases in them would be very weird:
fn thing<I, F>(iter: I, f: F)
where
    I: IntoIterator,
    T = <I as IntoIterator>::Item,
    F: FnMut(T)
{
    for item in iter {
        f(item);
    }
}

So, defining constants there would be equally confusing.

Perhaps we could use some sort of pattern syntax in the types to clarify bounds? Maybe something along the lines of <const N: usize[0..usize::MAX]>?

FWIW I think this discussion is getting a bit derailed and while some of these ideas are interesting, I expect they would not be in the initial implementation, if we want it to exist before late 2018.

Yeah, I guess probably the best thing for now is that bar should not compile...
@clarcharr

Off-topic
That's my whole point: it's not a type alias or a generic parameter. It's just a normal constant, but with its scope only defined for a particular function. And it can use the const and type parameters from that function in its own definition. The proposed syntax (with) would be completely independent of where. I just used where in the example to show that they can co-exist.

@rfcbot fcp merge
Proposing to merge this :tada: Likely there will be UX issues with the very initial versions because of the things that we've touched on in this thread, and we may need a second RFC later to clarify how we resolve those. We'll see. Either way, we have enough to get a nightly implementation, and the big picture questions about syntax and general semantics and so forth are, IMO, resolved.
I'll make edits today hopefully to clarify the unresolved questions.

Following a conversation on irc: I'd like to consider the possibility of not requiring const in declarations, which seems a bit onerous for the common case of integer generics. But we can consider this after implementation as part of stabilisation or whatever.

if (when) this gets implemented in rust, could generic impls of traits on arrays in std be stabilized before the entire feature is?

@tinaun Impls of stable traits are Insta-stable ;).

Re not requiring const - it could be optional for integer literals (as they're obviously values, not types)

@thepowersgang what do you mean by integer literals? The const is only required when the parameter is declaring struct Test<const N: usize>;. The literal can only used when the generic is instantiating Test<1>. We don't need to use const to qualify a literal.
I do not only want the const qualifier, but also a type qualifier on normal generic type parameter (even optional).
struct Test<const N: usize, type T: Trait>{}

@rfcbot concern expression-unifies-with-itself
(aside: sorry for potential redundancy; I cannot tell if rfcbot is monitoring the comment-threads that are attached to specific lines of the diff, so I am repeating my concern in the main thread now.)

Was this thread of discussion ever resolved? On my reading today (Sept 1), I came away with the impression that two occurrences of the AST {N + 1} (i.e. two different nodes in the AST that both are the subtree {N + 1}) would be considered equal to each other and thus [usize; N + 1] would unify with the type of [0_usize; N + 1].
But @eddyb said that contradicts what he wants to see.
So I cannot tell what we are actually agreeing to.
Reading the remainder of the comments on the RFC, I see no sign that @eddyb has changed his mind on this point, even though AFACIT the RFC still has the original text that allows for distinct, syntactically-congruent AST nodes of const expressions to be considered equal when solving type equations.

@F001 Ignore that, I misread as use (not declaration)

@pnkfelix We resolved it in IRC and I need to update the RFC (meant to yesterday, doing it now). We're going to do what @eddyb says will be easiest to implement for now - an expression unifies with itself if its a reference to the same AST node and in no other case.
For example:
type SuccArray<const N: usize> = [i32; N + 1];

fn foo<const N: usize>() -> SuccArray<N> {
    let x: SuccArray<N> = [0; N + 1];
    x
}

My understanding of what @eddyb said is that this would unify, but only this.
Essentially the result of each const expression acts as an anonymous associated const to the tuple of unknown const variables, so only multiple references to the same AST node can be unified in the first pass of this RFC.

The RFC has been updated to reflect that decision

@withoutboats Did you mean to have two copies N + 1 in your code? Those can't be unified yet.
type SuccArray<const N: usize> = [i32; N + 1];

fn foo<const N: usize>() -> SuccArray<N> {
    // This would actually work, given a const-generic Default impl:
    let x: SuccArray<N> = Default::default();
    x
}

@eddyb ah oops.

@rfcbot resolved expression-unifies-with-itself

Ordering and default parameters: Do all const parameters come last, or can they be mixed with types?

Given that we require all lifetime parameters to precede type parameters, it makes sense to me to require all const parameters to follow all type parameters, IOW to disallow mixing. This is a restriction that can always be lifted later.

@bstrie The restriction doesn't make sense IMO. We use const before the name to avoid restrictions.

@bstrie you are missing this context https://github.com/rust-lang/rfcs/pull/2000#discussion_r116131485

(Apologies if this has already been addressed, i'm still working through the RFC and comments)

Const parameters always come after type parameters

Why? I can vaguely imagine cases where i might prefer otherwise, like:
struct ParallelStridedArrays<T, const T_STRIDE: usize, U, const U_STRIDE: usize> {
  // ...
}

It's not a deal-breaker, but it will be a mild annoyance for someone at some point.

/me does the bikeshedding dance

When applying an expression as const parameter (except for arrays), which is not an identity expression, the expression must be contained within a block. This syntactic restriction is necessary to avoid requiring infinite lookahead when parsing an expression inside of a type.

A block rather than parentheses? I appreciate that they are pretty much equivalent in an expression-oriented language, but i would naturally reach for parens here myself.

For the latter point, it's because () is already valid in types (for tuples or grouping trait objects), {} isn't so can be used to indicate to the parser that it's about to parse an expression.

I think conceptually const generic parameters coming after others makes sense because the compiler might eventually make some const generic parameters into arguments under the hood, depending upon how they were used, the state of alloca/VLA, etc.  In principle, the compiler could do so with type parameters too, but the analysis sounds harder.  And lifetimes first makes sense because they never exist at runtime time.

Ordering of const arguments is supposed to be an unresolved question because of its interaction with default args, I'll remove that statement from the RFC.

Ordering of const arguments is supposed to be an unresolved question because of its interaction with default args, I'll remove that statement from the RFC.

Const generics is accepted & merged as RFC 2000. Tracking issue is rust-lang/rust#44580.


feat(v2): use __docusaurus as app root id

Motivation
Make the app root ID unique so that it's easier hook into if we have a need to. A side effect of this is that it's easier to tell whether a site is using Docusaurus.
Have you read the Contributing Guidelines on pull requests?
Yes
Test Plan
Netlify
Related PRs
(If this PR adds or changes functionality, please take some time to update the docs at https://github.com/facebook/docusaurus, and link to your PR here.)

Oops.. Did I merge it too fast
This one is needed too https://github.com/facebook/Docusaurus/blob/master/packages/docusaurus/lib/core/serverEntry.js


Move build process off of production server

Currently the prod server is handicapped when building the app. Build the app on a separate server, then transfer the assets to the prod server

This needs to be done soon

This needs to be done soon


Set file extension filter for form field?

Is it possible to set the allowed file extensions for a file form field?
That would help to tell the user what kind of files should be uploaded.
And the file dialog would only show the files with the right extension even when a folder is full of other files.

It´s not possible in the current feature set. We have a corresponding entry in our own wish list, but it´s currently not prioritized.


Reduce size of ternary expressions generated by Verilog backend

Calyx has been generating Verilog code that way too big. The root cause of this, identified in Adrian's comment, is that assigns statements are amalgamated into one big ternary expression. We should break assignments into smaller chunks. (and maybe discuss the best way to do that here!)

To state the obvious, the straightforward way to make this into separate lines is to use Verilog if:
if (msp_go_out) begin
  assign depth_output_addr0 = 13'd0
end else if (msp0_go_out) begin
  assign depth_output_addr0 = 13'd1
...

But I recall that we stopped doing that (and switched to the ternary expression style) for some reason… but I can't recall why. Maybe just testing that out to see if something goes obviously wrong would be informative?

I think there is was a problem with the semantics of assign and always_comb ... if not being exactly the same causing various problems. I think #1177 is the other approach we can consider.


21

Coverage increased (+2.1%) to 99.647% when pulling ed59f7141bcfbc4a403a8fd7fc9fe9ec3b0a54a1 on 21 into<PHONE_NUMBER>16e7e0edce5f280f60e6e36e12a8b9 on dev.

Coverage increased (+2.5%) to 100.0% when pulling bba2117030f0cfd79b7ce342190379a7d789ed0a on 21 into<PHONE_NUMBER>16e7e0edce5f280f60e6e36e12a8b9 on dev.


Continue sqlalchemy legacy cleanup

Things done:

[X] Tested using sandboxing (nix-build --option build-use-chroot true or nix.useChroot on NixOS)
Built on platform(s)

[X] NixOS
[ ] OS X
[ ] Linux

[ ] Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
[ ] Tested execution of all binary files (usually in ./result/bin/)
[ ] Fits CONTRIBUTING.md.

More
Related with issue #14026
sqlalchemy8 is still used, I am still working on that. I’ll post a PR ASAP.

LGTM


cmd/cgo: SIGSEGV, Segmentation fault, during runtime execution on arm (CortexA9)

What version of Go are you using (go version)?
On Host machine:

$ go version
go version go1.16.8 linux/amd64

Build with docker: golang:1.16-buster
Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (go env)?
On Host machine:
go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16.8"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build34544403=/tmp/go-build -gno-record-gcc-switches"

On Target machine:
cat /proc/cpuinfo Output
# cat /proc/cpuinfo
processor	: 0
model name	: ARMv7 Processor rev 10 (v7l)
BogoMIPS	: 6.45
Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpd32
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x2
CPU part	: 0xc09
CPU revision	: 10
processor	: 1
model name	: ARMv7 Processor rev 10 (v7l)
BogoMIPS	: 6.45
Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpd32
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x2
CPU part	: 0xc09
CPU revision	: 10
processor	: 2
model name	: ARMv7 Processor rev 10 (v7l)
BogoMIPS	: 6.45
Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpd32
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x2
CPU part	: 0xc09
CPU revision	: 10
processor	: 3
model name	: ARMv7 Processor rev 10 (v7l)
BogoMIPS	: 6.45
Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpd32
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x2
CPU part	: 0xc09
CPU revision	: 10
Hardware	: Freescale i.MX6 Quad/DualLite (Device Tree)
Revision	: 0000
Serial		:<PHONE_NUMBER>000000

On Target machine:
cat /etc/os-release Output
# cat /etc/os-release
NAME=Buildroot
VERSION=2019.11
ID=buildroot
VERSION_ID=2019.11
PRETTY_NAME="Buildroot 2019.11"

What did you do?
I'm building go application that should be run on CortexA9 CPU and uses 3 different C/C++ shared libraries (I use C wrapper to call C++ code), when calling one of them (Clips rules engine http://www.clipsrules.net/) I accidentally get SIGSEGV, Segmentation fault, the library itself is quite old and well tested, also the same code works well on amd64  arch. The place where error occurs looks quite random, if I rewrite code to avoid the specific code lines, it will occur in the middle of an other function.
How I build lib
I use arm-buildroot-linux-gnueabi toolchain and arm-buildroot-linux-gnueabihf-gcc as C compiler, so is built with this CFLAGS: -Wall -std=c99 -O3 -fno-strict-aliasing -fPIC -march=armv7-a -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=hard --sysroot=${some path}
If I build Clips as standalone binary (with this toolchain) and run some rules on it, it works well.
How I build golang app
I build app on docker golang:1.16-buster, where my toolchanin is placed
go clean && env CGO_CFLAGS="-march=armv7-a -mfpu=neon -mfloat-abi=hard -mtune=cortex-a9 --sysroot={soem path}" CGO_ENABLED=1 GOOS="linux" GOARM=7 GOARCH=arm go build --tags=with_libs,arm -o ./out/$app_name .
CC is set to arm-buildroot-linux-gnueabihf-gcc
To add library to project I have arm.go file:
// +build arm

package clips

// #cgo LDFLAGS: -L../../libs/arm -lclips -lm -Wl,-rpath -Wl,../libs/arm
import "C"

What did you expect to see?
I expect to see no unexpected signals.
What did you see instead?
While app is running, when I perform cgo calls from so library I get this (from gdb):
Thread 1 "myapp-arm" received signal SIGSEGV, Segmentation fault.
gdb: backtrace:
    #0  0x76d6fa6c in PrintTemplateFact (theEnv=0x4c8b90, logicalName=0x76d79184 "FactPPForm", theFact=0x4c6dd8, seperateLines=0, ignoreDefaults=0) at /myapp/clips_source/tmpltutl.c:387
    #1  0x76cbfa70 in PrintFact (theEnv=0x4c8b90, logicalName=0x76d79184 "FactPPForm", factPtr=0x4c6dd8, seperateLines=0, ignoreDefaults=0) at /myapp/clips_source/factmngr.c:445
    #2  0x76cbf704 in PrintFactWithIdentifier (theEnv=0x4c8b90, logicalName=0x76d79184 "FactPPForm", factPtr=0x4c6dd8) at /myapp/clips_source/factmngr.c:328
    #3  0x76cc1950 in EnvGetFactPPForm (theEnv=0x4c8b90, buffer=0x535290 "f--1    (attribute (id ) (comment ) (code ) (path", bufferLength=1023, theFact=0x4c6dd8) at /myapp/clips_source/factmngr.c:1590
    #4  0x002661e8 in _cgo_4cadad88d928_Cfunc_EnvGetFactPPForm ()
    #5  0x000823d8 in runtime.asmcgocall () at /usr/local/go/src/runtime/asm_arm.s:596
    #6  0x00a16050 in ?? ()

On Target machine:
gdb disas If this helps
...
   0x76d6fa3c <+616>:	mov	r2, r1
   0x76d6fa40 <+620>:	ldr	r1, [r11, #-60]	; 0xffffffc4
   0x76d6fa44 <+624>:	ldr	r0, [r11, #-56]	; 0xffffffc8
   0x76d6fa48 <+628>:	bl	0x76c68edc
   0x76d6fa4c <+632>:	b	0x76d6fad0
   0x76d6fa50 <+636>:	ldr	r3, [r11, #-8]
   0x76d6fa54 <+640>:	lsl	r3, r3, #3
   0x76d6fa58 <+644>:	ldr	r2, [r11, #-24]	; 0xffffffe8
   0x76d6fa5c <+648>:	add	r3, r2, r3
   0x76d6fa60 <+652>:	ldr	r3, [r3, #4]
   0x76d6fa64 <+656>:	str	r3, [r11, #-28]	; 0xffffffe4
   0x76d6fa68 <+660>:	ldr	r3, [r11, #-28]	; 0xffffffe4
=> 0x76d6fa6c <+664>:	ldr	r3, [r3, #4]
   0x76d6fa70 <+668>:	cmp	r3, #0
   0x76d6fa74 <+672>:	ble	0x76d6fad0
   0x76d6fa78 <+676>:	ldr	r3, [pc, #232]	; 0x76d6fb68
   0x76d6fa7c <+680>:	add	r3, pc, r3
   0x76d6fa80 <+684>:	mov	r2, r3
   0x76d6fa84 <+688>:	ldr	r1, [r11, #-60]	; 0xffffffc4
   0x76d6fa88 <+692>:	ldr	r0, [r11, #-56]	; 0xffffffc8
   0x76d6fa8c <+696>:	bl	0x76c68c3c
   0x76d6fa90 <+700>:	ldr	r3, [r11, #-8]
...

If it works on amd64 and fails on ARM, then the most likely cause is that the memory address is misaligned.  That would not be a problem with Go.

@ianlancetaylor you are right, the problem is not related to go/cgo.


AADSTS7000218: The request body must contain the following parameter: ‘client_assertion’ or ‘client_secret’

When attempting to authenticate to the app, you receive the following error:
AADSTS7000218: The request body must contain the following parameter: ‘client_assertion’ or ‘client_secret’
The fix is to enable "Allow public client flows" under the Authentication settings in your App Registration.  Just posting this here in case you want to update the docs, or to save somebody else the trouble of figuring this out.
Great app by the way.  Very much appreciate you sharing it with the community.

@alexromp, any idea on how to solve the following issue:
{"error":{"code":"Forbidden","message":"Failed to get license information for the user. Ensure user has a
| valid Office365 license assigned to
| them."
Does this only work on the enterprise version of Teams?
Thank you!


Running Total | Graph

Hi there,
does anyone know if you can automatically create a chart that has a running total available with it? e.g...
I have Sales each month, and I want to see a line (not trend line) that shows the running total total. The X would be the Months, and the Y would be the sales, but I want to see the running total.
The actual graph that this works with is the Waterfall in excel, but this is not available in ImportExcel.
thanks,

just adding a comment to avoid the original post from going stale. Will only do this the one time.
Thanks.

Sorry, unfortunately the Waterfall graph is not available in the module or the underlying library (which I do not maintain).


UnhandledPromiseRejectionWarning: HTTPError: Response code 429 (Too Many Requests)

did someone find a meaningful description of the existing limits?


chore: Simple Eslint cleanup ✨

SUMMARY

Just a teeny PR... just cleaning up some little lint warnings. Mostly unused items, and one non-null assertion.
Reviewers: @riahk / @etr2460
BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

TEST PLAN

ADDITIONAL INFORMATION

[ ] Has associated issue:
[ ] Changes UI
[ ] Requires DB Migration.
[ ] Confirm DB Migration upgrade and downgrade tested.
[ ] Introduces new feature or API
[ ] Removes existing feature or API

Codecov Report

Merging #10740 into master will decrease coverage by 4.53%.
The diff coverage is n/a.

@@            Coverage Diff             @@
##           master   #10740      +/-   ##
==========================================
- Coverage   65.80%   61.27%   -4.54%
==========================================
  Files         815      382     -433
  Lines       38327    24138   -14189
  Branches     3600        0    -3600
==========================================
- Hits        25221    14790   -10431
+ Misses      13002     9348    -3654
+ Partials      104        0     -104

Flag
Coverage Δ

#cypress
?

#javascript
?

#python
61.27% <ø> (-0.19%)
:arrow_down:

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files
Coverage Δ

superset/db_engine_specs/presto.py
73.54% <0.00%> (-8.75%)
:arrow_down:

superset/examples/world_bank.py
97.10% <0.00%> (-2.90%)
:arrow_down:

superset/examples/birth_names.py
97.36% <0.00%> (-2.64%)
:arrow_down:

superset/models/core.py
88.12% <0.00%> (-0.28%)
:arrow_down:

superset/connectors/sqla/models.py
89.61% <0.00%> (-0.14%)
:arrow_down:

...rontend/src/SqlLab/components/TabbedSqlEditors.jsx

...d/src/explore/components/MetricDefinitionValue.jsx

...-frontend/src/components/Button/Button.stories.jsx

...nd/src/dashboard/containers/DashboardComponent.jsx

...perset-frontend/src/views/CRUD/chart/ChartList.tsx

... and 425 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 557a303...b3e0e74. Read the comment docs.

Meh... this is too old/obsolete to worry about fixing up. Will tackle more current eslint issues in another PR


[bug 1118765] Upgrade waffle to v0.10.1 for django 1.7

This is a dot release that adds the new migrations for django 1.7.
r?

This is failing with:
======================================================================
ERROR: fjord/feedback/tests/test_views.py:TestFeedback.test_browser_data_not_there_when_feedbackdev_is_false
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/build/mozilla/fjord/fjord/base/tests/__init__.py", line 101, in _give_me_waffles
    except waffle.Flag.DoesNotExist:
AttributeError: 'module' object has no attribute 'Flag'

huh. That looks goofy. waffle.Flag instead of waffle.models.Flag?

Yeah, this broke it https://github.com/jsocol/django-waffle/commit/c117efe072eaea4fa88cec212b3f15b7b5eccff9

fixord ^

Great! Can you squash these? Then we'll merge it.

done! :point_up:

Yay!
b5676cf [bug 1118765] Upgrade waffle to v0.10.1 for django 1.7


Reload credentials from yaml logic for S3 [WIP]

cc @kakkoyun @bwplotka
(This PR is still in WIP and was made to be discussed in the weekly Mentor-Mentee meeting)

@yashrsharma44 Sorry for the late reply, I was working on the local fork and didn't get a chance to look at the PR further. Thanks for the reviews @bwplotka and @yashrsharma44. I've comitted your suggested changes, and for the multiple function call thing, Bartek suggested to run a thread in parallel to see if the file has changed once every minute, and if it has, only then would I call the reload function, along with a mutex lock, to prevent race conditions

@Biswajitghosh98 You made Stalebot unhappy, give it a last push as we discussed :)


Decompiler.exe and Windows 7

Describe the bug
https://github.com/SteamDatabase/ValveResourceFormat/actions/runs/1408195584
<IP_ADDRESS>8 - last working version on Windows 7 X64
all other versions after <IP_ADDRESS>8 got error about missing api-ms-win-core-winrt-l1-1-0.dll
P.S. VRF.exe last versions is working
What Valve game does this happen in
All
Reference file in a Source 2 game
All
Expected behavior
All
What version of VRF are you using? On what platform?
Decompiler.exe after <IP_ADDRESS>8 on Windows 7 x64

Windows 7 is EOL.
You can try figuring out why NET 6 doesn't work on it (e.g. compiling yourself), but nothing extra will be done in VRF.


Add session storage info to accordion guidance

Partly addresses #1443.
This PR updates the accordion guidance about setting up whether the sections are open.
Some users said they were confused that the accordion had not retained their changes when they refreshed the page. However, the accordion only 'remembers' changes made within a single session, for example, when users nav back to the page via their browser.

@calvin-lau-sig7 @36degrees Thanks for reviewing! If everything looks ok, can I get an approval? :)


Wind Hybrids is Missing "Balance of System" Inputs

Describe the bug
PV-Wind-Battery hybrids is missing the balance of system inputs
To Reproduce
Steps to reproduce the behavior:

Open a wind hybrids case on develop
Click on Wind Installation Costs
Click on "Go to balance of system cost inputs"
See error

Expected behavior
Cost inputs should match stand alone wind.
Screenshots
Hybrids:

Stand Alone Wind:

hide button, remove UI forms if not easily fixable


Add defaultCriteria for customers.

1. Why is this change necessary?
It is very common to add own extensions like associations to an existing customer.
To extend the customer edit panel in a plugin, it is necessary for the customer components to have an overridable criteria function.
2. What does this change do, exactly?
It adds defaultCriteria methods for sw-customer-detail and sw-customer-list.
3. Describe each step to reproduce the issue or behaviour.
--
4. Please link to the relevant issues (if any).
--
5. Which documentation changes (if any) need to be made because of this PR?
This change doesn't introduce any new behavior.
6. Checklist

[ ] I have written tests and verified that they fail without my change
[ ] I have squashed any insignificant commits
[ ] This change has comments for package types, values, functions, and non-obvious lines of code
[x] I have read the contribution requirements and fulfil them.

(first three points shouldn't be necessary)

All done. :slightly_smiling_face:

@itmuckel changes look good for me now, but you have to rebase your PR as it has conflicts.

@itmuckel, we will try to refactor all criteria instances in our Administration to be more extendable :+1:

I have no access to my machine until monday, so I'll have to do it then. Thank you for refactoring the criteria instances! 🙂

Rebased.

thanks for your contribution @itmuckel :+1: :tada: :blue_heart:


Chatbot sometimes redundantly reloads data

I told the chatbot to load a small PNG image, stripping the alpha channel, which worked: it did so then displayed it.
I then told the chatbot to perform a rolling ball background subtraction at radius 50. I noticed in the script it generated, as the output flew by, that it was calling imread again on the same file. Does it not have the dataset already loaded into a local variable, which can be reused?
I was able to avoid this behavior by appending "Save the result into a variable that can be subsequently reused" to my prompt—after doing so, the next prompt to perform the rolling ball successfully reused the already-loaded image (although the rolling ball operation ultimately failed—but that is a separate issue).

Thanks! While there is no straightforward way to control this behavior, I do adapted your prompt in the code here: https://github.com/bioimage-io/bioimage.io/pull/393
Feel free to reopen if this is still an obvious issue.


findpoly returning combination which is very far off

$ python3
Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from sympy import sympify
>>> from mpmath import mp, findpoly
>>> mp.dps = 30  # set high precision
>>> findpoly(sympify('31/10'), maxcoeff=10, n=50)
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]

As I understand, it proposes to compute 0x^49 + 0x^48 + ... + 0*x + 1 = 1, which is not close to 3.1

You banned valid values of coefficients and set an enormous upper bound of the degree.  But:
>>> findpoly(mpf('31/10'))
[-10, 31]
>>> findpoly(mpf('31/10'), n=10)
[-10, 31]
>>> findpoly(mpf('31/10'), maxcoeff=100, n=50)
[-10, 31]

Lets wait if @fredrik-johansson have another opinion, but I doubt it's a bug.

Ok, @elexunix, I'm closing this.  Feel free to reopen if you have arguments against.


UTM will boot no isos

https://user-images.githubusercontent.com/82119662/113928492-e49be580-97bc-11eb-9099-553850bc8421.MP4
Will not boot any iso spite the settings or iso
jailbreak: taurine
Installed with ReProvision
iOS 14.3
Latest ver of UTM

Hi, how did you set up your VM's drives? Make sure to have the CD drive as a "Removable" drive (don't import), then start the VM and tap the CD button to select the ISO file.

any tips?

I see

You have to pick the .ISO here

I fixed it, the iso I was using was uefi bootable only not bios bootable. > Hi, how did you set up your VM's drives? Make sure to have the CD drive as a "Removable" drive (don't import), then start the VM and tap the CD button to select the ISO file.

Maybe disallow importing ISOs in the future. It correctly knew I meant "CD/DVD ROM Image" but it didn't auto-tick removable.

I see

You have to pick the .ISO here

You can also start the VM, then click the CD button in the toolbar to select the ISO. Then restart the VM and it will work.

Issue seems to be solved but improvement to removable drive selection UI will be improved in the future.


Odd behaviour when spawning ghostface with child_process.spawn

Hi there,
I'm trying to spawn ghostface using child_process.spawn().
It's strange because none of the output is getting piped to the console, nor do any exit events trigger.
My guess is that the main ghostface isn't the process actually producing the output, nor the exit codes. Is there some other sub-process generating the output?
var spawn = require('child_process').spawn;
var spawned_process;

spawned_process = spawn('./node_modules/.bin/ghostface', ['test/browser_test_compiled.js']);
spawned_process.stdout.pipe(process.stdout);
spawned_process.stderr.pipe(process.stderr);

spawned_process.on('exit', function(code, signal){
    console.log("EXITED with code", code);
});

spawned_process.on('error', function(err){
    console.log("ERROR", err);
});

The same setup works for things like browserify, for example if I do:
spawned_process = spawn('./node_modules/.bin/browserify', ['test/browser_tes.js']);

It outputs the stdout and exits with a 0.
Any thoughts?

Hmm; I haven't tried this, but I bet this is due to how ghostface detects if it should expect input on stdin (say via a cat somefile.js | ghostface) and it's probably just hanging waiting for input. See this line https://github.com/fardog/ghostface/blob/master/lib/cli.js#L89
This isn't ideal, and I'll leave this issue open and check into it further. However for your use case, you may find it much simpler: ghostface is actually requireable, I just haven't documented this yet.
var fs = require('fs')
var path = require('path')
var ghostface = require('ghostface')

var options = {
  html: path.join(__dirname, 'file.html'),
  timeout: 1000,
  input: fs.createReadStream(path.join(__dirname, 'file.js')),
  phantomPath: '/usr/sbin/phantomjs'
}

ghostface(options, process, function(code, signal) {
  if(code > 0) {
    console.error(sprintf('\nphantomjs exited abnormally: %d'), code)
  }

  process.exit(code || signal === 'SIGTERM' ? 0 : 1)
})

…admittedly, this is not a very clean interface, but it wasn't intended for public consumption (yet!). Let me know if you think that'll work for you, and like I say, I'll leave this issue open as a reminder to:

Document the programatic interface
Figure out what the root of this bug is

oh, and a quick note on the above: the process object that I pass in, you could construct yourself, it just wants something that takes this shape:
{
  stdin: readableStream,
  stderr: writableStream,
  stdout: writableStream
}

You don't have to specifically pass in the process object, but that's possibly easiest for what you're looking to do. You can see how I very simply mock this object in the tests: https://github.com/fardog/ghostface/blob/master/test/index.js#L175

This actually does work for my situation. Thank you!
While it isn't ideal, it works for me. And while I can personally work around the issue, maybe other people won't be able to, so keeping the issue open is a good idea :D
Also, piping into the CLI is what I tried to do initially, and it works for me too, except even that wasn't exiting with proper error codes either. BUT I see the bug there, and I can help you with that.
Super cool that this can be used with a require!
Thanks again.


Refactor open tas

Refactor OpenTas

Moved enum Category into a Struct, to prevent collisions.
Moved open_file_return_data::auto_close fields into a struct.
Moved open_file_return_data::auto_put fields into a struct.
Added method ReadStep to consolidate extract step data code from groups, templates, & steps.

Not really happy with the name ReadStep, however i am proud of the technique of using a vector iterator to reuse the same code for steps, templates (and groups).

Those are both fair points, and i hope to do a second revision someday.


added icons to toolbar

Added fontawesome icons to Previous, Next and Agenda buttons

hi there, thanks for the PR. Not sure if you meant to send this to your fork, but I don't think this is a good change for the default component. It adds build complexity and design opinions that are harder to change. If you want add icons you can still do via a custom toolbar or custom messages thanks!


feat(query): Default Service Account In Use for Kubernetes

Proposed Changes

Default Service Account In Use for Kubernetes
Probablyi s a confilict with https://github.com/Checkmarx/kics/pull/5078

I submit this contribution under the Apache-2.0 license.

Hi @cxMiguelSilva, just got tagged by you referencing my PR 😎
Just wanted to let you know that this check is already realized by the service_account_token_automount_not_disabled rule. It additionally covers another case, where automountServiceAccountToken is specified separately.

Hi @cxMiguelSilva, just got tagged by you referencing my PR 😎
Just wanted to let you know that this check is already realized by the service_account_token_automount_not_disabled rule. It additionally covers another case, where automountServiceAccountToken is specified separately.

Hi @Churro  thanks a lot for your help  😀


Start of issue 718, file not existing clean up

[ ] Is it mergable?
[ ] Did it pass the tests?
[ ] If it introduces new functionality in scripts/ is it tested?
Check for code coverage.
[ ] Is it well formatted? Look at make pep8, make diff_pylint_report,
make cppcheck, and make doc output. Use make format and manual
fixing as needed.
[ ] Did it change the command-line interface? Only additions are allowed
without a major version increment. Changing file formats also requires a
major version number increment.
[ ] Is it documented in the ChangeLog?
[ ] Was a spellchecker run on the source code and documentation after
changes were made?

Can 2 people please review this code? @b-wyss @bocajnotnef @brtaylor92

Looks good to me minus the non-mergable status.

Looks good to me as well, unless you want to change existance to existence? Totally up to you, but the rest looks okay!

@mr-c has the compatibility problem with pep8/autopep8 been fixed?

Yes, sorry. Update to the latest from the master branch and you should be
good to go.
On Fri, Mar 13, 2015, 14:38 jessicamizzi<EMAIL_ADDRESS>wrote:

@mr-c https://github.com/mr-c has the compatibility problem with
pep8/autopep8 been fixed?
—
Reply to this email directly or view it on GitHub
https://github.com/ged-lab/khmer/pull/772#issuecomment-79232679.

Thanks!


tearing down the infrastructure and any extra nodes

This will do better teardown node groups and teardown all cloud formations in one play by running the following.
ansible-playbook -i inventory/aws/hosts -e 'region=us-east-1 stack_name=stack ci=true' -e '{"extra_app_nodes":["stack-ose-app-node03","stack-ose-app-node04","stack-ose-app-node05"]}' playbooks/teardown.yaml

aos-ci-test

aos-ci-test


Segmentation Fault (core dumped) on exit from unit test that imports tf.contrib.rnn

System information

Have I written custom code (as opposed to using a stock example script provided in TensorFlow): Yes
OS Platform and Distribution (e.g., Linux Ubuntu 16.04): Linux Ubuntu 14.04
TensorFlow installed from (source or binary): Source
TensorFlow version (use command below): 1.0.0
Bazel version (if compiling from source): 0.4.4
CUDA/cuDNN version: 8.0/5110
GPU model and memory: GeForce GTX 980 Ti
Exact command to reproduce: python -m unittest discover -s tests -p "example_test.py"(see below for details)

Describe the problem
I am running Tensorflow code from within the Python unittest module. The individual unit-tests, each of which train a specific architecture, run successfully with an OK. However, I observed that given the above described system configuration, I receive a Segmentation Fault (core dumped) just before the program exits. And this leads to the overall test being marked as FAIL (despite the individual tests passing).
On further investigation, I observed that the segmentation fault can be prevented from occurring by preventing the tensorflow/contrib/rnn/python/ops/_gru_ops.so file from being loaded by the load_op_library function inside tensorflow.contrib.rnn.python.ops.gru_ops
Source code / logs
Say I have a folder my_code that contains a tests folder where my unit-tests are all located. The error can be reproduced by running an example_test.py (given below) within the unittest module using the call python -m unittest discover -s tests -p "example_test.py" from within the my_codedirectory. The filemy_code/tests/example_tests.py` contains the following:
import unittest
import tensorflow as tf

class SomeTestClass(unittest.TestCase):
    """Some docstring."""

    def test_something(self):
        print("Testing something...\n")
        print tf.contrib.rnn.LSTMCell
        session = tf.Session()
        session.close()

Note that the error occurs only when both session is created and there is a reference to tf.contrib.rnn.

I'm having the same problem - my python code that uses TensorFlow will segfault when the python process terminates. I'm also using TF 1.0.0, but haven't touched any of the source code.

@gunan, do you have any ideas on this?

I was able to reproduce this in 1.0.1, but I found that in the nightly build it works fine, so I'd recommend upgrading to at least 1.2.

I am using tensorflow-gpu binary and could not reproduce this with v1.1.0 (current PyPI version).
Log is here.

Yes - I don't see the problem in v1.1 or higher. However, our team is heavily using v1.0 and we won't be able to upgrade everything anytime soon....
For what it's worth, I found a temporary fix:
I have a train() method, in which i have something like
def train(self, ...):     self.get_model(...)     self.fit(...)
in which get_model() builds the model:
def get_model(self, ...):     tf.reset_default_graph()     self.tf_graph = tf.Graph()     with self.tf_graph.as_default():         build graph...(this is where I use tf.contrib.rnn)
and fit() trains the model:
def fit(self, ...):     with self.tf_graph.as_default():         self.sess = tf.Session()         self.sess.run(...)
The temporary fix I added was in train():
def train(self, ...):     _ = tf.Session()   # adding this makes the segfault go away     self.get_model(...)     self.fit(...)
What's interesting is the session returned from _ = tf.Session() is never used anywhere, because in fit() I make a new session and use that session.
Hopefully this helps anyone who's also stuck in v1.0 for the moment...

This issue is automatically closed due to lack of activity. Please re-open if this is still an issue for you. Thanks!


Add support so aws_codedeploy deploys to Lambda

Duplicate of https://github.com/iasql/iasql-engine/issues/1787


Ensure consumer background tasks are cancelled after subscribe failures

Motivation
Some of the background consumer tasks are being started in the ConsumerImpl constructor though these are not being cancelled if the consumer creation fails, leaving active refs to these objects.

run java8 tests


Migrate docs from wiki to quarto

Overview
See title. Much of this is a straightforward migration of the existing docs, but modifications have been made where necessary. For example, I've omitted any direct references to the scrapers that would instead be covered in that documentation, and have adjusted sections that discuss technologies/methods that we no longer use here.

Connects #1158

Demo

Testing Instructions

Run the docs locally following the instructions in the README

Confirm that things look as expected, items described within make sense, and links work

Metro is seeing if they could share any docs from their side. In the meantime I'm requesting a re-review so we can bring this bit in. I'll keep the issue open though.


Is there a way to have frontmatter fields that are links show up as editable fields?

What would you like to be added?
For example, I have a dataview for movies that looks like this
TABLE WITHOUT ID
	file.link as "Movie",
        director,
        plot
WHERE
	contains(in, [[Movies]]) and
SORT rating desc, year asc

And plot shows up in Projects  because it's just a bunch of text, but director does not show up because it's a link like:
director:
  - "[[Peter Jackson]]"

Any tricks to make fields with links work with Projects?
Why is this needed?
To make dataview fields show up, even if they are links.

Thanks for the report, I tested your case and find this would possibly be a bug. Link syntax seems to be ignored both in a text field and a list field. I will look into this when I'm available.

That was fast! Thanks for the reply :)

Sorry for the long wait. This will be solved in the incoming release 1.17.3. Please note that to need to config the field to enable rich text rendering to make the link clickable. A previous PR #814 makes this possible.


remove xalan dependency due to it being end of life

PJ Fanning (Bug 66171):
Xalan is no longer supported.
https://lists.apache.org/thread/s8kjny5270ssfcp46v0fl39lk98987w7
It is better to use JAXP TransformerFactory than using xalan directly. If you add xalan dependency just to ensure that you have a JAXP compliant transformer on the classpath, this is unnecessary - the Java runtime has a built-in implementation.
Xalan dependency in:
https://mvnrepository.com/artifact/org.apache.jmeter/ApacheJMeter_core/5.5
Severity: normal
OS: All

Hi team, any update/progress on this?

There's a new Xalan release pending, so I guess we'll update xalan in JMeter soon: https://lists.apache.org/thread/1pmwtqy1wf6wh96h9d1cdwn8qsdy42zh

https://github.com/HtmlUnit/htmlunit-xpath
Can this be an alternative?
I checked the same problem with htmlunit and saw this ticket:
https://github.com/HtmlUnit/htmlunit/issues/493

I updated Xalan to 2.7.3 in https://github.com/apache/jmeter/pull/5880


make the color important

some themes have important font colors. this fights against that.
@rchen1992

👍


working validator input reading

Pull Request Description
What issue does this change request address?
Closes  #37
What are the significant changes in functionality due to this change request?
Enables input reading mechanics for thevalidator.

For Change Control Board: Change Request Review
The following review must be completed by an authorized member of the Change Control Board.

[x] 1. Review all computer code.
[x] 2. If any changes occur to the input syntax, there must be an accompanying change to the user manual and xsd schema. If the input syntax change deprecates existing input files, a conversion script needs to be added (see Conversion Scripts).
[x] 3. Make sure the Python code and commenting standards are respected (camelBack, etc.) - See on the wiki for details.
[x] 4. Automated Tests should pass.
[x] 5. If significant functionality is added, there must be tests added to check this. Tests should cover all possible options.  Multiple short tests are preferred over one large tes.
[x] 6. If the change modifies or adds a requirement or a requirement based test case, the Change Control Board's Chair or designee also needs to approve the change.  The requirements and the requirements test shall be in sync.
[x] 7. The merge request must reference an issue.  If the issue is closed, the issue close checklist shall be done.
[x] 8. If an analytic test is changed/added, the the analytic documentation must be updated/added.
[x] 9. If any test used as a basis for documentation examples have been changed, the associated documentation must be reviewed and assured the text matches the example.

Added Issue reference.
PR is approved. Checklist passed.

Checklist passed... Merging.


Add details in Home Page

Add Funding
Add details of the group mission
Add Goals and objectives (attached)

Add objectives to the homepage
Purposes & Objectives(1).pdf