Conversions: FromLossy and TryFromLossy traits

Add FromLossy, TryFromLossy traits.
Discuss the bigger picture of conversions and the as keyword.
Specify that From implementations must not only be safe, but also exact.
Rendered RFC

I think the word exact is problematic and that it defined imprecisely in this RFC.
It suggests to me that for  X: From<Y> there must exist an inversion Y: From<X> such that X and Y are isomorphic. But u8 → u16 does not have an inversion u16 → u8 precisely because it is a narrowing operation.
Since From is such a central trait in the ecosystem, I think the requirements and guarantees placed on implementations of it should be specified with mathematical precision. As currently specified, I am not sure how the changed definition extends to types outside the standard library.
One possible definition that seems to fit the criteria described in the RFC is:

[X: From<Y>] → [∀ y0, y1 : Y.  X::from(y0) ≡ X::from(y1) → y0 ≡ y1].

Other questions that this RFC provoked:

Should From::from always be a "pure" computation?
Is such a change in recommendation re. From considered to be a breaking change?

should From be allowed to allocate remote resources?

It suggests to me that for X: From there must exist an inversion Y: From such that X and Y are isomorphic

I disagree with the need for an isomorphism; e.g. I see no problem with f32's two representations for 0 both mapping to the same integer value.
To be fair, that's not what you said. But surely an exact conversion f: A → B implies only that for any a1, a2 in A, a1==a2 exactly when f(a1) == f(a2) (and derived from this: if a==b can be defined for a in A and b in B, then a==f(a) for all a in A). Okay, that's roughly what your type rule says, if I parse it right (the . in the middle is confusing; I've usually seen | used (maths contexts); also I believe we need a two-way implication).

Should From::from always be a "pure" computation?

Meaning an intrinsic? I don't really see why this is important.

Is such a change in recommendation re. From considered to be a breaking change?

Since this wasn't specified before, I don't see it as a big issue, but I suppose it could be (if libs remove their implementations to comply).

should From be allowed to allocate remote resources?

It musn't fail (existing requirement, not from this RFC). Exactly what this means with regards to unlikely (and probably unrecoverable) panics is up for interpretation, I guess (and specifying something won't necessarily influence how people use it for anyway).

@dhardy To be clear, I'm not saying that X: From<Y> must also imply Y: From<X>, so I don't think there should be an isomorphism requirement either. I'm just saying the way you framed it suggests that to me.

Okay, that's roughly what your type rule says

That's exactly what the proposition says :)
In other words:
 X: From<Y>   X::from(y0) ≡ X::from(y1)
--------------------------------------- proper_From_implementation
                 y0 ≡ y1

or if we are inclined to be somewhat more pedantic:
Δ ⊢ Implemented(X, From<Y>)
Γ ⊢ y0 : Y
Γ ⊢ y1 : Y
Γ, Δ ⊢ X::from(y0) ≡ X::from(y1)
--------------------------------- proper_From_implementation
Γ, Δ ⊢ y0 ≡ y1

Meaning an intrinsic? I don't really see why this is important.

No, "pure" means deterministic here. That is (formulated somewhat imprecisely), for
any two y0, y1 : Y, y0 ≡ y1 → X::from(y0) ≡ X::from(y1). So X::from could have no side-effects.
I don't such a requirement is necessary tho?

It's not just about this RFC, but can't we make FromFoo traits just aliases for TryFromFoo<Error=!>?

@Centril someone likes their type theory :smile:
WP has an article on pure functions. But it's not the same as what you wrote which is about from respecting the ≡ operator (presumably in this case PartialEq, which is not required to be implemented for either type). Or if by ≡ you mean "the same binary representation" or something, I don't think that's a distinction worth making; it's not something we have any operator to test (aside from indirectly with memory comparisons), and it would be possible (though wrong) for PartialEq to depend on other things such as the memory alignment.
Back on topic, I guess all from implementations should be pure (ignoring allocations / caches), but I don't think specifying this in the documentation is useful in any way.
@newpavlov Good point.  ;) I think we should specify formally (with logic -- probably not typing rules) in the RFC and the documentation of From what laws should hold and what is meant by "exact", as we've done with PartialEq.
Yeah being imprecise about what ≡ exactly is is what I meant about "formulated somewhat imprecisely" ;)

I guess all from implementations should be pure (ignoring allocations / caches), but I don't think specifying this in the documentation is useful in any way.

If that is a reasonable expectation the user has, we might as well specify it?

@dhardy
I am not sure, I guess it will depend how trait aliases and never type will shape out. For example if impl's on trait aliases will be allowed, then current implementations of From will be still legal and without blank implementations of TryFrom for From we should be fine. And of course we will need automatic coercion (or straight equivalence maybe?) of Result<T, !> to just T. (I am not sure how folks who work on it think it should work) But either way backward compatibility concerns only From and Into traits, not the traits described in this RFC.

Updated regarding several things mentioned.

Wrt. the definition of exactness for From, is it not sufficient that the function is injective?

I agree that as is problematic and like the idea of adding alternatives. (Maybe deprecating it some day, but this RFC can be incremental improvement without going that far.)

Regarding naming: I find the world lossy to be a bit vague. What kind of loss are we talking about? It turns out that this RFC is all about approximating numeric types, so maybe Approximate and TryApproximate would work as trait names? Verbs are nice for single-method traits because they also work well for the method name.

Regarding the prelude: we have precedent with TryFrom and TryInto of adding unstable traits and saying “we’ll consider adding them to the prelude when stabilizing”. When we did, a number of crates broke because they had copy/pasted the traits into their own code in order to use them on stable Rust, and now had two traits in scope with methods of the same name, causing a compiler error. We had to revert: https://github.com/rust-lang/rust/pull/49518
I think the lesson here is that when discussing new traits here and there’s a chance that we’ll want them in the prelude, we should add them to the prelude as soon as they are implemented even if we end up removing them before stabilization.
However if we make an API that works without traits being in scope, being in the prelude doesn’t matter. There is precedent for this with the str::parse inherent method and the FromStr trait. Since this RFC is about numeric approximation, it is concerned with a comparatively small number of types (14, v.s. unbounded for the more general From and TryFrom traits). We could have inherent methods on the relevant numeric types, similar to str::parse.

@repax The documentation of From should explain what injective means for those not familiar with that mathematical jargon :)
But yes, saying that T::from must be an injective function should be sufficient since to be a function in the first place, T::from must satisfy ∀ s0, s1 : S. s0 ≡ s1 → T::from(s0) ≡ T::from(s1) since a function satisfies ∀ x, y : S. x ≡ y → f(x) ≡ f(y) by definition.
The link to PartialEq is not something testable for all From implementations since there is no requirement that X: From<Y> → [X: PartialEq ∧ Y: PartialEq] so idk about that part...

@Centril of course all functions are homomorphisms w.r.t. equality (whoops). I guess we can drop the PartialEq stuff then.
@SimonSapin thanks for the feedback.

Yes, the approximations could be inherent methods, though it is much easier to write generic code using traits (one of the motivations here).
I guess these could be named Approximate etc., though isn't the parallel with the name From useful?

I suppose there should be Into parallels too.

it is much easier to write generic code using traits (one of the motivations here).

I’m having a hard time imagining a situation where generic code with these traits in a where clause is useful. Do you have some examples?
If I remember correctly the existence of both From and Into has to do with impl coherence. In some combinations of types one can be implemented but not the other. I don’t think this is as much of a concern here since I don’t expect many impls outside of the standard library.

https://github.com/rust-lang/rust/pull/42456 was another attempt that could be mentioned in Prior Art, even though it didn’t land.

Adding traits sounds unnecessarily confusing and hierarchical.  And maybe breaking.  Could const members address this without breakage?
pub trait From<T> {
    fn from(T) -> Self;
    const INJECTIVE: Option<bool> = None;
    const SURJECTIVE: Option<bool> = None;
}

If you needed this, then you'd write where U: From<T, const INJECTIVE = Some(true)> or whatever.

@SimonSapin this is what motivated me. Ideally we wouldn't need to implement this trait ourselves. But it may not have wide usage.
@burdges interesting idea. But why use Option and why mention SURJECTIVE? And if we can have const INJECTIVE: bool = true; then does U: From<T> imply U only matches injective ("non lossy") implementations? If so then this might be workable. (But would it also be possible to match any implementation, e.g. with U: From<T, INJECTIVE = _>?)

@dhardy This example is sort of making my point. As far as I can tell it is not generic, and $ty is (after macro expansion) a concrete type at every $ty::cast_from_int(…) call site.
Is there a use case for code like either of these?
fn foo<N>(…) where N: CastFromInt<u32> {…}
fn bar<N>(…) where u32: CastFromInt<N> {…}

I think const SURJECTIVE: Option<bool> = None; keeps existing impl From<..> for .. code correct by not specifying either true or false incorrectly.

Perhaps not. So I guess the alternative is simple but involves quite a few methods: add these to every integer type:
fn to_f32(self) -> f32;
fn to_f64(self) -> f64;

These types already have to_le and to_be functions and proposed to_bytes, so I guess these fit.

But @burdges U: From<T, SURJECTIVE = None> (i.e. the default) will not match From<T, SURJECTIVE = Some(false)> implementations, so it becomes a breaking change to specify these constants in existing implementations (and a pain to use generically).

We do nee a default regardless.  I suppose you're saying const INJECTIVE: bool = false; can be the default because code should never use U: From<T, SURJECTIVE = false>?  Fine.
If you want to avoid breaking changes then you can specify it like this:
/// Opaque type used to specify if a `From` is injective.
pub struct Injectivity(bool);
const INJECTION: Injectivity = Injectivity(true)

pub trait From<T> {
    fn from(T) -> Self;
    const INJECTIVE: Injectivity = Injectivity(false);
}

pub trait Into<T>: Sized {
    fn into(self) -> T;
    const INJECTIVE: Injectivity = Injectivity(false);
}
impl<T, U> Into<U> for T where U: From<T>
{
    fn into(self) -> U {
        U::from(self)
    }
    const INJECTIVE: From::Injectivity = <U as From>::INJECTIVE;
}

@burdges adding constants like that seems way more confusing (and also breaking) than what is proposed in the RFC.
IMO it was a mistake to add From/To traits in the first place without specifying a meaning beyond what their signature implies. Luckily, in practice usage of these traits has followed the rules set down in this RFC (that conversions with these traits should be lossless).
Having more traits is fine, but I think it would be useful to reduce the number of traits which must be implemented, so I think going forward all new infallible traits should have a generic implementation for types implementing the infallible trait with an error type of !:
impl<T> FromLossy<T> for TryFromLossy<T, Error=!> { ... }

Also, @dhardy, the trait definitions in the RFC are missing their generic parameter T - I believe this is a mistake?

