Skip to content

RFC: Casting From by as_cast #3413

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed

Conversation

VitWW
Copy link

@VitWW VitWW commented Apr 12, 2023

This RFC proposes new abilities for as(as_cast) casting From Trait implementations.

Like this:

let foo = "my string" as String;

let baz = 12u32 as Ipv4Addr;

let bar = 12 as Rc<i32>;

Rendered

This proposal was inspired by "smart constructors" discussion in #3408 RFC.

@CraftSpider
Copy link

Rust has, generally, been trying to move away from as casting to dedicated methods. as has worse precedence as well as being highly confusable (its behavior on integers couldn't be changed, so it wouldn't perform an infallible cast on them).

@VitWW
Copy link
Author

VitWW commented Apr 12, 2023

@CraftSpider
(1) First, as_cast is already exist in Rust and it is irremovable for backward compatibility. Why do not make it useful?
(2) Second, nothing forbids to optimize ineffective casting to effective ones
(3) Third, bad precedence design could be softened by adding another good-design precedence cousins to as.

@ehuss ehuss added the T-lang Relevant to the language team, which will review and decide on the RFC. label Apr 12, 2023
@CraftSpider
Copy link

First: Because we can soft-deprecate it instead, make less code use it going forwards, and even if we can't remove it, we can replace it with better alternatives. It already is useful in exactly one main scenario - dynamic unsizing - and we don't need to make it more confusing by adding more hard-to-teach behavior. And thinking of that, that's another issue - as Box<dyn Foo> would need to still not go through From, but use unsizing, which would mean even generic types could behave differently based on the exact type involved.

Second: This isn't about optimization, this is about behavior. We can't change behavior just because it's inconvenient, that's part of our version promises.

Third: If we want to add another as like operator with better rules, we could do that. But that would be its own entirely different change, that if anything is a point in favor of not changing as, for the reasons mentioned in the first point.

@VitWW
Copy link
Author

VitWW commented Apr 12, 2023

@CraftSpider
Sure, I agree, default behavior remains, I propose to add additional sugaring for another cases:

// default
a as T where T == T_as_castable   ~   a as T; // nothing changes

// new
a as T    ~   T::from(a);
(a : U) as T<U>  ~  T::from(a);

a as Result<T,_>   ~   T::try_from(a);
(a : U) as Result<T<U>,_>   ~   T::try_from(a);

@clarfonthey
Copy link

IMHO, as is an unfortunate construct that exists in the language because we don't have a good way of representing all of its functionality as a trait. Pretty much every usage of as would be better suited to a more explicit method, and moving to bundle more of this functionality into as is backwards IMHO.

As others have mentioned, dynamic unsizing is just one of the cases where as is necessary right now, as we've already implemented From for all the various primitives. It's also necessary in const context until we have full support for keyword generics in some form, which is probably the bigger use case at the moment.

While mathematical operations make sense to have syntax sugar since they're so much more easily readable that way (I much prefer x * x + y * y over x.times(x).plus(y.times(y)) or add(mul(x, x), mul(y, y))) the same cannot be applied to conversions, since:

  • There's no sigil for conversion in common use
  • A lot of the conversion can be baked into function arguments with generics
  • And, most importantly, from and into are only four characters each, with the worst offenders requiring you only to specify a type name (usually without generics), two colons, and the word from.

@Aloso
Copy link

Aloso commented Apr 13, 2023

I've been meaning to write a RFC that supersedes as for numbers with explicit traits, with the goal to deprecate as for numbers in a future edition.

@VitWW
Copy link
Author

VitWW commented Apr 13, 2023

@Aloso Wow!
By the way, your possible proposal DO NOT contradict my proposal.
It would be nice to insert all default as_cast behavior into From Trait and switch every as_cast for implementation From/TryFrom traits!
Your idea is to unify behavior, my idea is to unify behavior and both our ideas together also are to unify behavior.

@VitWW VitWW changed the title Casting From by as_cast RFC: Casting From by as_cast Apr 13, 2023
@asquared31415
Copy link

On the topic of deprecating as casts in favor of other more explicit methods, I proposed rust-lang/libs-team#204 as a library solution to perform every operation that as can perform on integer types, with compile time checks that the behavior is possible.

@VitWW
Copy link
Author

VitWW commented Apr 14, 2023

@asquared31415 Thanks, I added your proposal to alternatives

@oli-obk
Copy link
Contributor

oli-obk commented May 16, 2023

It has been said before, but I'll repeat it at this closing comment: as is already too overloaded and problematic around its implicit truncation and unclear provenance semantics. We're trying to build explicit replacements instead of having a Swiss army knife that has a footgun builtin. I appreciate that your proposal desugars to regular trait method calls, but for now, this is not an RFC that can be merged. I recommend you chat with folk in the lang team zulip to figure out if there is some part of this that can be worked on.

Thanks everyone for the discussion. I will close this RFC now to reduce the load on the sync lang team meetings and leave it to async zulip discussions to determine the future of as

@oli-obk oli-obk closed this May 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants