Stream: t-lang

Topic: Edition Request: let `1` be a float literal


Lokathor (May 04 2020 at 20:27, on Zulip):

What I miss the most from Haskell is honestly just that you can just write 1 in a floating point position and it'll give you 1.0 like you wanted instead of giving you a compile error that says "I know what you meant but you have to put a dot on that number manually".

Sebastian Malton (May 04 2020 at 20:53, on Zulip):

That would be nice, namely let x:f32 = 1; would then work.

scottmcm (May 05 2020 at 01:25, on Zulip):

Potential risk: That would mean that 1 would be both {integer} and {float}; I'm not sure how that might impact inference.

Lokathor (May 05 2020 at 06:57, on Zulip):

I'd propose that, rather than immediately being "integer or float" the whole time, it's integer until an integer inference would fail, then at that moment the inference tries to continue as float until either that would also fail or things work out.

Though that doesn't fully mitigate the problem. It does make for an easy to explain rule at least.

Hanna Kruppe (May 05 2020 at 07:38, on Zulip):

Inference fallbacks are already fiddly, adding more layers to it seems scary. What if we just said the {integer} pseudo-type can be constrained to any concrete float or int type, instead of just any concrete int type? Is there any situation where "this is some float or int type, don't know which one yet" leads to ambiguities but "this is some int type, don't know which one yet" doesn't?

kennytm (May 05 2020 at 09:13, on Zulip):

Is there any situation where "this is some float or int type, don't know which one yet" leads to ambiguities but "this is some int type, don't know which one yet" doesn't?

trait Tr {
    fn foo(self) {}
}
impl Tr for u32 {}
impl Tr for f32 {}
fn main() {
    5.foo(); // inference breakage if `{float}` has same priority as `{int}`
}
Hanna Kruppe (May 05 2020 at 09:21, on Zulip):

Okay, good point. Next question: is this something that is at all common in the real world? I recall a similar problem exists with allowing slice/array indexing with integer types other than usize, but I can't think of any cases where one integer type and some float types are an option. Much more common are "several/all int types" and "all numeric types (ints and floats)".

Josh Triplett (May 05 2020 at 14:35, on Zulip):

There's also that at least some users may expect that 0 or 1 is an integer and 0.0 or 1.0 is a float.

Josh Triplett (May 05 2020 at 14:36, on Zulip):

There's the standard tension between wanting the compiler to DWIM and wanting types kept strictly separated.

nikomatsakis (May 05 2020 at 14:37, on Zulip):

well, in this instance, the type would be clearly assigned and not "mixable"

nikomatsakis (May 05 2020 at 14:37, on Zulip):

I think that whenever this topic comes up, it behooves us to be very clear about the obstacles we're wary of

nikomatsakis (May 05 2020 at 14:38, on Zulip):

"this topic" here means specifically "the tension about DWIM vs being strict"

Lokathor (May 05 2020 at 16:24, on Zulip):

The common case that I encounter is that you're doing an operation, x+=1 for example, and x has a type already and so there's no question as to what type 1 must be for the expression to become valid. Any type but a particular type is a compilation error.

Josh Triplett (May 05 2020 at 16:45, on Zulip):

Right. The question then becomes, is the desired behavior "compilation error". For some users it may be.

nikomatsakis (May 05 2020 at 16:58, on Zulip):

note though that we could plausibly solve that problem through a Add impl, though maybe not

nikomatsakis (May 05 2020 at 16:58, on Zulip):

we have some limitations to the set of impls we can add

Lokathor (May 05 2020 at 17:01, on Zulip):

@Josh: Sure, and that's perhaps a reasonable thing to want. I was more responding to Hanna's question of "what are the real world examples of this?"

If people do want to be extra hardline about things perhaps converting an int literal into being a float literal could also fire off an allow-by-default lint that a project could change to deny by default.

