Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upGenerate builtin impls for `Clone` #43690
Conversation
rust-highfive
assigned
eddyb
Aug 5, 2017
This comment has been minimized.
This comment has been minimized.
|
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @eddyb (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
This comment has been minimized.
This comment has been minimized.
|
IMO it does need an RFC and I am against this specific implementation atm, although I am pleasantly surprised it's possible at all. There might be some value to moving all builtin auto-derives to MIR. |
This comment has been minimized.
This comment has been minimized.
|
What's your problem with the implementation? I think it's pretty clean. However, we are probably not going to merge this at least before @nikomatsakis returns from vacation next week. |
arielb1
reviewed
Aug 6, 2017
| @@ -143,6 +143,12 @@ fn resolve_associated_item<'a, 'tcx>( | |||
| substs: rcvr_substs | |||
| } | |||
| } | |||
| traits::VtableBuiltin(ref data) => { | |||
| Instance { | |||
| def: ty::InstanceDef::BuiltinShim(def_id, data.ty), | |||
This comment has been minimized.
This comment has been minimized.
arielb1
Aug 6, 2017
Contributor
You don't need to store ty anywhere - it is available as trait_ref.self_ty().
This comment has been minimized.
This comment has been minimized.
|
@arielb1 My problem is not how it's implemented, but using this method only for some |
This comment has been minimized.
This comment has been minimized.
|
Because that would mean the code is "tested" more? I'm not so sure on that - it e.g. means we'll have to re-implement error reporting on |
arielb1
reviewed
Aug 7, 2017
| DropGlue(DefId, Option<Ty<'tcx>>), | ||
|
|
||
| /// Builtin method implementation, e.g. `Clone::clone`. | ||
| BuiltinShim(DefId, Ty<'tcx>), |
This comment has been minimized.
This comment has been minimized.
arielb1
Aug 7, 2017
Contributor
Can't this be CloneShim? In other places I have a separate shim class for each trait.
This comment has been minimized.
This comment has been minimized.
arielb1
reviewed
Aug 7, 2017
| /// Build a `Clone::clone` shim for `recvr_ty`. Here, `def_id` is `Clone::clone`. | ||
| fn build_clone_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, | ||
| def_id: DefId, | ||
| rcvr_ty: ty::Ty<'tcx>) |
This comment has been minimized.
This comment has been minimized.
arielb1
Aug 7, 2017
Contributor
don't call this rcvr_ty - ty is fine. The receiver is the first argument of the method, which has type &Self (e.g. &[Vec<u32>; 2] if the impl is for <[Vec<u32>; 2] as Clone>. Also fix the comment.
arielb1
reviewed
Aug 7, 2017
| /// Build a `Clone::clone` shim for `recvr_ty`. Here, `def_id` is `Clone::clone`. | ||
| fn build_clone_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, | ||
| def_id: DefId, | ||
| rcvr_ty: ty::Ty<'tcx>) |
This comment has been minimized.
This comment has been minimized.
arielb1
Aug 7, 2017
Contributor
don't call this rcvr_ty - ty is fine. The receiver is the first argument of the method, which has type &Self (e.g. &[Vec<u32>; 2] if the impl is for <[Vec<u32>; 2] as Clone>. Also fix the comment above.
This comment has been minimized.
This comment has been minimized.
scalexm
Aug 7, 2017
Author
Member
Actually there are too many variables named ty appearing in the code, and I ended up confusing two of them (and having a wrong code generation), that's why I renamed it but I agree rcvr_ty is not ideal, I'll find something else.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
arielb1
reviewed
Aug 7, 2017
| rcvr_ty: ty::Ty<'tcx>) | ||
| -> Mir<'tcx> | ||
| { | ||
| let sig = tcx.fn_sig(def_id); |
This comment has been minimized.
This comment has been minimized.
arielb1
Aug 7, 2017
•
Contributor
Small note: this is a "fully generic" shim, so it knows the concrete receiver type. You could check if the source type is Copy and emit an "optimized" impl that just copies the result. This will speed up cloning [u8; 1048576] on unoptimized builds and is generally a good idea.
Also, as @eddyb says, it might be a smart idea to plumb #[derive(Clone)] impls through this to avoid implementing the logic twice and to potentially speed up compilation - maybe have #[derive(Clone)] add a #[is_builtin_clone] attribute to the method? I'm not sure.
This comment has been minimized.
This comment has been minimized.
scalexm
Aug 7, 2017
Author
Member
@arielb1 how would we handle bounds checking? #[derive(Clone)] currently uses local variables of type AssertParamIsClone<T: Clone + ?Sized> for each field type T in order to deal with recursive types. This would not be applicable here.
This comment has been minimized.
This comment has been minimized.
scalexm
Aug 7, 2017
Author
Member
Actually since we are "fully generic" here as you said, we would could indeed check by hand that the bounds hold for each field type when building the shim.
This comment has been minimized.
This comment has been minimized.
arielb1
Aug 8, 2017
Contributor
About plumbing #[derive(Clone)] - we want to give an error on the generic types, before monomorphization, so we can't use this function. So we need a separate checking function - maybe that is not a good idea after all.
arielb1
reviewed
Aug 7, 2017
|
|
||
| match rcvr_ty.sty { | ||
| ty::TyArray(ty, len) => { | ||
| let mut returns = Vec::new(); |
This comment has been minimized.
This comment has been minimized.
arielb1
Aug 7, 2017
Contributor
I'm worried this might create code explosion for large arrays (think of <[Box<u8>; 1048576]>::clone). Can you try to use a loop and let LLVM unroll it? You're late MIR, so I don't think you have to care about pre-initializing the array.
This comment has been minimized.
This comment has been minimized.
scalexm
Aug 7, 2017
Author
Member
There is also the possibility to only build a Clone shim for [T; N] where T: Copy, as it's the case already.
This comment has been minimized.
This comment has been minimized.
arielb1
reviewed
Aug 7, 2017
| func, | ||
| args: vec![Operand::Consume(ref_loc)], | ||
| destination: Some((loc.clone(), BasicBlock::new(i + 1))), | ||
| cleanup: None, |
This comment has been minimized.
This comment has been minimized.
arielb1
Aug 7, 2017
•
Contributor
This is wrong - if the drop of a field panics, you need to drop all the previous fields.
It sounds like we have way too many places that try to create their own drop ladders, and we need some sort of unified abstraction.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
arielb1
added
the
S-waiting-on-author
label
Aug 8, 2017
scalexm
force-pushed the
scalexm:issue-28229
branch
2 times, most recently
from
7370f8f
to
779d2c5
Aug 8, 2017
This comment has been minimized.
This comment has been minimized.
|
From a lang team perspective, I am on board with this change. I don't have an opinion on the compiler side of things. |
This comment has been minimized.
This comment has been minimized.
|
@arielb1 should be good now |
This comment has been minimized.
This comment has been minimized.
|
|
scalexm
added some commits
Aug 4, 2017
scalexm
force-pushed the
scalexm:issue-28229
branch
from
0d108eb
to
d58b40e
Aug 14, 2017
arielb1
referenced this pull request
Aug 15, 2017
Merged
Remove the trait selection impl in method::probe #43880
bors
added a commit
that referenced
this pull request
Aug 15, 2017
nikomatsakis
self-assigned this
Aug 21, 2017
This comment has been minimized.
This comment has been minimized.
|
I like the approach. =) @bors r+ |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Aug 21, 2017
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Aug 22, 2017
This comment has been minimized.
This comment has been minimized.
|
|
bors
merged commit d58b40e
into
rust-lang:master
Aug 22, 2017
This comment has been minimized.
This comment has been minimized.
|
OK, so, I think I was a bit hasty in merging this PR. I thought that the only question at hand was whether it was ok for clone to be a lang-item and for us to generate impls of However, reading more carefully, I see that this PR generates clone impls for a few other cases beyond that minimal set. To be fair, these were called out in the PR description. I was just hasty.
For those two reasons, I am thinking that perhaps we should back out this change -- or at least disable it temporarily until we reach a consensus. (And perhaps both libs and lang team ought to be involved, given that |
This comment has been minimized.
This comment has been minimized.
|
I'm not sure it was necessarily intentional for |
This comment has been minimized.
This comment has been minimized.
Fair. Of course, under the approach implemented in this PR, that is not an issue. |
This comment has been minimized.
This comment has been minimized.
|
|
bluss
added
the
relnotes
label
Aug 22, 2017
arielb1
added a commit
to arielb1/rust
that referenced
this pull request
Aug 22, 2017
arielb1
referenced this pull request
Aug 22, 2017
Closed
Revert "Auto merge of #43690 - scalexm:issue-28229, r=nikomatsakis" #44045
This was referenced Aug 28, 2017
bors
added a commit
that referenced
this pull request
Aug 30, 2017
scalexm
referenced this pull request
Aug 30, 2017
Merged
RFC - compiler-generated Clone impls for Arrays and Tuples #2133
This comment has been minimized.
This comment has been minimized.
|
Tracking issue #44496 |
scalexm commentedAug 5, 2017
This fixes a long-standing ICE and limitation where some builtin types implement
Copybut notClone(whereasCloneis a super trait ofCopy).However, this PR has a few side-effects:
Cloneis now marked as a lang item.[T; N]is nowCloneifT: Clone(currently, only ifT: Copyand forN <= 32).fn foo<'a>() where &'a mut (): Clone { }won't compile anymore because of how bounds for builtin traits are handled (e.g. same thing currently if you replaceClonebyCopyin this example). Of course this function is unusable anyway, an error would pop as soon as it is called.Hence, I'm wondering wether this PR would need an RFC...
Also, cc-ing @nikomatsakis, @arielb1.
Related issues: #28229, #24000.