I imagined the coherence rules isolated any breakage when adding a default constant, but..  I suppose you're talking about how the trickier coherence rules around the existing type parameter, yes?
I suggested constants here largely because they permit positive or indeterminate defaults, while traits mostly only support negative defaults.  It's possible negative defaults are desirable here, but the RFC design looked kinda bent around negative defaults.  I think folks have voiced roughly that opinion, hence my initial suggestion being a default None interpreted as unspecified.
As an aside, constants are less confusing because they're documented with the main trait, but rust doc could be modified to have subordinate traits documented on the same page as the main trait, so whatever.
Oh.  If one really wants unspecified defaults, one might also define trait FromProperties<T> : From<T> { const INJECTIVE : bool }, but that's messier.

@Diggsey what's your take on @SimonSapin's point that it may be better to find options which don't involve adding to the prelude? FromLossy is more generic than what he proposed but is not the only option.
Auto-implementing TryFromLossy for all FromLossy impls makes sense. Doing the same for TryFrom / From is breaking (for any explicit implementations of both) but, once specialisation is ready, we should be able to introduce a default implementation. There's one caveat here: introducing usage of default on an existing implementation is (technically) a breaking change, so either we should not auto-implement TryFromLossy before specialisation, or we should put up with slightly different semantics there.

It's a good point - I would at least like a solution which is generic over the numeric types (including user-defined numeric types) but I don't think it need be more general than that.
Regarding the prelude - would it be possible to have the traits exist in both the prelude and a module, and only stabilise the version outside the prelude? (Effectively preventing the kinds of conflicts @SimonSapin described without committing to stabilisation of the trait's existence in the prelude).
TBH, I'm not sure these need to be in the prelude when the as operator still exist, as that will cover the most common uses.

I don’t think we can stabilize a trait without stabilizing its presence in the prelude. (That is #[unstable] on pub use items doesn’t actually work, unfortunately.) My suggestion was having the trait(s) in the prelude while they’re still unstable, to hopefully cause conflict if someone tries to have a trait with the same method names in the mean time, and decide one prelude inclusion before stabilization.
I think that this new feature (whatever form it ends up taking) should be designed to replace the need for the as operator (which has its issues discussed in the RFC), so the existence of as shouldn’t be an argument for this feature being less needed.

Roughly, this RFC proposes supporting two classes of conversions:

i* / u* → f* — always succeed, but may lose precision
f* → i* / u* — may lose precision and may fail

This requires at least one trait generic over the error type (TryFromLossy) and optionally another with no error type (FromLossy), unless we just add a lot of small methods (to_f32(), to_u128() etc. or from_* equivalents; i.e. 2×2×10=40 methods excluding isize/usize). Using traits seems the better option.
Ease-of-use then requires either that these traits are in the prelude, or that some utility methods are added on at least one of the types being converted (for example, f32::from_num<T> -> f32 where Self: FromLossy<T>). Since the latter option involves extra methods and redundant ways of using the underlying traits, it does not look like a good choice to me.
So that leaves the RFC proposal as still being the best option IMO.
There remains scope for changing the names/presentation (e.g. ApproxFrom instead of FromLossy, or IntoApprox).

First, :+1::+1::+1: to the direction of providing core methods that explicitly do one predictable thing instead of yolo-as.  (I'd like to officially deprecate as for things that aren't coercions eventually.)
I like clarifying the intent of the From trait.  I do wonder if mentioning PartialEq is the way to go here; this seems to be using more of an abstract equivalence since a strict reading in terms of PartialEq means that you could map NANs to random outputs and still meet the rules.
As a stab at a different (or additional) direction, what about something tying From and TryFrom closer?  So something like a lib guideline that if you have let b = B::from(a); you could also be able to do let a_prime = A::try_from(b).unwrap(); to recover an equivalent value.  (Which of course still doesn't define equivalent, but...)  For the reflexive blanket that's trivially true, and it implies some currently-missing-but-reasonable things like A: TryFrom<Option<A>> to go with Option<A>: From<A>.
Good job on the description of FromLossy, but I think the word "lossy" is too fuzzy about what exactly kind of lossy is appropriate with it -- truncation is, of course, also lossy.  I think I like the alternative names referencing "approximate", or a word like that, better.  Possibly-crazy idea: add an associated const with the accuracy.  (I don't have a good idea how exactly to specify that, though.)
Rather than TruncateFrom, how about WrappingFrom?  That makes sense for all combinations of integer types, doing sign transmutes for iN <-> uN, truncations for uM -> uN, extensions for uN -> uM (linted to suggest just From in concrete cases), etc.  Those are all "just shove it into the type I said" kinds of conversions that usually don't preserve the value the way From and TryFrom do, so I think I'd be happy with them all in a single trait.  And it could even do things like bool: WrappingFrom<u128> or u32: From<BigInteger> with a well-defined meaning.
(That would also suggest SaturatingFrom to fill out the usual trio -- since CheckedFrom is just TryFrom -- but that's not something as does so makes sense to wait for later.)

Previous iteration on this idea: https://github.com/rust-lang/rfcs/pull/1218 (without FP and with "related problems" though).
Some practical evaluation: https://internals.rust-lang.org/t/implicit-widening-polymorphic-indexing-and-similar-ideas/1141/70

If you excuse me for brainstorming, how about using new structs instead of new traits? I e, two options, either using a wrapper struct or as an empty struct to use in a tuple:
 let x: u32 = Truncate(my_u64).into();
 let y: u32 = ((my_u64, Truncate)).into();

...not sure which one is more ergonomic and easier to read.
I could also imagine a OrDefault struct, like:
let x: u8 = OrDefault(my_f64).into();
let x: u8 = ((my_f64, OrDefault)).into();

...if people want a quick'n'easy conversion, where everything in the f64 that doesn't fit into u8 just gets the default value for u8 (i e, zero).
I could imagine this living outside std, either to keep std minimal or while evaluating the feature.
From / into is already in the prelude and adding more traits seems difficult according to earlier comment, so piggybacking on the from/into traits seems beneficial for that reason too.

I don't like how this proposal introduces 'lossy' conversions without specifying exactly what 'lossy' is supposed to entail. Is is acceptable to implement a 'lossy' conversion that sends everything to the same value? If I 'lossily' convert a floating-point value to an integer, what can I say about the result?
I suspect that in situations where the user wants to perform a 'lossy conversion', they actually want something more specific: the closest representable approximation, or the least representable upper bound/greatest representable lower bound for the original value.

I addressed some of the comments here (especially @scottmcm's very helpful suggestions).

TruncateFrom → WrappingFrom and is extended to include sign-conversions and is now a core part of the RFC
I tried to be precise about what "lossy" means and what acceptable approximations are (@fstirlitz is this good enough for you?)
I added suggestions to add default implementations of TryFrom and TryFromLossy once specialisation is ready

Note that since FromLossy is a special case of TryFromLossy we don't need it, but it does seem nice to have for convenience. Note further that From and TryFrom are also special cases of TryFromLossy but I'm less convinced this can be usefully specified.

Possibly-crazy idea: add an associated const with the accuracy. (I don't have a good idea how exactly to specify that, though.)

(@scottmcm) I'm not sure how that could work either. For integers a constant of 1 would work, but e.g. for f32 the precision varies from 2-149 to 2104.
We could still have default implementations of TryFromLossy for all other "from" implementations though, I think.

Thinking more about the meaning of "lossy", I had an epiphany: it's not that it's "small error" -- if so then f32::from_lossy(1) could give 1.00027 fairly legitimately and INF could never be converted to an integer type since there'd always be infinite error -- but that it's "the closest value".
The thing that makes me particularly happy about that phrasing is that FromNearest is actually a generalization of the saturating_* pattern the same way that TryFrom is the generalization of the checked_* pattern -- impl ClosestFrom<i64> for u32 preserves values in 0..=u32::MAX, and saturates those above MAX to MAX and those below 0 to 0, as those values are the closest to the input i64.
That definition does mean that there wouldn't be things like impl FromLossy<String> for AsciiString, but I'm personally good with that, as it hits all the badness about lossy how, exactly? and the "there are different ways it could be lossy" that make traits poor choices.
So maybe even put things in core::num?  Putting WrappingFrom next to Wrapping there certainly seems reasonable.  Of course, that could also suggest following @diwic's idea and just using impl From<Wrapping<i64>> for Wrapping<u16> instead of impl WrappingFrom<i64> for u16...

Ah, thanks, I missed the update to the FromLossy docs.

but rather this should be an error

That brings a few things to mind:

Today we have std::f32::INFINITY as u8 == 255.  Is that operation available with the current proposed traits?  Did you have a way in mind that that would become available with some not-proposed-right-now trait?
What's the smallest value of f such that u8::try_from_lossy(f) fails?
What does the associated error type for the conversions look like? Is it a ZST, or does it give you variants for the possible failure reasons?

Well, these are my views:

I don't see the approximation INFINITY → 255 as ever being useful.
From the doc above, I define u as "the precision of the result type at x", which for integer types like u8 is 1. |x - from_lossy(x)| < u thus implies that it is legal to cast values in the range (254, 256) (excluding end points) to 255. However, the above doesn't require that this is implemented; it might make more sense for an implementation to cast to nearest integer and reject out-of-range values, in which case I suppose values in the range [-0.5, 255.5) could be cast to u8 successfully.
By ZST you mean a unit type? I don't know. Existing TryFrom implementations use TryFromSliceError and TryFromIntError which are unit types. We could potentially use enum TryFromFloatError { IsNan, OutOfRange } but I don't know if this is useful.

Regarding errors: we can make them unit / zero-sized types at first, but with a private field so that extending them later if we want to is compatible.

Update: specify that the WrappingFrom trait should support isize and usize types.
Question: should FromLossy also support these types? I'd like to add this, but for example impl FromLossy<usize> for f64 is an exact conversion on 32-bit platforms, which could overlap with a potential impl From<usize> for f64.
So really this is about overlap: should FromLossy support all valid From conversions via a blanket implementation?

@SoniEx2 then this gives motivation for adding SaturatingFrom as mentioned above if pre-clamping your values to [0, MAX) is not good enough. I don't think we should have this behaviour by default...
but this comes back to the name FromLossy being unclear. So perhaps we should have ApproxFrom (or Approximate as suggested by @SimonSapin) instead?

In some cases it would be a logic bug, for example the way we use integers to sample from the Bernoulli distribution. Rust favours error-checking however this is practical (e.g. with checked overflows being active by default in debug builds), so it seems sensible not to allow this type of bug to be easily hidden.
Other than that though, I don't see another reason.

@dhardy wouldn't that use a TryFrom or something?

No, because p * SCALE may not be an integer (for very small p`).

Regarding naming: I find the world lossy to be a bit vague. What kind of loss are we talking about? It turns out that this RFC is all about approximating numeric types, so maybe Approximate and TryApproximate would work as trait names? Verbs are nice for single-method traits because they also work well for the method name.

I also find this a bit vague, and makes me wonder, what is the advantage of traits with "generic" names versus traits implementing single well-defined operations: .truncate(), .zero_extend(), .sign_extend(), .round(MODE), etc. ?

This makes sense @gnzlbg. For sure there are good alternatives to what is in the RFC. I'd really like to see a solution in this space but I'm not sure whether my proposal is the best one.
That said, I have tried to define "lossy" quite well in the docs now (since the quoted comment was written).

.truncate(), .zero_extend(), .sign_extend()

These all come under the WrappingFrom trait now. Personally I quite like how they come together, but it took me some time to properly understand these conversions:

Equivalently, the conversion results can be defined numerically (where n
is the initial value and M is the number of distinct values in the target
type):

for unsigned target, n % M
for signed target, if n % M < M/2 { n % M } else { n % M - M }

.round() (or .round(MODE), maybe, one day, or not)

This implies either different trait names like RoundFrom or RoundTo, or perhaps some more comprehensive trait. I agree, more discussion of these alternatives would be nice. I don't have much time to go over this myself now.

The intended semantics are specified in more detail than before, but they're still somewhat handwave-y, and I'm not very pleased with truncation proposed for floating-point → integer approximations. For one, I don't see why in float → unsigned approximations one would want to consider values in the range (−1, 0) to be validly approximable by 0, but at the same time have −1 be an erroneous, unapproximable value.
Under the Euclidean modulo RFC, I listed a handful of semi-concrete use cases for flooring and Euclidean division-with-remainder operations. Can we write down a similar list of use cases for approximate conversions?
Right now I suspect that if we start looking for those, we're going to find:

Cases where the user wants a guarantee that the approximation error is as small as possible. Using truncation semantics without a possibility to override them goes against this.
Cases where the user wants to receive an explicit approximation error. This case isn't served by the current proposal at all. For conversions from floating-point to other built-in number types, converting back and subtracting the difference would address this, but such a solution may perform poorly, or not be available at all for abstract types T and U.
Cases where erring in one direction is acceptable, but erring in the other is not. Similarly, for float-to-integer conversions this would be doable by calling .ceil() or .floor() before the conversion, but this may fail to be suitable in the general case, and even this workaround may fail to catch some corner cases. (Consider for example a series of types denoting time durations in concrete units: milliseconds, nanoseconds, etc. together with an abstract, usize-like time duration type with a platform-dependent resolution that you pass to the sleep function.)
Cases where the user is perfectly willing to sacrifice some precision as long as the approximation errors aren't too egregious, and simply wishes to obtain the fastest approximation the platform provides (e.g. in multimedia rendering). I grant there may be circumstances where that's exactly what is wanted, but so far Rust seems to follow the principle of steering the user towards making such correctness trade-offs in an informed, explicit manner (compare unsafe, longer/'scarier' method names for more dangerous/uncommon operations like *_unchecked, etc.).

I don't think those cases would be served well by this proposal, maybe except for the last one.

So, I'm tempted to change this RFC as follows, but would like some feedback before doing so:

rounding mode for conversion to integer (previous post)
add SaturatingFrom
rename FromLossy / TryFromLossy to RoundFrom / TryRoundFrom

I didn't fully engage with @newpavlov's suggestion to make From<T> an alias of TryFrom<T, Error=!>. Is this better than the current proposal (auto impl of TryFrom via specialisation)? An implication of the alias approach is that all TryFrom impls have two functions, one of which can only panic on failure. To repeat @newpavlov's code:
pub trait TryFrom<T>: Sized {
    type Error;
    fn from(value: T) -> Self {
        Self::try_from(value).unwrap_or_else(|_| panic!("error"))
    }
    fn try_from(value: T) -> Result<Self, Self::Error> {
        Ok(Self::from(value))
    }
}
trait From = TryFrom<Error=!>;

The implication (if we can implement this for the existing From/TryFrom which I'm less sure about) is that T::from(S) is valid for all types T supporting TryFrom<S>, but may panic.
I think therefore the current proposal with separate traits but default implementations via specialisation is better?
This still leaves the question about whether the new traits should be in the prelude. I don't currently see a good design which doesn't use the prelude, so my current answer is yes.

There is also the potential to support other rounding modes, e.g. fn round_from_mode(val: S, mode: Mode) -> Self, but this gets messy (also want a try_round_from_mode fn).

.zero_extend(), .sign_extend()

There is occasionally reason to "sign-extend" unsigned types, so I suppose we could add an extra trait for this (alongside WrappingFrom to handle the common cases):
trait Extend<S> {
    fn zero_extend(val: S) -> Self;
    fn sign_extend(val: S) -> Self;
}

But overall this just seems messy (adding another trait only for slightly better ergonomics in a corner case).
Alternatively we could have Truncate and Extend instead of WrappingFrom, but probably the convenience of a single trait out-weighs the benefits of the explicit operations here?

I'm not an expert on CPU operations, but I suspect most of these conversions can be "fast enough". Perhaps there are some specific CPU or GPU conversion modes we should support?

Well, for example on x86 with SSE2 the C-style double → int truncating cast can be realised as a single instruction, CVTTSD2SI. All other approximate conversions are going to incur extra instruction overhead: either from flipping rounding mode bits, or from additional range-checking logic. Other architectures may offer similar 'fast' conversion instructions (which I suspect to most likely perform the very same truncating one).

This article covers CPU rounding modes (most of these are single instruction).
The rounding mode for CVTTSD2SI depends on the MXCSR register. I guess this design is to allow extra control without increasing CPU bandwidth/instruction count, but I'm not sure how we should handle this — state-ful APIs are less easy to use correctly (when you care about the exact mode).

@dhardy I am not sure that we are allowed to even change the rounding mode per LLVM rules but I'll trust @rkruppe on that .

@dhardy: I assume that's an error in the manual. The instruction that uses the rounding mode specified in the MXCSR register is CVTSD2SI (note single T).

From the RFC:

Tweak the documentation to clarify that From implementations should not lose precision (i.e. should be injective)

This may not be possible, because as https://github.com/rust-lang/rfcs/pull/2506#issuecomment-408659599 points out some existing impls in std do not satisfy this property and removing them would be a breaking change. For example, From<Vec<T>> for BinaryHeap<T> does not preserve order.

IMHO, things like Vec -> BinaryHeap and Vec -> HashSet should implement FromLossy and have their From implementations deprecated.

As far as I know impl deprecation isn’t really a thing.

I really like RoundFrom.  It's the best word I've seen yet in this thread for what it does, and it conveniently would allow it to exist in num, and thus not get blanket impls from normal From, since I definitely wouldn't say that String: RoundFrom<&str> makes sense.
I'm not a fan of trying to turn From/TryFrom into a single trait.  I definitely don't want anything on TryFrom that reports failure by panicking; someone can .try_into().unwrap() if they want that.
(Given a time machine, I'd rather like trait From<T> where T: TryFrom<Self> {} as a way to mark the expectations for the conversion, but obviously that cannot happen now.)
I definitely agree with omitting zero_extend and sign_extend.  People can change signedness (via WrappingFrom) if they need that, the same as they need to do for right shifts.
Obviously I would be happy to see SaturatingFrom 🙂
In fact, the phrasing as WrappingFrom + RoundingFrom + SaturatingFrom (all in core::num) gives a nice, focused title for the RFC as something like "numeric conversion traits", helping to scope it down to the critical parts, and avoid questions like whether Vec -> HashSet fits in any generic trait.
The question of rounding mode is an interesting one.  I think the word "rounding" suggests to me that i8::rounding_from(f32::from(1i8) ± ϵ) should still be 1i8, which implies that it should be round-to-nearest (also the default LLVM floating point environment).  But at the same time, I was picturing round-downward for u8: SaturatingFrom<f32> so that i..i+1 mapped to i.  I do think it shouldn't be round-toward-zero, since that makes 0 twice as wide as the other integers.

the word "rounding" suggests to me that i8::round_from(f32::from(1i8) ± ϵ) should still be 1i8

This is an important point. While I don't think that's something that can be taken for granted (since there are several ways to round things), it could be very misleading if in fact it rounds down (or to zero, or anything other than to nearest).
So much as I like the name RoundFrom, it seems like we should use ApproxFrom instead and/or make RoundFrom actually round to nearest (perhaps with ties to even). (From my POV, something like ApproxFrom with rounding down to neg-inf or 0, probably the former, seems important.)
The other point about using the num crate is an interesting one. To me, ApproxFrom, WrappingFrom, and potentially also SaturatingFrom feel like std lib functionality (the first two are pretty-much required for various common numeric conversions, if not using the as keyword). On the other hand, RoundFrom might fit well in num — except that it's so similar to ApproxFrom that having both feels redundant.

The other point about using the num crate is an interesting one

I meant the core::num module (which I apparently only specified later in the post, oops).  I definitely agree that these should be in std, as a critical part of being able to deprecate them in as later.
On round-to-nearest, what does f64 -> f32 do?  I would have hoped round-to-nearest, but I assume round-towards-zero by truncating would be the cheap implementation.  Maybe the differing expectations here is evidence that it should just take an enum of the four rounding modes?

The other point about using the num crate is an interesting one

I meant the core::num module (which I apparently only specified later in the post, oops).  I definitely agree that these should be in std, as a critical part of being able to deprecate them in as later.
On round-to-nearest, what does f64 -> f32 do?  I would have hoped round-to-nearest, but I assume round-towards-zero by truncating would be the cheap implementation.  Maybe the differing expectations here is evidence that it should just take an enum of the four rounding modes?

The other point about using the num crate is an interesting one

I meant the core::num module (which I apparently only specified later in the post, oops).  I definitely agree that these should be in std, as a critical part of being able to deprecate them in as later.
On round-to-nearest, what does f64 -> f32 do?  I would have hoped round-to-nearest, but I assume round-towards-zero by truncating would be the cheap implementation.  Maybe the differing expectations here is evidence that it should just take an enum of the four rounding modes?

Maybe the differing expectations here is evidence that it should just take an enum of the four rounding modes?

How would we implement that? IIRC there were some undefined behavior related issues with changing the rounding mode in LLVM to do these types of computations.

Many existing Into and From impls are already lossy.
Any impl Into<Y> for X  is analogous to a function X -> Y, and an impl TryInto<Y> from X is a partial function. The existence of corresponding From and TryFrom impls also says something about the nature of the Into impl.
An alternative to this RFC might be to acknowledge that Into and From impls can be lossy, but introduce new traits for when they're not:
trait Surj<T>: TryInto<T> + From<T> {} // sort of
trait Inj<T>: Into<T> + TryFrom<T> {}
trait Bij<T>: Surj<T> + Inj<T> {}

impl<A, B> Surj<A> for B where B: TryInto<A> + From<A> {}
impl<A, B> Inj<A> for B where B: Into<A> + TryFrom<A> {}
impl<A, B> Bij<A> for B where B: Surj<A> + Inj<A> {}

The definitions – Surj in particular – are a little loose, so perhaps other names could be chosen.

See https://docs.rs/frunk_core/0.2.0/frunk_core/generic/trait.Generic.html for Bij

I will push some minor tweaks to the RFC, but still not sure what to do with regards to rounding behaviour etc. For f64 → f32 as well as float → int conversions, we also have range issues, and the following options:

undefined behaviour: common in C but definitely not preferred; I believe this is what using unguarded instructions like CVTTSD2SI would result in
saturating cast (excepting NaN): convert to min/max of output type when out of range, or error value if input is NaN; this is sometimes desired but other times errors are preferable
saturating cast (including NaN): as above but also output MAX (or some such) when input is NaN and output type has no NaN value; this is probably never useful except that it avoids need for error handling (though saturating_cast(input).unwrap_or(MAX) probably suffices)
explicit error: probably the best default

Of the above, it seems that it may be worth supporting both saturating casts and explicit errors, e.g. via SaturatingFrom and TryRoundFrom.
Then there is rounding behaviour (see @fstirlitz's post):

truncate (towards zero): seems to be the default / fast option; good enough in many cases
round to nearest: common human-friendly and best-approximation option
round up / round down: less common
round with explicit error: requires multiple output parameters; probably no fast general-purpose implementation so may be better left to third-party libraries?

Of the above, it would be nice to support at least the first two options; maybe also round up/down. However, how should this be done? One possibility would be to have multiple methods within a TryRoundFrom trait, though this doesn't properly allow partial implementation:
trait TryRoundFrom<T> {
    type Error;
    fn trunc_from(x: T) -> Result<Self, Self::Error>;
    fn round_from(x: T) -> Result<Self, Self::Error>;
}

I believe this is what using unguarded instructions like CVTTSD2SI would result in

Doesn't CVTTSD2SI perform a truncation?

What does truncation mean for values out of range of the target type?

Julia has a nice approach to conversions, basically parameterised rounding functions. Unfortunately by the time you add error handling and account for Rust not allowing default values for type arguments, the nearest equivalent is much less ergonomic):
trait Round<T> {
    type Error;
    fn round(&self) -> Result<T, Error>;
}
let y = Round::<u32>::round(2.6f32)?;
// In Julia, it always rounds to the nearest integer:
assert_eq!(Round::<f64>::round(10.1).unwrap(), 10.0);
// though we'd probably not want to do this

The above is not exactly ergonomic Rust. But regarding @SimonSapin's previous point about focusing on numeric conversions, it suggests the following direction:

RoundFrom, TruncFrom, CeilFrom, FloorFrom
all traits have an Error type and always return a Result
could be in prelude or could just be traits in std::num or std::convert

Which brings up another point: why are the error types CharTryFromError, TryFromIntError, TryFromSliceError not in the std::convert module and not even consistently named?
Or, there is another possible approach, though more convoluted and probably a bad idea:
/// pure marker wrapper
pub struct Round<T>(T);

impl TryFrom<Round<f32>> for u32 { ... }

Thanks @rkruppe!

For saturating conversions (clamping to target range), is it reasonable to only support a single rounding mode (perhaps truncation) or is there reason to support multiple rounding modes, as with other conversions?
Also, for saturating conversions from floating point, what should be the behaviour on NaN and Inf input? (Do we need error handling anyway, via Result or panic?) @SoniEx2?
Because saturating conversions could be as complex as non-saturating (erroring) variants, or could be simplified to a single trait & function.

@SimonSapin would you know if there are any proposals similar to ? in try_f()? but for .unwrap()? The point is that T::round_from(x).unwrap() is not very ergonomic, but something like T::round_from(x)?! might be good enough.
Or will we even get free unwrapping from Result<T, !> types eventually?
The point is that in this case we can use uniform error handling (type Error; fn round_from(x: T) -> Result<Self, Self::Error>;). But if the above is not the case, then there is more reason to have multiple traits (as with FromLossy and TryFromLossy in the current RFC, though those names will be changed).

@dhardy Per http://smallcultfollowing.com/babysteps/blog/2018/08/13/never-patterns-exhaustive-matching-and-uninhabited-types-oh-my/ it sounds like the plan is to allow this:
fn foo(x: Result<T, !>) {
    let Ok(value) = x;  // This pattern is irrefutable, since the Err(!) case is impossible
}

… but I don’t know of any proposal for doing it within an expression in any way close in terseness to the ? operator.

For saturating conversions (clamping to target range), is it reasonable to only support a single rounding mode (perhaps truncation) or is there reason to support multiple rounding modes, as with other conversions?

I don't see why the handling out values outside the target range should be related to how you're rounding fractional quantities within the range.

I don't see why the handling out values outside the target range should be related to how you're rounding fractional quantities within the range.

It's not related; it's just an attempt to simplify. Because so far it looks like we might want all these:
fn trunc_from(x: T) -> Result<Self, Error>;
fn round_from(x: T) -> Result<Self, Error>;
fn ceil_from(x: T) -> Result<Self, Error>;
fn floor_from(x: T) -> Result<Self, Error>;
fn saturating_trunc_from(x: T) -> Result<Self, Error>;
fn saturating_round_from(x: T) -> Result<Self, Error>;
fn saturating_ceil_from(x: T) -> Result<Self, Error>;
fn saturating_floor_from(x: T) -> Result<Self, Error>;

(and this is assuming we don't have separate try_trunc_from etc.)
Of course, we could reduce this list by means of a rounding_mode parameter, but that's less convenient to use much of the time.
Or we could use T::try_from(Round(x)) etc. as I suggested above, though it has drawbacks — Round etc. need to be imported and unintuitively Round(x) doesn't actually do anything.

Of course, we could reduce this list by means of a rounding_mode parameter, but that's less convenient to use much of the time.

Alternatively, there could be an ApproxScheme type parameter, see conv::ApproxFrom. However, this is prone to result in unportable code. I think it is best to have explicit methods as you suggested.

Currently "as" casts are a language feature, and they are a basic feature in a language, so I think the problem of casts should be discussed and worked on from a more general point of view, instead of just from a stdlib point of view like (I think) it's being discussed here, to face the bigger problem.
I think the first we should take a look at Rust code to see where most casts are, to classify them and see how much dangerous they could be.
In past I've written various posts about this, like:
https://internals.rust-lang.org/t/to-reduce-the-number-of-true-casts/3076
https://users.rust-lang.org/t/correctness-integral-overflows/6449/
In many cases the casts are like:
let i: u16 = ...;
my_slice[i as usize] = 0;

So a well rounded proposal for casts should face the problem of array/slice/vec indexes.
Another common situation is this one, Rust should offer a safe cast (that doesn't contain an unwrap) to do this:

let x: u32 = ...;
let y = (x % 10) as u8;

To do this I think a stdlib-level solution isn't good enough, you need to bake inside the compiler some value-range analysis.
Also, number casts aren't the only thing we should care about.
There are also enums:
https://users.rust-lang.org/t/c-style-enum-conversions/12861
And slices, currently in Nightly you can do this:
#![feature(try_from)]

use std::convert::{TryFrom, TryInto};

fn foo(a: &[u8; 4]) {
    println!("{:?}", a);
}

fn main() {
    let data = [10, 20, 30, 40, 50];

    let conv1 = <&[u8; 4]>::try_from(&data[1..]);
    foo(conv1.unwrap());

    foo(<_>::try_from(&data[1..]).unwrap());

    let conv2: Result<&[u8; 4], _> = data[1..].try_into();
    foo(conv2.unwrap());

    foo(data[1..].try_into().unwrap());
}

But the slice <-> array conversions is currently too much underpowered, tricky and unergonomic, it should become more flexible and simpler to use, keeping code correctness.
Beside the value-range analysis of numeric expressions the compiler could perform analysis on the length of the slices too, to allow slice <-> array conversions with a light syntax, keeping safety and avoiding unwraps() where the slice->array conversion is provably always correct (like in the (x % 10) as u8 case above).

I noticed that the RFC and the discussion above has been almost exclusively focussed on numeric conversions.
However, it is my impression that From is used for much more than that. The documentation uses String::from as an example of a From<&str> for String. Similarly, I would expect thst a FromLossy trait would be implemented for conversation between UTF-8 and Latin1 text encodings.
Going further, one could imagine a parsing library that implements TryFrom<&str> for AST. The latter might be better expressed with a function parse(&str) -> Result<AST, ParseError> so maybe the sentiment is that these traits should only be used for "small" and "quick" conversions?

From this example:
let i: u16 = ...;
my_slice[i as usize] = 0;

one would think it could be solved by by implementing SliceIndex<[T]> for I where usize: From<I>. At least, this would solve the case mentioned — but since there are a lot of methods which take usize index parameters (including most of the Vec methods), generalising this to all applicable cases would result in a fair amount of code churn (and probably a noticeable increase to compile time and some cases of failed monomorphisation).
In C++ one could take a different approach: implicit conversions. Rust doesn't have them and C++ over-uses them, but perhaps this would be a legitimate use.

True, that wouldn't work because of type inference.
What might work is (a) trait Implicit<S>: From<S> {} selectively enabling implicit conversions plus (b) changes to type inference such that if the type is not directly specified (x: T) then there must be a unique type among input types (x = f() where f -> I) or, failing that, output types (g(x) where g(y: O)), such that all bounds are met (T: Implicit<I> and Implicit<O>: T).

So, lets try to revive some of the discussion here...

Of course, we could reduce this list by means of a rounding_mode parameter, but that's less convenient to use much of the time.

Alternatively, there could be an ApproxScheme type parameter, see conv::ApproxFrom. However, this is prone to result in unportable code. I think it is best to have explicit methods as you suggested.

This is an interesting solution. I think the reason for the compile error is just because ApproxFrom has an associated type? There is also a lesson here: ApproxFrom has a lot of implementations (only considering the primitive types).
We could do something similar using wrapper types as above:
/// pure marker wrapper
pub struct Round<T>(T);

impl TryFrom<Round<f32>> for u32 { ... }

assert_eq!(u32::try_from(Round(13.7f32))?, 14);

One could achieve a similar effect with the existing rounding methods, but could we optimise it to similar code?
let x = u32::try_from(13.7f32.round())?;

let i: u16 = ...;
my_slice[i as usize] = 0;

This is a numeric conversion supported by From. usize::from(i) works; i.into() doesn't (the slice impls Index<I> where I: SliceIndex<[T]> which includes usize, Range, RangeFull, etc.).
There's a related case: let i: u32 = ...;. In this case From is not supported; TryFrom is, but (1) this is not currently in the prelude so must be manually imported and (2) usize::try_from(i).unwrap() is much less ergonomic.
Making safe conversion as ergonomic as via the as keyword is a tall order! Given how common this is, it might be worth adding a specialist trait with a function like fn as_usize(self) -> .... To make error handling ergonomic, there are only two options: panic-on-error, or add syntactic-sugar like ?! for .unwrap().
Alternatively, it seems @leonardo-m is hinting that we should have a language-level solution which does not have the drawbacks of as... it seems such a feature would be quite difficult to introduce.

There are also enums

As mentioned, there seems to be no reason that one can't implement From<T> for B for each enum T with base type B. Alternatively std could add a new trait for enum conversions. This goes beyond the scope of this RFC.

let x: u32 = ...;
let y = (x % 10) as u8;

This is just an optimiser problem IMO, and not common enough to worry about ergonomics.

But the slice <-> array conversions is currently too much underpowered, tricky and unergonomic

Fundamentally the length is part of an array's type and a slice's value, so a library solution can never omit the error check from slice[..4].into::<[_; 4]>(). If one must have an ergonomic type-safe conversion, then panic-on-error is probably the way to go (but not with From which is only for infallible conversions).
The only option for proving correctness at compile-time is language-level support via some new syntax (e.g. slice[..4] as [_; 4]).
Both these examples (and many others) desire type-safe conversion which should be provably-correct, but where proof is beyond the capabilities of language syntax + the type system. To address these, we could add a method to TryFrom:
pub trait TryFrom {
    type Error;
    fn try_from(value: T) -> Result<Self, Self::Error>;

    #[expect_success]
    fn do_from(value: T) -> Self;
}

where do_from will panic-on-error but the new expect_success attribute causes the compiler to generate a warning if it is unable to prove that the method will not panic. (Or we could just leave out the attribute.)

I definitely like (soft-)deprecating as's use for lossy conversions. I feel like as should only be used for two things:

safe, exact casts (u8 -> u16, maybe f32 -> f64?)
casts between raw pointers or casts from functions to raw pointers (or other related casts)

Perhaps we could warn on as being used for lossy conversions and then switch to a hard error for the 2021 (or later) edition?

With my lang hat on, this is a big enough change that there's no way it's happening for the 2021 edition.
The lint does exist in clippy, but even there it seems to be allow-by-default: https://rust-lang.github.io/rust-clippy/master/index.html#cast_lossless

Perhaps we could warn on as being used for lossy conversions and then switch to a hard error for the 2021 (or later) edition?

No.
2021 or not, I feel that a lint against as (while useful!) should never be switched to error by default, let alone a hard error. Yes as is ambiguous and would often be better replaced by more explicit APIs (ignoring for a moment that those APIs mostly don’t exist yet). But forcing that transition on existing code based would just be a barrier for adoption of a new edition. And for what benefit? Many of these existing as expressions are in fact correct.

A small subset of you might be interested in my new library, easy-cast. It attempts to replace most uses of as in for numeric casts (though not all), and covers a small sub-set of what this RFC proposed.

For anyone still interested on this topic: It just came up again in a thread about Rusts ergonomics around numerical computations.
https://internals.rust-lang.org/t/rust-and-numeric-computation/20425/14


Don't keep STDIN open if not attached

The -i argument for docker keeps STDIN open even when the container is
not attached. In some ci environments this will likely by the case and
result in this error: cannot enable tty mode on non tty input
This also changes the scratch and output directory creation to use -p
so it will both create the whole path and not fail if the directory
exists.

👍


Invalid URL port: "undefined"

Environment

React-Native 0.66.3
Android

Description
Running react-native webpack-start results in error message on Android device: Invalid URL port: "undefined"
Reproducible Demo
The webpack.config.js is the same as per the template. Hermes is enabled and there isn't really any other special configuration enabled. Logs show:
[20:27:04.678Z][DevServerProxy] Server listening at http://[::]:8081
ℹ [20:27:04.680Z][DevServerProxy] Dashboard available at: http://localhost:8081/dashboard
ℹ [20:27:06.024Z][DevServerProxy] Hermes device connected { deviceId: 0 }
ℹ [20:27:25.051Z][DevServerProxy] Dashboard client connected { clientId: 'client#0' }
ℹ [20:27:39.099Z][DevServerProxy] Starting compiler worker { platform: 'android', port: 46031 }
ℹ [20:27:39.966Z][DevServer@android] Server listening at http://[::]:46031
ℹ [20:27:39.970Z][DevServerProxy] fetching from remote server { source: 'http://localhost:46031/index.bundle?platform=android' }
ℹ [20:27:40.044Z][DevServerProxy] fetching from remote server {
  source: 'http://localhost:46031/api/dashboard/stats?platform=android'
}
ℹ [20:27:40.046Z][DevServerPlugin] Successfully run: /opt/android-sdk/platform-tools/adb reverse tcp:46031 tcp:46031
ℹ [20:27:40.055Z][webpack-dev-middleware] wait until bundle finished: /index.bundle?platform=android
ℹ [20:27:40.061Z][DevServer@android] Dashboard client connected { clientId: 'client#0' }
ℹ [20:27:40.080Z][webpack-dev-middleware] wait until bundle finished: /api/dashboard/stats?platform=android
ℹ [20:28:06.399Z][LoggerPlugin] Bundle built { time: 26241 }
ℹ [20:28:06.432Z][DevServerProxy] response received
ℹ [20:28:06.472Z][DevServerProxy] response received
ℹ [20:28:55.618Z][DevServerProxy] fetching from remote server {
  source: 'http://localhost:46031/index.bundle?platform=android&dev=true&minify=false&app=com.dominate&modulesOnly=false&runModule=true'
}
ℹ [20:28:55.642Z][DevServerProxy] response received
ℹ [20:28:55.999Z][DevServerProxy] React Native client connected { clientId: 'client#0' }
ℹ [20:28:56.663Z][Console] [HMRClient] Connecting... {"url": "ws://<IP_ADDRESS>:undefined/__hmr"}

The url in HMRClient log is missing port value. The port should be available in process.env.__PUBLIC_PORT__ global variable, which is added by DevServerPlugin.
Can you check if console.log(process.env.__PUBLIC_PORT__) works? Or if you're overwriting the variable anywhere?

Not exactly this error, but for me on iOS, HMR is not working. But the reason seems same, PUBLIC_PORT env is undefined.
ℹ [21:48:45.606Z][DevServerProxy] response received
ℹ [21:48:46.455Z][DevServerProxy] React Native client connected { clientId: 'client#0' }
ℹ [21:48:48.219Z][Console] [HMRClient] Connecting... {"url": "ws://localhost:undefined/__hmr"}
ℹ [21:48:48.219Z][Console] {"msg": "rtcvs-client ver.: 18.1.0  commitHash: 6754bb0c75 "}
ℹ [21:48:48.220Z][Console] [HMRClient] Error {"isTrusted": false, "message": "The operation couldn’t be completed. Connection refused"}
ℹ [21:48:48.221Z][Console] [HMRClient] Disconnected

Not happening in a fresh project though.

@roshan-lmi Can you provide me your Webpack config and package.json?

Webpack config:
const path = require('path');
const webpack = require('webpack');
const ReactNative = require('@callstack/repack');
const TerserPlugin = require('terser-webpack-plugin');

/**
 * More documentation, installation, usage, motivation and differences with Metro is available at:
 * https://github.com/callstack/repack/blob/main/README.md
 *
 * The API documentation for the functions and plugins used in this file is available at:
 * https://re-pack.netlify.app/
 */

/**
 * This is the Webpack configuration file for your React Native project.
 * It can be used in 2 ways:
 * - by running React Native CLI eg: `npx react-native start` or `npx react-native bundle`
 * - by running Webpack CLI eg: `npx webpack-cli -c webpack.config.js`
 *
 * Depending on which option you chose the output might be different, since when running with
 * React Native CLI most of the values from `getMode`, `getPlatform`, etc. will be filled in by React Native CLI.
 * However, when running with Webpack CLI, you might want to tweak `fallback` values to your liking.
 *
 * Please refer to the API documentation for list of options, plugins and their descriptions.
 */

/**
 * Get options from React Native CLI when Webpack is run from `react-native start` or `react-native bundle`.
 *
 * If you run Webpack using Webpack CLI, the values from `fallback` will be used - use it
 * to specify your values, if the defaults don't suit your project.
 */

const mode = ReactNative.getMode();
const dev = mode === 'development';
const context = ReactNative.getContext();
const platform = ReactNative.getPlatform({ fallback: process.env.PLATFORM });
const minimize = ReactNative.isMinimizeEnabled({ fallback: !dev });
const devServer = ReactNative.getDevServerOptions();
const reactNativePath = ReactNative.getReactNativePath();

/**
 * Depending on your Babel configuration you might want to keep it.
 * If you don't use `env` in your Babel config, you can remove it.
 *
 * Keep in mind that if you remove it you should set `BABEL_ENV` or `NODE_ENV`
 * to `development` or `production`. Otherwise your production code might be compiled with
 * in development mode by Babel.
 */
process.env.BABEL_ENV = mode;

/**
 * Webpack configuration.
 */
module.exports = {
  mode,
  /**
   * This should be always `false`, since the Source Map configuration is done
   * by `SourceMapDevToolPlugin`.
   */
  devtool: false,
  context,
  /**
   * `getInitializationEntries` will return necessary entries with setup and initialization code.
   * If you don't want to use Hot Module Replacement, set `hmr` option to `false`. By default,
   * HMR will be enabled in development mode.
   */
  entry: [
    ...ReactNative.getInitializationEntries(reactNativePath, {
      hmr: devServer.hmr,
    }),
    './container_autogenerated/index.js',
  ],
  resolve: {
    /**
     * `getResolveOptions` returns additional resolution configuration for React Native.
     * If it's removed, you won't be able to use `<file>.<platform>.<ext>` (eg: `file.ios.js`)
     * convention and some 3rd-party libraries that specify `react-native` field
     * in their `package.json` might not work correctly.
     */
    ...ReactNative.getResolveOptions(platform),

    /**
     * Uncomment this to ensure all `react-native*` imports will resolve to the same React Native
     * dependency. You might need it when using workspaces/monorepos or unconventional project
     * structure. For simple/typical project you won't need it.
     */
    alias: {
      'react-native': reactNativePath,
      // app: path.resolve(__dirname),
    },
  },
  /**
   * Configures output.
   * It's recommended to leave it as it is unless you know what you're doing.
   * By default Webpack will emit files into the directory specified under `path`. In order for the
   * React Native app use them when bundling the `.ipa`/`.apk`, they need to be copied over with
   * `ReactNative.OutputPlugin`, which is configured by default.
   */
  output: {
    clean: true,
    path: path.join(__dirname, 'build', platform),
    filename: 'index.bundle',
    chunkFilename: '[name].chunk.bundle',
    publicPath: ReactNative.getPublicPath(devServer),
  },
  /**
   * Configures optimization of the built bundle.
   */
  optimization: {
    /** Enables minification based on values passed from React Native CLI or from fallback. */
    minimize,
    /** Configure minimizer to process the bundle. */
    minimizer: [
      new TerserPlugin({
        test: /\.(js)?bundle(\?.*)?$/i,
        /**
         * Prevents emitting text file with comments, licenses etc.
         * If you want to gather in-file licenses, feel free to remove this line or configure it
         * differently.
         */
        extractComments: false,
      }),
    ],
  },
  module: {
    /**
     * This rule will process all React Native related dependencies with Babel.
     * If you have a 3rd-party dependency that you need to transpile, you can add it to the
     * `include` list.
     *
     * You can also enable persistent caching with `cacheDirectory` - please refer to:
     * https://github.com/babel/babel-loader#options
     */
    rules: [
      {
        test: /\.[jt]sx?$/,
        resolve: {
          extensions: ['.ts', '...'],
        },
        include: [
          /node_modules(.*[/\\])+react/,
          /node_modules(.*[/\\])+@react-native/,
          /node_modules(.*[/\\])+@react-navigation/,
          /node_modules(.*[/\\])+@react-native-community/,
          /node_modules(.*[/\\])+@expo/,
          /node_modules(.*[/\\])+pretty-format/,
          /node_modules(.*[/\\])+metro/,
          /node_modules(.*[/\\])+abort-controller/,
          /node_modules(.*[/\\])+@callstack[/\\]repack/,
          /node_modules(.*[/\\])+@gorhom[/\\]portal/,
          // additional lib
          /node_modules(.*[/\\])+rn-fetch-blob/,
          // mono repo lib
          /node_modules(.*[/\\])+@goto[/\\]redux-listeners/,
          /node_modules<other packages in the monorepo>

        ],
        use: 'babel-loader',
      },
      /**
       * Here you can adjust loader that will process your files.
       *
       * You can also enable persistent caching with `cacheDirectory` - please refer to:
       * https://github.com/babel/babel-loader#options
       */
      {
        test: /\.(js|ts|tsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            /** Add React Refresh transform only when HMR is enabled. */
            plugins: devServer.hmr ? ['module:react-refresh/babel'] : undefined,
          },
        },
      },
      {
        test: ReactNative.getAssetExtensionsRegExp(ReactNative.ASSET_EXTENSIONS.filter((ext) => ext !== 'svg')),
        use: {
          loader: '@callstack/repack/assets-loader',
          options: {
            platform,
            devServerEnabled: devServer.enabled,
            /**
             * * Defines which assets are scalable - which assets can have
             * * scale suffixes: `@1x`, `@2x` and so on.
             * * By default all images are scalable.
             */
            scalableAssetExtensions: ReactNative.SCALABLE_ASSETS,
          },
        },
      },
      {
        test: /\.svg$/,
        use: [
          {
            loader: '@svgr/webpack',
            options: {
              native: true,
              // You might want to uncomment the following line.
              // More info: https://react-svgr.com/docs/options/#dimensions
              // dimensions: false,
            },
          },
        ],
      },
    ],
  },
  plugins: [
    /**
     * Various libraries like React and React rely on `process.env.NODE_ENV` / `__DEV__`
     * to distinguish between production and development
     */
    new webpack.DefinePlugin({
      __DEV__: JSON.stringify(dev),
    }),

    /**
     * * This plugin makes sure the resolution for assets like images works with scales,
     * * for example<EMAIL_ADDRESS><EMAIL_ADDRESS>     * */
    new ReactNative.AssetsResolverPlugin({
      platform,
    }),

    /**
     * React Native environment (globals and APIs that are available inside JS) differ greatly
     * from Web or Node.js. This plugin ensures everything is setup correctly so that features
     * like Hot Module Replacement will work correctly.
     */
    new ReactNative.TargetPlugin(),

    /**
     * By default Webpack will emit files into `output.path` directory (eg: `<root>/build/ios`),
     * but in order to for the React Native application to include those files (or a subset of those)
     * they need to be copied over to correct output directories supplied from React Native CLI
     * when bundling the code (with `webpack-start` command).
     * In development mode (when development server is running), this plugin is a no-op.
     */
    new ReactNative.OutputPlugin({
      platform,
      devServerEnabled: devServer.enabled,
    }),

    /**
     * Runs development server when running with React Native CLI start command or if `devServer`
     * was provided as s `fallback`.
     */
    new ReactNative.DevServerPlugin({
      platform,
      ...devServer,
    }),

    /**
     * Configures Source Maps for the main bundle based on CLI options received from
     * React Native CLI or fallback value..
     * It's recommended to leave the default values, unless you know what you're doing.
     * Wrong options might cause symbolication of stack trace inside React Native app
     * to fail - the app will still work, but you might not get Source Map support.
     */
    new webpack.SourceMapDevToolPlugin({
      test: /\.(js)?bundle$/,
      exclude: /\.chunk\.(js)?bundle$/,
      filename: '[file].map',
      append: `//# sourceMappingURL=[url]?platform=${platform}`,
      /**
       * Uncomment for faster builds but less accurate Source Maps
       */
      // columns: false,
    }),

    /**
     * Configures Source Maps for any additional chunks.
     * It's recommended to leave the default values, unless you know what you're doing.
     * Wrong options might cause symbolication of stack trace inside React Native app
     * to fail - the app will still work, but you might not get Source Map support.
     */
    new webpack.SourceMapDevToolPlugin({
      test: /\.(js)?bundle$/,
      include: /\.chunk\.(js)?bundle$/,
      filename: '[file].map',
      append: `//# sourceMappingURL=[url]?platform=${platform}`,
      /**
       * Uncomment for faster builds but less accurate Source Maps
       */
      // columns: false,
    }),

    /**
     * Logs messages and progress.
     * It's recommended to always have this plugin, otherwise it might be difficult
     * to figure out what's going on when bundling or running development server.
     */
    new ReactNative.LoggerPlugin({
      platform,
      devServerEnabled: devServer.enabled,
      output: {
        console: true,
        /**
         * Uncomment for having logs stored in a file to this specific compilation.
         * Compilation for each platform gets it's own log file.
         */
        // file: path.join(__dirname, `${mode}.${platform}.log`),
      },
    }),
  ],
};

This is a big monorepo and we have lots and dependencies are distributed in multiple package.json. Can you mention what information do you need from package.json ? I can try to provide that.

Could you try adding:
new webpack.DefinePlugin({
  'process.env.__PUBLIC_PORT__': JSON.stringify(devServer.port)
})

to plugins in Webpack config and let me know if anything changes?

Hey, I added this but nothing changes for me. I get the same warnings and errors. I did console log for devServer.port and it's not undefined.
Just to not leave anything, I see these warnings too:
ℹ [12:19:29.007Z][LoggerPlugin] Bundle built with warnings { time: 7095 }
⚠ [12:19:29.007Z][LoggerPlugin] Warning in "../../node_modules/react-native/Libraries/Core/setUpReactRefresh.js": Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
⚠ [12:19:29.007Z][LoggerPlugin] Warning in "../../node_modules/react-native/Libraries/Performance/Systrace.js": Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

The these warning are irrelevant to this problem, I'm seeing them in TesterApp and there's nothing I can do about them.
Could you open http://localhost:8081/index.bundle?platform=ios and search the bundle for ../repack/dist/client/setup/modules/WebpackHMRClient.js and sent me the content of this module?
It should look like this
/***/ "../repack/dist/client/setup/modules/WebpackHMRClient.js":
/*!***************************************************************!*\
  !*** ../repack/dist/client/setup/modules/WebpackHMRClient.js ***!
  \***************************************************************/
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

// here is the content of the module - copy and sent me this part

const currentExports = __react_refresh_utils__.getModuleExports(module.id);
__react_refresh_utils__.registerExportsForReactRefresh(currentExports, module.id);

if (true) {
  // some irrelevant HMR stuff
}

/***/ }),

hmm It looks like this for me.
/***/<EMAIL_ADDRESS>/*!******************************************************************************************!*\
  !***<EMAIL_ADDRESS>***!
  \******************************************************************************************/
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";
var _interopRequireDefault=__webpack_require__(/*! ../../node_modules/@babel/runtime/helpers/interopRequireDefault */ "../../node_modules/@babel/runtime/helpers/interopRequireDefault.js");var _regenerator=_interopRequireDefault(__webpack_require__(/*! ../../node_modules/@babel/runtime/regenerator */ "../../node_modules/@babel/runtime/regenerator/index.js"));var _classCallCheck2=_interopRequireDefault(__webpack_require__(/*! ../../node_modules/@babel/runtime/helpers/classCallCheck */ "../../node_modules/@babel/runtime/helpers/classCallCheck.js"));var _createClass2=_interopRequireDefault(__webpack_require__(/*! ../../node_modules/@babel/runtime/helpers/createClass */ "../../node_modules/@babel/runtime/helpers/createClass.js"));var _getDevServerLocation=__webpack_require__(/*! ../utils/getDevServerLocation */ "../../node_modules/@callstack/repack/dist/client/setup/utils/getDevServerLocation.js");function _defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;}var HMRClient=function(){function HMRClient(app){var _this=this;(0,_classCallCheck2.default)(this,HMRClient);this.app=app;_defineProperty(this,"url",void 0);_defineProperty(this,"socket",void 0);_defineProperty(this,"lastHash",'');this.url="ws://"+(0,_getDevServerLocation.getDevServerLocation)().hostname+":"+undefined+"/__hmr";this.socket=new WebSocket(this.url);console.log('[HMRClient] Connecting...',{url:this.url});this.socket.onopen=function(){console.log('[HMRClient] Connected');};this.socket.onclose=function(){console.log('[HMRClient] Disconnected');};this.socket.onerror=function(event){console.log('[HMRClient] Error',event);};this.socket.onmessage=function(event){try{_this.processMessage(JSON.parse(event.data.toString()));}catch(error){console.warn('[HMRClient] Invalid HMR message',{event:event,error:error});}};}(0,_createClass2.default)(HMRClient,[{key:"upToDate",value:function upToDate(hash){if(hash){this.lastHash=hash;}return this.lastHash===__webpack_require__.h();}},{key:"processMessage",value:function processMessage(message){var _message$body,_message$body2,_message$body3,_message$body$errors,_message$body$warning;switch(message.action){case'building':this.app.LoadingView.showMessage('Rebuilding...','refresh');console.log('[HMRClient] Bundle rebuilding',{name:(_message$body=message.body)===null||_message$body===void 0?void 0:_message$body.name});break;case'built':console.log('[HMRClient] Bundle rebuilt',{name:(_message$body2=message.body)===null||_message$body2===void 0?void 0:_message$body2.name,time:(_message$body3=message.body)===null||_message$body3===void 0?void 0:_message$body3.time});case'sync':if(!message.body){console.warn('[HMRClient] HMR message body is empty');return;}if((_message$body$errors=message.body.errors)!==null&&_message$body$errors!==void 0&&_message$body$errors.length){message.body.errors.forEach(function(error){console.error('Cannot apply update due to error:',error);});this.app.LoadingView.hide();return;}if((_message$body$warning=message.body.warnings)!==null&&_message$body$warning!==void 0&&_message$body$warning.length){message.body.warnings.forEach(function(warning){console.warn('[HMRClient] Bundle contains warnings:',warning);});}this.applyUpdate(message.body);}}},{key:"applyUpdate",value:function applyUpdate(update){if(false){}if(!this.upToDate(update.hash)&&module.hot.status()==='idle'){console.log('[HMRClient] Checking for updates on the server...');this.checkUpdates(update);}}},{key:"checkUpdates",value:function checkUpdates(update){var _module$hot,_module$hot2,updatedModules,renewedModules,unacceptedModules,_module$hot3,_module$hot4;return _regenerator.default.async(function checkUpdates$(_context){while(1){switch(_context.prev=_context.next){case 0:_context.prev=0;this.app.LoadingView.showMessage('Refreshing...','refresh');_context.next=4;return _regenerator.default.awrap((_module$hot=module.hot)===null||_module$hot===void 0?void 0:_module$hot.check(false));case 4:updatedModules=_context.sent;if(updatedModules){_context.next=9;break;}console.warn('[HMRClient] Cannot find update - full reload needed');this.app.reload();return _context.abrupt("return");case 9:_context.next=11;return _regenerator.default.awrap((_module$hot2=module.hot)===null||_module$hot2===void 0?void 0:_module$hot2.apply({ignoreDeclined:true,ignoreUnaccepted:false,ignoreErrored:false,onDeclined:function onDeclined(data){console.warn('[HMRClient] Ignored an update due to declined module',{chain:data.chain});}}));case 11:renewedModules=_context.sent;if(!this.upToDate()){this.checkUpdates(update);}unacceptedModules=updatedModules.filter(function(moduleId){return renewedModules&&renewedModules.indexOf(moduleId)<0;});if(unacceptedModules.length){console.warn('[HMRClient] Not every module was accepted - full reload needed',{unacceptedModules:unacceptedModules});this.app.reload();}else{console.log('[HMRClient] Renewed modules - app is up to date',{renewedModules:renewedModules});this.app.dismissErrors();}_context.next=20;break;case 17:_context.prev=17;_context.t0=_context["catch"](0);if(((_module$hot3=module.hot)===null||_module$hot3===void 0?void 0:_module$hot3.status())==='fail'||((_module$hot4=module.hot)===null||_module$hot4===void 0?void 0:_module$hot4.status())==='abort'){console.warn('[HMRClient] Cannot check for update - full reload needed');console.warn('[HMRClient]',_context.t0);this.app.reload();}else{console.warn('[HMRClient] Update check failed',{error:_context.t0});}case 20:_context.prev=20;this.app.LoadingView.hide();return _context.finish(20);case 23:case"end":return _context.stop();}}},null,this,[[0,17,20,23]],Promise);}}]);return HMRClient;}();if(true){var _require=__webpack_require__(/*! ../../node_modules/react-native */ "../../node_modules/react-native/index.js"),DevSettings=_require.DevSettings,Platform=_require.Platform;var LoadingView=__webpack_require__(/*! ../../node_modules/react-native/Libraries/Utilities/LoadingView */ "../../node_modules/react-native/Libraries/Utilities/LoadingView.ios.js");var reload=function reload(){return DevSettings.reload();};var dismissErrors=function dismissErrors(){if(Platform.OS==='ios'){var _NativeRedBox$dismiss;var NativeRedBox=__webpack_require__(/*! ../../node_modules/react-native/Libraries/NativeModules/specs/NativeRedBox */ "../../node_modules/react-native/Libraries/NativeModules/specs/NativeRedBox.js").default;NativeRedBox===null||NativeRedBox===void 0?void 0:(_NativeRedBox$dismiss=NativeRedBox.dismiss)===null||_NativeRedBox$dismiss===void 0?void 0:_NativeRedBox$dismiss.call(NativeRedBox);}else{var NativeExceptionsManager=__webpack_require__(/*! ../../node_modules/react-native/Libraries/Core/NativeExceptionsManager */ "../../node_modules/react-native/Libraries/Core/NativeExceptionsManager.js").default;NativeExceptionsManager===null||NativeExceptionsManager===void 0?void 0:NativeExceptionsManager.dismissRedbox();}var LogBoxData=__webpack_require__(/*! ../../node_modules/react-native/Libraries/LogBox/Data/LogBoxData */ "../../node_modules/react-native/Libraries/LogBox/Data/LogBoxData.js");LogBoxData.clear();};new HMRClient({reload:reload,dismissErrors:dismissErrors,LoadingView:LoadingView});}

It looks like this for me. Sorry for the weird markdown.

//<EMAIL_ADDRESS>/!!
<EMAIL_ADDRESS>!
*/
/*/ (function(module, __unused_webpack_exports, webpack_require) {
"use strict";
var _interopRequireDefault=webpack_require(/*! ../../node_modules/@babel/runtime/helpers/interopRequireDefault / "../../node_modules/@babel/runtime/helpers/interopRequireDefault.js");var _regenerator=_interopRequireDefault(webpack_require(/! ../../node_modules/@babel/runtime/regenerator / "../../node_modules/@babel/runtime/regenerator/index.js"));var _classCallCheck2=_interopRequireDefault(webpack_require(/! ../../node_modules/@babel/runtime/helpers/classCallCheck / "../../node_modules/@babel/runtime/helpers/classCallCheck.js"));var _createClass2=_interopRequireDefault(webpack_require(/! ../../node_modules/@babel/runtime/helpers/createClass / "../../node_modules/@babel/runtime/helpers/createClass.js"));var _getDevServerLocation=webpack_require(/! ../utils/getDevServerLocation / "../../node_modules/@callstack/repack/dist/client/setup/utils/getDevServerLocation.js");function _defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;}var HMRClient=function(){function HMRClient(app){var _this=this;(0,_classCallCheck2.default)(this,HMRClient);this.app=app;_defineProperty(this,"url",void 0);_defineProperty(this,"socket",void 0);_defineProperty(this,"lastHash",'');this.url="ws://"+(0,_getDevServerLocation.getDevServerLocation)().hostname+":"+undefined+"/__hmr";this.socket=new WebSocket(this.url);console.log('[HMRClient] Connecting...',{url:this.url});this.socket.onopen=function(){console.log('[HMRClient] Connected');};this.socket.onclose=function(){console.log('[HMRClient] Disconnected');};this.socket.onerror=function(event){console.log('[HMRClient] Error',event);};this.socket.onmessage=function(event){try{_this.processMessage(JSON.parse(event.data.toString()));}catch(error){console.warn('[HMRClient] Invalid HMR message',{event:event,error:error});}};}(0,_createClass2.default)(HMRClient,[{key:"upToDate",value:function upToDate(hash){if(hash){this.lastHash=hash;}return this.lastHash===webpack_require.h();}},{key:"processMessage",value:function processMessage(message){var _message$body,_message$body2,_message$body3,_message$body$errors,_message$body$warning;switch(message.action){case'building':this.app.LoadingView.showMessage('Rebuilding...','refresh');console.log('[HMRClient] Bundle rebuilding',{name:(_message$body=message.body)===null||_message$body===void 0?void 0:_message$body.name});break;case'built':console.log('[HMRClient] Bundle rebuilt',{name:(_message$body2=message.body)===null||_message$body2===void 0?void 0:_message$body2.name,time:(_message$body3=message.body)===null||_message$body3===void 0?void 0:_message$body3.time});case'sync':if(!message.body){console.warn('[HMRClient] HMR message body is empty');return;}if((_message$body$errors=message.body.errors)!==null&&_message$body$errors!==void 0&&_message$body$errors.length){message.body.errors.forEach(function(error){console.error('Cannot apply update due to error:',error);});this.app.LoadingView.hide();return;}if((_message$body$warning=message.body.warnings)!==null&&_message$body$warning!==void 0&&_message$body$warning.length){message.body.warnings.forEach(function(warning){console.warn('[HMRClient] Bundle contains warnings:',warning);});}this.applyUpdate(message.body);}}},{key:"applyUpdate",value:function applyUpdate(update){if(false){}if(!this.upToDate(update.hash)&&module.hot.status()==='idle'){console.log('[HMRClient] Checking for updates on the server...');this.checkUpdates(update);}}},{key:"checkUpdates",value:function checkUpdates(update){var _module$hot,_module$hot2,updatedModules,renewedModules,unacceptedModules,_module$hot3,_module$hot4;return _regenerator.default.async(function checkUpdates$(_context){while(1){switch(_context.prev=_context.next){case 0:_context.prev=0;this.app.LoadingView.showMessage('Refreshing...','refresh');_context.next=4;return _regenerator.default.awrap((_module$hot=module.hot)===null||_module$hot===void 0?void 0:_module$hot.check(false));case 4:updatedModules=_context.sent;if(updatedModules){_context.next=9;break;}console.warn('[HMRClient] Cannot find update - full reload needed');this.app.reload();return _context.abrupt("return");case 9:_context.next=11;return _regenerator.default.awrap((_module$hot2=module.hot)===null||_module$hot2===void 0?void 0:_module$hot2.apply({ignoreDeclined:true,ignoreUnaccepted:false,ignoreErrored:false,onDeclined:function onDeclined(data){console.warn('[HMRClient] Ignored an update due to declined module',{chain:data.chain});}}));case 11:renewedModules=_context.sent;if(!this.upToDate()){this.checkUpdates(update);}unacceptedModules=updatedModules.filter(function(moduleId){return renewedModules&&renewedModules.indexOf(moduleId)<0;});if(unacceptedModules.length){console.warn('[HMRClient] Not every module was accepted - full reload needed',{unacceptedModules:unacceptedModules});this.app.reload();}else{console.log('[HMRClient] Renewed modules - app is up to date',{renewedModules:renewedModules});this.app.dismissErrors();}_context.next=20;break;case 17:_context.prev=17;_context.t0=_context"catch";if(((_module$hot3=module.hot)===null||_module$hot3===void 0?void 0:_module$hot3.status())==='fail'||((_module$hot4=module.hot)===null||_module$hot4===void 0?void 0:_module$hot4.status())==='abort'){console.warn('[HMRClient] Cannot check for update - full reload needed');console.warn('[HMRClient]',_context.t0);this.app.reload();}else{console.warn('[HMRClient] Update check failed',{error:_context.t0});}case 20:_context.prev=20;this.app.LoadingView.hide();return _context.finish(20);case 23:case"end":return _context.stop();}}},null,this,[[0,17,20,23]],Promise);}}]);return HMRClient;}();if(true){var _require=webpack_require(/! ../../node_modules/react-native / "../../node_modules/react-native/index.js"),DevSettings=_require.DevSettings,Platform=_require.Platform;var LoadingView=webpack_require(/! ../../node_modules/react-native/Libraries/Utilities/LoadingView / "../../node_modules/react-native/Libraries/Utilities/LoadingView.ios.js");var reload=function reload(){return DevSettings.reload();};var dismissErrors=function dismissErrors(){if(Platform.OS==='ios'){var _NativeRedBox$dismiss;var NativeRedBox=webpack_require(/! ../../node_modules/react-native/Libraries/NativeModules/specs/NativeRedBox / "../../node_modules/react-native/Libraries/NativeModules/specs/NativeRedBox.js").default;NativeRedBox===null||NativeRedBox===void 0?void 0:(_NativeRedBox$dismiss=NativeRedBox.dismiss)===null||_NativeRedBox$dismiss===void 0?void 0:_NativeRedBox$dismiss.call(NativeRedBox);}else{var NativeExceptionsManager=webpack_require(/! ../../node_modules/react-native/Libraries/Core/NativeExceptionsManager / "../../node_modules/react-native/Libraries/Core/NativeExceptionsManager.js").default;NativeExceptionsManager===null||NativeExceptionsManager===void 0?void 0:NativeExceptionsManager.dismissRedbox();}var LogBoxData=webpack_require(/! ../../node_modules/react-native/Libraries/LogBox/Data/LogBoxData */ "../../node_modules/react-native/Libraries/LogBox/Data/LogBoxData.js");LogBoxData.clear();};new HMRClient({reload:reload,dismissErrors:dismissErrors,LoadingView:LoadingView});}

Can you check if you have more than 1 Webpack dependencies in node_modules:
yarn why webpack in root or npm ls webpack in each package

Your Webpack config is inside react-native-container or somewhere else?

Hey, actually in two places. Inside react-native-container and app package. But looks like, the one in app package is being actively being used at the moment.

Thanks for all the investigation @zamotany . I could try but these code related to react-native-container is not available in public repositories. It looks like the architecture in wix though.
https://github.com/wix-incubator/react-native-wix-engine
BTW, I have webpack.config.js in app package which is just a javascript package which doesn't have android or ios folder. react-native-container provides pre-built binaries for app package. Mentioning because this might trigger something to someone. :)
Also, I am getting similar behaviour as op in android. If you have simpler repository to reproduce this, can you provide one ? @cstranex

@zamotany
So, the reason is still unknown why process.env.__PUBLIC_PORT__ is undefined inside WebpackHMRClient.js but if I set the port number to be constant with getPort({ port: 1234}) and use this port value in HMRClient then somehow hot reloading is working (still slow because, rebuilding is also happening).
Questions for the workaround:

What was the reason behind choosing port randomly ?
Could there be any other way to share the port to other files more reliably instead of env? Not that I am saying process.env is not relaible. (I don't have much idea on how it works.)

Because I don't know what ports are free or not and how many ports we will need. You can have more then 2 platforms.
It should be possible to add BannerPlugin with e.g: const __PUBLIC_PORT__ = ${devServer.port}; and change WebpackHMRClient.js to use __PUBLIC_PORT__ instead of process.env.__PUBLIC_PORT__

Actually, this is working with DefinePlugin if we are not using process.env. So, BannerPlugin is not needed.
      __PUBLIC_PORT__: devServer.port,
    }),