The Haskell community does get along just fine with 1 + 5.4 evaluating to 6.4 (also C and Python and basically the whole rest of the world, but Haskell specifically has a similar mentality to Rust of "absolute minimal implicit conversions")

@Niko: Well also: fields in a struct when you're initializing with a literal, or function args when you pass a literal to a function.

RalfJ (May 06 2020 at 20:16, on Zulip):

re: "keep strictly separated", I think my main concern here would be precision loss

RalfJ (May 06 2020 at 20:16, on Zulip):

so even if 1 becomes "float or int", I think integers that cannot be precisely represented in the target float point must not be turned into floats implicitly

RalfJ (May 06 2020 at 20:16, on Zulip):

such loss of information should at least be explicitly acknowledged by appending .0

RalfJ (May 06 2020 at 20:18, on Zulip):

if we adopt that, since we are already accepting that 5 might considered an element of i32 or u8, I dont see any harm in also freely considering it an element of f32 -- I dont think signed 32-bit and unsigned 8-bit integers are conceptually that much closer to each other than to f32 to justify the distinction. people that want strict type separation should already be writing 5i32 for extra explicitness.

Lokathor (May 07 2020 at 04:00, on Zulip):

Right, i suppose i was also assuming that the "overflowing literals" lint would apply here, the same as you can't use 0xFFF in a u8 position.

kennytm (May 07 2020 at 05:44, on Zulip):

speaking of which, if 123 can be considered an f32, can 0xff / 0o777 / 0b1010 be also be considered an f32

Lokathor (May 07 2020 at 06:29, on Zulip):

oof that's a big can of worms.

Sebastian Malton (May 07 2020 at 13:30, on Zulip):

I would say not since the reason for using binary, or octal, or hex is generally because you care about specific bit locations

Lokathor (May 07 2020 at 15:32, on Zulip):

Advanced float math actually does use hex float literals because "advanced float math" means "very carefully weave the line between what CPUs do and how IEEE works".

Lokathor (May 07 2020 at 15:33, on Zulip):

That said if we didn't have hex float literals in the "first round" of this change, or even ever, it'd be fine. You can use the "const union hack" in that rare case.

Hanna Kruppe (May 07 2020 at 15:37, on Zulip):

It sounds like you're referring to e.g. specifying the smallest subnormal as 0x0000_0001 (which you can express today with fN::from_bits), but extrapolating the "1 as float literal" feature to integer hexadecimal literals would instead suggest e.g. 0xff == 255.0 (which you can express today with as casts).

Hanna Kruppe (May 07 2020 at 15:38, on Zulip):

I assumed everyone was referring to the latter. Making let x: f32 = 0xff; do something different from let x: f32 = 255; (if both work) seems very confusing.

kennytm (May 07 2020 at 15:51, on Zulip):

one issue:

let a: f32 = 123;       // proposed for 2021.
let b: f32 = 123_f32;   // works in 2015.
let c: f32 = 0xff;      // proposed for 2021.
let d: f32 = 0xff_f32;  // errrr....
Lokathor (May 07 2020 at 16:00, on Zulip):

ohno.jpg

Sebastian Malton (May 07 2020 at 16:05, on Zulip):

I would say that it would be better to do:

let a: f32 = 123;       // proposed for 2021.
let b: f32 = 123_f32;   // works in 2015.
let c: f32 = 0xff;      // errors now and in 2021
let d: f32 = 0xff_f32;  // ^^^
Sebastian Malton (May 07 2020 at 16:25, on Zulip):

Would people think that we have had enough discussion to write up an RFC.

I see the following points:

  1. Allow for base 10 numeric literals to be interpreted by the compiler as {float} if interpreting it as {integer} results in a type error. If both result in a type error, only report the {integer} type error.
  2. Implement an allow-by-default lint for the above feature so that project that do not want to have this can disable it.
Lokathor (May 07 2020 at 16:26, on Zulip):

I agree with those points but I already am looking after about 1.5 RFCs so I wouldn't want to take on another right now.

Sebastian Malton (May 07 2020 at 16:28, on Zulip):

I would be fine doing the writeup

Lokathor (May 07 2020 at 16:29, on Zulip):

There's a lang meeting later today and I'm not on the lang team but I can point them in the direction of this topic for them to check out when they get the time.

kennytm (May 07 2020 at 16:29, on Zulip):
trait X: Sized {
    fn g(self);
}
impl X for f32 {
    fn g(self) {
        println!("f32");
    }
}
impl X for f64 {
    fn g(self) {
        println!("f64");
    }
}

fn main() {
    1.0.g(); // currently prints "f64"
    1.g();   // type error or print "f64"?
}
Josh Triplett (May 07 2020 at 17:20, on Zulip):

@Lokathor I think I'm still trying to wrap my head around the use case for this. The goal here is to...avoid typing .0?

Josh Triplett (May 07 2020 at 17:21, on Zulip):

And in exchange for that, we get potential new inference issues and what seems like a lot of complexity?

Josh Triplett (May 07 2020 at 17:21, on Zulip):

What am I missing?

Josh Triplett (May 07 2020 at 17:22, on Zulip):

(That's leaving aside whether we want the compiler to accept 1 as a float, which I personally would prefer it didn't, but for the purposes of the questions above I'm ignoring that for the moment.)

Sebastian Malton (May 07 2020 at 17:36, on Zulip):

@kennytm Since it is only implemented for f32 and f64 the behaviour between 1.0.g() and 1.g() should be the same

kennytm (May 07 2020 at 17:37, on Zulip):

so there would be 4 levels of inference: i32 > {integer} > f64 > {float}

Sebastian Malton (May 07 2020 at 17:46, on Zulip):

I don't know, in edition 2015 and 2018 are there already two for 1 and a different two for 1.0?

kennytm (May 07 2020 at 17:48, on Zulip):

in 2018 for 1 it is i32 > {integer} and for 1.0 it is f64 > {float}

kennytm (May 07 2020 at 17:49, on Zulip):

if 1.g() is compilation error, we get 3 levels for 2021 i32 > {integer} > {float}

Sebastian Malton (May 07 2020 at 19:37, on Zulip):

Well I think that it would be much more confusing if 1.g() was a compilation error.

cuviper (May 08 2020 at 01:24, on Zulip):

@Josh Triplett one time I've wanted this is when implementing something by macro for both integers and floats -- then it's annoying that I can't write a literal that works with both.

cuviper (May 08 2020 at 01:24, on Zulip):

not a big deal to work around though

Lokathor (May 08 2020 at 03:23, on Zulip):

Right, it's not the worst thing, but nearly every other major language lets you do it.

Josh Triplett (May 08 2020 at 03:27, on Zulip):

Other weakly typed languages definitely. Do other strongly typed languages?

Lokathor (May 08 2020 at 03:37, on Zulip):

Yes, Haskell does.

Lokathor (May 08 2020 at 03:42, on Zulip):

In Haskell, any integer literal n is effectively the expression fromInteger n and has the type Num a => a

or in approximate Rust terms, n: impl Num

Lokathor (May 08 2020 at 03:43, on Zulip):

and you can further constrain a particular literal of course, making it Int32 or Float or whatever specific number type

Josh Triplett (May 08 2020 at 04:35, on Zulip):

I'm aware of what Haskell does. For the benefit of something like the macro case, we could easily add something like fromInteger. The question is whether we should do so by default.

kennytm (May 08 2020 at 06:18, on Zulip):

Other weakly typed languages definitely. Do other strongly typed languages?

perhaps this question is more about what languages do not allow 1 as float.

Swift, Go, C#, Scala all can accept the dotless literal as float, not to mention C++ ("weak"), Python, TypeScript (no clear distinction between int and float), Haskell (see above).

Hanna Kruppe (May 08 2020 at 07:31, on Zulip):

FWIW, at least C# and Python don't really "allow 1 as float" but rather have implicit conversions from ints to floats that affect all runtime values (not specifically literals). Well, Python doesn't have "implicit conversions" per se, but essentially all operators and functions that expect floats will gladly accept anything with a __float__ method.

kennytm (May 08 2020 at 07:36, on Zulip):

ok that means C# is "weak".

RalfJ (May 08 2020 at 08:03, on Zulip):

Lokathor said:

Advanced float math actually does use hex float literals because "advanced float math" means "very carefully weave the line between what CPUs do and how IEEE works".

there's also binary float literals to directly control the float bits which rust unfortunately does not support (but there's a crate for it)

nikomatsakis (May 08 2020 at 10:37, on Zulip):

A bit of history:

When I first started working on Rust, the expression 22 always had type isize (then called int). You had to explicitly write 22_u32. When we changed it to do inference, there was vociferous resistance, because things had to be explicit. We settled on inference and a lint for 'oversized' literals that don't fit the type they are ultimately inferred to be. (I actually.. am not entirely sure why a lint and not a hard error, I think there was some use case to sometimes abuse 2's complement notation or something..?)

nikomatsakis (May 08 2020 at 10:38, on Zulip):

In particular, @Josh Triplett, I want to push back on the notion that allowing 22 to be inferred to be 22.0 is truly "loosely typed". I think you can say that C's implicit upcasting of types and so forth is definitely loose, but inferring a fixed float type seems much different.

nikomatsakis (May 08 2020 at 10:44, on Zulip):

I guess it'd be good to list out specific errors you can get that can't be addressed through a lint that checks for extreme floating point issues (e.g., a number that can't be represented)

Bastian Kauschke (May 08 2020 at 11:35, on Zulip):

I guess it'd be good to list out specific errors you can get that can't be addressed through a lint that checks for extreme floating point issues (e.g., a number that can't be represented)

Things like this feel both undesirable and inevitable if we allow float literals afaict. (if somewhat artificial tbh)

trait Foo {}
impl Foo for f32 {}
fn consume(_: impl Foo) {}
fn main() {
    consume(20_000_000 + 1); // When using f32, this calls consume with 20_000_000
}
nikomatsakis (May 08 2020 at 11:43, on Zulip):

I'm not sure why that feels undesirable

nikomatsakis (May 08 2020 at 11:43, on Zulip):

it's the arithmetic?

nikomatsakis (May 08 2020 at 11:44, on Zulip):

oh, I see the comment

nikomatsakis (May 08 2020 at 11:44, on Zulip):

ok, that's helpful :)

nikomatsakis (May 08 2020 at 11:44, on Zulip):

although.. hmm.. I'm not sure ultimately it's any more surprising than 20_000_000.0 + 1.0

nikomatsakis (May 08 2020 at 11:45, on Zulip):

or 255 + 1 where you have impl Foo for u8

Bastian Kauschke (May 08 2020 at 11:57, on Zulip):

or 255 + 1 where you have impl Foo for u8

That's a good point. I still think it's worse for floats, as integer overflow is far more noticeable :sweat_smile:
I also really dislike floats in general, so I am somewhat biased here.

Bastian Kauschke (May 08 2020 at 12:02, on Zulip):

^ A worse example is consume(20_000_000 + 1 + 1). Even if consume should take a f32 here, there is an actual difference between (20_000_000 + 1 + 1) as f32 and 20_000_000.0 + 1.0 + 1.0.

nikomatsakis (May 08 2020 at 12:10, on Zulip):

Yeah, I definitely think there's an argument to be made for "the surprise factor of floats is so high that they are qualitatively different than integers" (and I think these examples are a good way to make it). That, combined with "floats are needed an order of magnitude less often" is perhaps enough to tilt the balance away from the surprise factor of "wait? there's a difference between 1 and 1.0?" (I've definitely sometimes spent time scratching my head over that...even though I ought to know better.)

nikomatsakis (May 08 2020 at 15:19, on Zulip):

Josh Triplett said:

Lokathor I think I'm still trying to wrap my head around the use case for this. The goal here is to...avoid typing .0?

Just to respond to this, too, I think it's not fair to characterize as "avoid typing". The goal is to make numbers in Rust behave more like numbers in the real world, I imagine, and to avoid the "ergonomic hit" of compilation cycles driven just by "oh yeah gotta add a .0 to please the compiler". Those cycles may be worthwhile, but I think the burden of proof should fall on us to show it's worth it to force you to change your code, because it prevents bugs (or is easier to understand or can be implemented or whatever), and not the reverse.

Josh Triplett (May 08 2020 at 17:29, on Zulip):

@nikomatsakis I appreciate the explanation in those terms. To clarify something, that was intended as a genuine question. I didn't understand the use case for this at all, and my question was intended as "I must be missing something here".

Josh Triplett (May 08 2020 at 17:30, on Zulip):

Separate from that, I do think your phrasing of "the surprise factor of floats is so high that they are qualitatively different than integers" is a much better way of putting my argument that I don't think we should let one token infer to either int or float, without stating that.

Josh Triplett (May 08 2020 at 17:31, on Zulip):

I do think, for uses such as macros, we may need a way of writing "1 or 1.0, whichever the expression needs". But I'm inclined to make that 1.to_num() or 1.into(), not just 1.

Josh Triplett (May 08 2020 at 17:34, on Zulip):

Having just written a pile of code that uses as in many places (far more than I'd like), I think I can also further elaborate in response to the notion of "gotta add a .0 to please the compiler". The question is, how often is the response "just add .0", and how often is the response going to be "yikes, it's a float? I need to think about this harder". Because with the mixing of integer types, it turns out that when I had a u64 and needed a u32, the answer was almost never "gotta add as u32 to please the compiler", but rather "hrm, how do I handle this, let me work backwards and figure out if the original thing should have been a u32 to begin with".

Lokathor (May 08 2020 at 18:06, on Zulip):

Well, I started this topic when I'd just written 200+ doc tests with math in them that, on a test by test basis, used floating point and integer types of all sizes. And it really started to show the fiddly weaknesses involved (eg: from often also has very poor errors). And now I'm up to 409 doc tests any my position has not changed at all.

To answer your most recent question there:

I am sympathetic to the "20 million + 1" problem. However, that's also mostly a slightly separate problem with how float literals work. This example here:

fn main() {
    println!("{}", 20_000_001.0_f32);
}

Will print 20000000 with no warning that your literal can't be exactly represented within f32.

So my own opinion is that 20_000_000+1 should fold to 20_000_001: {integer} and then as the next step turning that integer to an f32 should fire off a warning that the value can't be exactly represented within the f32 type. However I also expect that such a system could then lead to some other edge case.

oli (May 08 2020 at 18:09, on Zulip):

we can detect at const prop time that 20_000_000.0_f32 + 1.0 does not do anything

Josh Triplett (May 08 2020 at 18:11, on Zulip):

@Lokathor I do think there's value in warning when literal values can't be represented precisely.

Lokathor (May 08 2020 at 18:11, on Zulip):

(deleted)

Hanna Kruppe (May 08 2020 at 18:12, on Zulip):

@oli but this kind of thing can happen in "ordinary" computations that happen to become elegible for const prop, so warning about it is on shaky ground / likely to give false positives

oli (May 08 2020 at 18:14, on Zulip):

indeed, that is a problem, but the above example seems awefully rare, I would expect this to only be an issue when more complexity is involved, as it isn't obvious to the user what's going on

Lokathor (May 08 2020 at 18:15, on Zulip):

does float math even run at const time? I thought it did not and would never because of the dreaded non-determinism

Josh Triplett (May 08 2020 at 18:17, on Zulip):

@Lokathor GCC, at least, runs float math at compile time, and has some very careful libraries that exist to do so deterministically.

Lokathor (May 08 2020 at 18:19, on Zulip):

To be clear I would love to have floats at const times and even to emulate float intrinsics at compile time, and so on.

I was just previously told by various folks that it is (loosely) "probably never gonna happen, because it's non-determinism"

Hanna Kruppe (May 08 2020 at 18:23, on Zulip):

idk what const prop does or should do, but for better or worse, float arithmetic in constant expressions is supported.

oli (May 08 2020 at 18:23, on Zulip):

since https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=5eb83b14d13b63470af9336e9b2ae459 compiles, we can be sure that it works at const eval time. We may not be doing it at const prop time, but we most definitely could

Lokathor (May 08 2020 at 18:24, on Zulip):

It's supported in a const declaration expression but not a const fn body.

Lokathor (May 08 2020 at 18:26, on Zulip):

well, stable that is.

anyway that's maybe a little off topic for this particular thread.

nikomatsakis (May 08 2020 at 18:35, on Zulip):

By the way, this thread is making me think.

nikomatsakis (May 08 2020 at 18:35, on Zulip):

I want to beef up the lang-team website to have a lot more info

nikomatsakis (May 08 2020 at 18:35, on Zulip):

including design notes and thoughts that collect over time about particular questions

nikomatsakis (May 08 2020 at 18:35, on Zulip):

I was thinking that after major threads like this that occur on Zulip, we should make a point to write-up conclusions

nikomatsakis (May 08 2020 at 18:35, on Zulip):

I'm going to try and do just a bit of that for this thread

nikomatsakis (May 08 2020 at 18:36, on Zulip):

to show what I mean, but I think it should be standard practice -- in fact, i'm even getting grandiose ideas of trying to create a set of "wg-scribes" or something who generally have that role

nikomatsakis (May 08 2020 at 18:36, on Zulip):

but let's start small :)

nikomatsakis (May 08 2020 at 18:36, on Zulip):

I'm sick of having the same conversations over and over and rediscovering the same constraints :P

RalfJ (May 08 2020 at 18:42, on Zulip):

Josh Triplett said:

Lokathor GCC, at least, runs float math at compile time, and has some very careful libraries that exist to do so deterministically.

We use @eddyb 's Rust port of LLVM's libapfloat for this

RalfJ (May 08 2020 at 18:42, on Zulip):

so, I think basically the same as GCC

eddyb (May 08 2020 at 18:42, on Zulip):

well, the same as Clang, but yeah :P

RalfJ (May 08 2020 at 18:42, on Zulip):

I mean on the level of "careful lib for deterministic float math"

RalfJ (May 08 2020 at 18:43, on Zulip):

Miri-the-tool will use host float operations to fill in some gaps in libapfloat, but rustc itself will never do that

Bastian Kauschke (May 08 2020 at 18:43, on Zulip):

we can detect at const prop time that 20_000_000.0_f32 + 1.0 does not do anything

This is not always possible though :sweat_smile:

trait Foo<T> {
     fn use(&self, _: T) -> T;
}

fn test<T>(bar: &dyn T)
where
    T: Foo<f32>,
    T: Foo<i32>,
{
    consume(bar.use(20_000_000) + 1);
}
eddyb (May 08 2020 at 18:54, on Zulip):

@RalfJ @Josh Triplett @Lokathor btw rustc_apfloat:

eddyb (May 08 2020 at 18:54, on Zulip):

AFAIK this effectively makes it "pure" :P

eddyb (May 08 2020 at 18:55, on Zulip):

might be able to start using const fn in it except for traits (Iterator is the worst I guess)

Hanna Kruppe (May 08 2020 at 18:56, on Zulip):

(don't copy what core::dec2flt does, it has arbitrary limitations and is much slower than it has to be)

eddyb (May 08 2020 at 18:57, on Zulip):

I strongly suspect rustc_apfloat is slower given how naive it is, but if I would do the stack thing, it would probably be behind a not(feature(alloc)) or something

Hanna Kruppe (May 08 2020 at 18:59, on Zulip):

Much of the slowness in the libcore impl is in the bignum operations, fwiw

eddyb (May 08 2020 at 19:03, on Zulip):

I didn't implement any of the APInt optimizations for e.g. division, except for short division (idk if they have it as a special case or what), which is when your divisor fits in whatever bigint unit ("limb") you're using, true for most of the common divisors

eddyb (May 08 2020 at 19:06, on Zulip):

and that was to fix a regression when we switched to rustc_apfloat :P

cuviper (May 08 2020 at 19:09, on Zulip):

@Josh Triplett on using something like 1.into(), you still need a type for that 1 -- u8 works into everything but i8

cuviper (May 08 2020 at 19:11, on Zulip):

1 as $num is the lazy macro solution

Josh Triplett (May 08 2020 at 19:12, on Zulip):

$num?

Josh Triplett (May 08 2020 at 19:13, on Zulip):

Is that a macro argument supplying the type?

nikomatsakis (May 08 2020 at 19:27, on Zulip):

OK folks

nikomatsakis (May 08 2020 at 19:27, on Zulip):

I created this PR that summarizes some key points and takeaways:

https://github.com/rust-lang/lang-team/pull/16

nikomatsakis (May 08 2020 at 19:28, on Zulip):

It is by no means exhaustive. I would love it if people who participated in this meeting went and suggested edits.

nikomatsakis (May 08 2020 at 19:28, on Zulip):

As I was saying, I think that -- eventually -- every substantial conversation that takes place here should conclude with a PR of this kind that updates and records the information :)

nikomatsakis (May 08 2020 at 19:28, on Zulip):

but let's just start with this one

Josh Triplett (May 08 2020 at 19:29, on Zulip):

Good summary, thank you.

Josh Triplett (May 08 2020 at 19:29, on Zulip):

That'll help the next time this comes up.

Josh Triplett (May 08 2020 at 19:29, on Zulip):

It doesn't have a conclusion, but then, neither did the discussion here.

nikomatsakis (May 08 2020 at 19:49, on Zulip):

Indeed, it wasn't meant to "conclude"

nikomatsakis (May 08 2020 at 20:12, on Zulip):

@Lokathor I was concerned I didn't capture the "pro" side very well btw :)

cuviper (May 08 2020 at 21:07, on Zulip):

@Josh Triplett yes I meant that like a macro argument $num:ty

simulacrum (May 08 2020 at 21:09, on Zulip):

hm you might even be able to get away with "5 as _" right?

Josh Triplett (May 08 2020 at 21:10, on Zulip):

/me stares.

Josh Triplett (May 08 2020 at 21:10, on Zulip):

/me stares harder.

Josh Triplett (May 08 2020 at 21:10, on Zulip):

/me is impressed with Rust type inference.

cuviper (May 08 2020 at 21:15, on Zulip):

@simulacrum as _ would probably work, but I usually do have the type at hand because I'm writing some impl XYZ for $num

simulacrum (May 08 2020 at 21:15, on Zulip):

sure, yes

Lokathor (May 08 2020 at 21:49, on Zulip):

@nikomatsakis I can comment on the PR later perhaps with more persuasive words. My ISP is dead right now and I was hoping it would be fixed around the top of the hour but it was not. Until then I'm stuck on just a phone.

nikomatsakis (May 08 2020 at 21:51, on Zulip):

@Lokathor ok -- I may also just land and you can open a follow-up PR

Lokathor (May 08 2020 at 21:52, on Zulip):

yeah no worries

kennytm (May 09 2020 at 06:49, on Zulip):

with 5 as _ you may end up with 5 as *const String if you can't control the $num :upside_down:

Last update: Oct 28 2020 at 17:00UTC