Skip to content
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

Use `dangling` for default slices (like vec and box do) #62487

Closed
wants to merge 1 commit into from

Conversation

@scottmcm
Copy link
Member

commented Jul 8, 2019

More consistent and means LLVM & linking don't need to faff about with useless private constants.

(I suspect the previous way might also have meant it could return different things in different translation units, but I haven't actually checked whether that was happening.)

Use dangling for default slices (like vec and box do)
More consistent and means LLVM doesn't need to faff about with useless private constants.
@rust-highfive

This comment has been minimized.

Copy link
Collaborator

commented Jul 8, 2019

r? @aidanhs

(rust_highfive has picked a reviewer for you, use r? to override)

@cramertj

This comment has been minimized.

Copy link
Member

commented Jul 8, 2019

I frequently use &[] and &mut [] literals in code, so if this is actually a perf / codegen improvement it'd be great to see it on all uses of &[] and &mut [].

@Aaron1011

This comment has been minimized.

Copy link
Contributor

commented Jul 8, 2019

I would be somewhat concerned if from_raw_parts(ptr::NonNull::dangling().as_ptr(), 0) represented any perf/codegen improvement over &[] - that would mean that an obscure, non-obvious way of constructing an empty slice should actually be preferred over the obvious, easy-to-read way.

@scottmcm

This comment has been minimized.

Copy link
Member Author

commented Jul 8, 2019

There is a slight codegen difference, but I wouldn't expect any perf difference from it.

I just wanted this check to pass so my debugging printfs of .as_ptr()s were more readable:

std::ptr::eq(<&[u32]>::default(), <Vec<u32>>::default().as_slice())
@gagan0723

This comment has been minimized.

Copy link
Member

commented Jul 23, 2019

ping from wg-triage, @aidanhs any updates on this?

@chocol4te

This comment has been minimized.

Copy link
Contributor

commented Jul 31, 2019

Second ping from wg-triage, pinging reviewer from T-compiler per procedure.

@nagisa

@hdhoang

This comment has been minimized.

Copy link
Contributor

commented Aug 9, 2019

Third ping from triage, pinging reviewer in T-compiler @estebank

@estebank
Copy link
Contributor

left a comment

The code change looks reasonable but I share the concerns about codegen differences with &[]. I would prefer other reviewers in @rust-lang/compiler took a second look to verify we're not missing something obvious.

@scottmcm

This comment has been minimized.

Copy link
Member Author

commented Aug 9, 2019

Now that I'm back from vacation, I'd also be willing to take a look at changing something in mir transforms to generate the simpler version of this, if someone could point me to somewhere appropriate. (Presumably in the promotion code somewhere? Or maybe I could change &_N in MIR to just be a constant when typeof(_N) is a ZST? But I don't know how to check generic ZSTs...)

@eddyb

This comment has been minimized.

Copy link
Member

commented Aug 9, 2019

@scottmcm You don't want to do this in MIR, but rather rustc_codegen_llvm::consts.
That is, whenever a constant allocation of size 0 is needed, instead of adding a LLVM global, you can constant-inttoptr-cast the allocation's alignment to the right pointer type.
@oli-obk might be able to help with this.

@oli-obk

This comment has been minimized.

Copy link
Contributor

commented Aug 9, 2019

Oh, I never thought about ZSTs when messing with llvm and constants. You should be able to just add an if alloc.size() != 0 around

let init = const_alloc_to_llvm(self, alloc);
if alloc.mutability == Mutability::Mutable {
self.static_addr_of_mut(init, alloc.align, None)
} else {
self.static_addr_of(init, alloc.align, None)
}
and generate a properly aligned pointer in the else branch.

Though such a solution will miss &(&(42, [])).1 (or something similar), because the allocation is large while the pointer doesn't need to point to something large. It's probably irrelevant (I mean we miss this right now, too), and it's probably rare for just the inner reference to be publicly reachable.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

commented Aug 15, 2019

Compiler team meeting:

Assigning to @eddyb to either help with a more general solution or perhaps "just do it".

r? @eddyb

@scottmcm

This comment has been minimized.

Copy link
Member Author

commented Aug 17, 2019

Closing in favour of #63635

@scottmcm scottmcm closed this Aug 17, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.