I can send a PR by replacing the usage of process.env.__PUBLIC_PORT__ with __PUBLIC_PORT__ if you want.
However, the hot reload is slow for me probably because of the size of the project but it takes almost 10 seconds to see the changes. This is probably a different issue anyway.

Yeah, if you could send a PR, that would be awesome.
As for the speed of hot reloading, there's little we can do, since it's a Webpack thing.

Done!


[Feature] Add option to hide 500 error details

#42

[x] Added setting HIDE_500_ERROR_DETAILS and set it to False by default to ensure backward compatibility
[x] Added test for the same
[x] Changed the "Internal server error." to "Unhandled server error."  in tests to avoid conflict between the message from hide_500_error_details

@ghazi-git Any updates on this ?

Actually, I don't think this feature should be added to the package since it can be implemented easily using a custom exception formatter as shown in the linked issue.
One of the main goals of this package is making drf exception handler easier to customize giving users finer control over the error response. That way, they can hide only 500 errors (like what you did), or all 5xx (like what the linked issue author wanted), or even specific 5xx errors.


docs(faq): add faq about usage of index

#143

@homu r+

:pushpin: Commit b8efea6 has been approved by azu

:zap: Test exempted - status


IsTxSafeForMining should not fail if ChainLocks are enabled but not enforced

This should not affect live networks because ChainLocks are enforced already but technically speaking it's a bug. You can reproduce it in tests if you enable spork19 before dip8 is activated.

It'd be nice if you implemented a regression test


LinkedList

Please assign me this

Please assign me this

I would love to contribute . Please assign this to me

The pull request has been sent.

@sayandas722 Why don't you merge the pull request?


az extension add --name aks-preview still fails with checksum error

As of January 12, 2020, at 11:30 pm KST, the error that occurred before still continues to appear. #37826
$ az extension add --name aks-preview
The checksum of the extension does not match the expected value. Use --debug for more information.

$ az version
This command is in preview. It may be changed/removed in a future release.
{
  "azure-cli": "2.0.79",
  "azure-cli-command-modules-nspkg": "2.0.3",
  "azure-cli-core": "2.0.79",
  "azure-cli-nspkg": "3.0.4",
  "azure-cli-telemetry": "1.0.4",
  "extensions": {}
}

Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

ID: 6de70aec-9ebe-5655-6657-5c171de374b1
Version Independent ID: c9eb35c8-8703-511b-987b-e2a441be2e47
Content: Preview - Create a Windows Server container on an Azure Kubernetes Service (AKS) cluster
Content Source: articles/aks/windows-container-cli.md
Service: container-service
GitHub Login: @mlearned
Microsoft Alias: mlearned

Same issue here on a hosted ubuntu azure devops agent:
azure-cli                         2.0.77 *

command-modules-nspkg              2.0.3
core                              2.0.77 *
nspkg                              3.0.4
telemetry                          1.0.4

Added the debug flag and gives an error on this:
ERROR: cli.azure.cli.core.util : The checksum of the extension does not match the expected value.

Hi @rkttu Thanks for reaching out. We will review and update as appropriate.

@rkttu I just tried reproducing the issue both on Cloud Shell and my local PC, however I am not able to reproduce the issue. Can you try once again and check if it is intermittent issue. I am looping product team on this issue for visibility.
@bramvdklinkenberg Can you try to upgrade the cli to latest version and give it try and see if you it works.

@MicrosoftDocs/aks-pm for awareness

@VikasPullagura-MSFT I will then have to upgrade the cli on the hosted build agent every time we run a job on a hosted agent. Will try that upcoming weekend, we only use the hosted agent to rebuild/redeploy our own AKS cluster with vsts build agents.

@VikasPullagura-MSFT The issue was gone when I tried to download again about three or four hours ago today. I know that this feature is not ready for production, but I think the download feature should work at any time.
Also, because it has occurred before, and it seems like a regression problem. It would be appreciated if you can detect and fix it first with monitoring activity.

@rkttu Thanks for confirming it is working for you. As per the Feedback, I am following up with Product team on this.

@MicrosoftDocs/aks-pm Can you check and add your comments

@zikalino do you know of any cases where extension checksums can diverge? It seems this is a transient issue occurring now and then that sometimes resolves on its own. It looks like CLI based logic to match the checksums in general for any extension installed, have you seen this occur for other services?

@rkttu Hope this issue is resolved now.
We will now close this issue. If there are further questions regarding this, please tag me in a comment. I will reopen it and we will continue the discussion.


Update README.md

fixed documentation for execCreate(...)

Thanks. Fixed here https://github.com/spotify/docker-client/commit/fcf31c871796a280ed19d2a0b473850be0add20c


Provide clarity on what the application is actually doing for the general public

The translatefgo app modifies the FGO application's resources. Even if it's not modifying the APK directly, it can still be considered as a modification of the application in some cases.
Can you put in additional details on how the application works (reading the FGO resource folder and replacing the files with the translated versions), so people using this app will be aware of the risks that they're getting into when using this app?

It does not modify executable code (which is the term "Application"). The Terms of Service has separate clauses for "Game data" including text, and does not forbid modification.
Even if it did, the game has no detection, it can't even detect hacked APKs, so there's nothing to worry about. The game used to be able to detect certain things such as root, emulators, modified apks, and sent it as part of the user login process, but this was removed with the engine update last June.
I would not release this application to the public if I was not 100% convinced it was safe.

Thanks! I was mostly concerned on people installing the app without being aware of what it specifically does.
We'll never know when DW will change stances on stuff like these, all they need is to put in a hash check on the resource files and everyone with modified resources may get screwed.

A hash check would also be tripped up by corrupted files, so it's not reliable. Either way if an update is introduced (I check every update) specifically to target this app, I will take the appropriate action.


Add spot instance requests to ec2 driver

Rancher versions:
rancher/server: 2.0
rancher/agent:
Docker-machine supports requesting spot instances with --amazonec2-request-spot-instance and --amazonec2-spot-price
We should add the option for people to request spot instances when provisioning via Rancher server.

Version - 2.0 master 4/10
Verified fixed


FuturesUnordered + HashMap?

I would like to have something like FuturesUnordered but where the collection behaves more like a HashMap (so that I can easily look up a future by its key instead of using .iter().find() etc). Has this been considered and if so, is there any reason this doesn't exist?
I guess there is a good reason why the following also doesn't exist, but it would be awesome if somehow FuturesOrdered and FutureUnordered could have been traits that were automatically implemented for any collection where the stored type implements Future.

I think it's a good idea to add something like a map.
In particular, there is currently no way to remove a specific future from the FuturesUnordered.

I'd think one could obtain that kind of behaviour with tokio's StreamMap, but of course might not hurt to have a structure more geared towards Futures as compared to Streams.

Would it be better to modify FuturesUnordered or add a new FutureMap type? The latter would probably be much easier.

The latter would probably be much easier.

Yeah. I would prefer the latter.

I went ahead and wrote a library based on FuturesUnordered that does exactly this: https://github.com/StoicDeveloper/mapped_futures

Here is the crate that covers this issue: https://crates.io/crates/mapped_futures

@StoicDeveloper what was the motivation for making a separate crate instead of opening a PR, here?

@StoicDeveloper what was the motivation for making a separate crate instead of opening a PR, here?

Honestly, it had not occurred to me to do so. I haven't really contributed to open source projects before. Mostly, I wanted to start using the feature immediately, whereas opening a PR would involve more discussion and require approval by the owners of this repo, though of course that would be a very good thing for verifying the soundness of my unsafe changes. I think my task next will be to do just that.

We had a similar need with the added requirements of bounding the Futures and Streams in their execution time and also capping the size of how many are allowed to execute at any one time.
In case it is of interest, the code is here: https://github.com/libp2p/rust-libp2p/tree/master/misc/futures-bounded/src.


Add tests for flatMapValues/mapValues/etc...

Memory did not support it, so clearly we are not exercising it.
See note in: #638

There actually are tests:
https://github.com/twitter/summingbird/blob/develop/summingbird-core-test/src/main/scala/com/twitter/summingbird/TestGraphs.scala#L194
We are just not running those tests in the Memory/ConcurrentMemory platforms.
They may not work correctly because I guess there is a hidden assumption that there is no pipelining for the logic of that to be correct (for each key, you have to push it all the way through before you can process the next value for that key). As such, we need to detect those nodes and combine them into one operation to handle it correctly (something storm still does not do, as of this writing).


[Doc-enhance][updated-doc][1827919]

Added function details in Authentication namespace.

Docs Build status updates of commit f88ac53:
:white_check_mark: Validation status: passed

File
Status
Preview URL
Details

msteams-platform/tabs/how-to/using-teams-client-sdk.md
:white_check_mark:Succeeded
View

For more details, please refer to the build report.
Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report.
For any questions, please:Try searching the docs.microsoft.com contributor guidesPost your question in the Docs support channel

Docs Build status updates of commit c4affbc:
:white_check_mark: Validation status: passed

File
Status
Preview URL
Details

msteams-platform/tabs/how-to/using-teams-client-sdk.md
:white_check_mark:Succeeded
View

For more details, please refer to the build report.
Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report.
For any questions, please:Try searching the docs.microsoft.com contributor guidesPost your question in the Docs support channel


Just made a port in Go!

Link: https://github.com/annihilatorrrr/gotinystatus
Maybe useful :)

might as well do it in pure bash

Cool, that's useful! :)I’ll add it to the README.
Bash/shell script should useful as well.