Skip to content

Simplify some Deref impls.#155536

Closed
nnethercote wants to merge 1 commit intorust-lang:mainfrom
nnethercote:fix-deref-Target
Closed

Simplify some Deref impls.#155536
nnethercote wants to merge 1 commit intorust-lang:mainfrom
nnethercote:fix-deref-Target

Conversation

@nnethercote
Copy link
Copy Markdown
Contributor

Deref has an associated type Target. Normally it's a non-reference type, because the deref method provides the reference in its return type &Self::Type.

There are several impls where Target is a reference type, which means the return type of deref is a double reference. This is necessary for DiagCtxtHandle and TyCtxt (due to how the lifetimes work) but unnecessary for the others. This commit changes the others to be more normal, which simplifies things in a few places.

r? @mejrs

`Deref` has an associated type `Target`. Normally it's a non-reference
type, because the `deref` method provides the reference in its return
type `&Self::Type`.

There are several impls where `Target` is a reference type, which means
the return type of `deref` is a double reference. This is necessary for
`DiagCtxtHandle` and `TyCtxt` (due to how the lifetimes work) but
unnecessary for the others. This commit changes the others to
be more normal, which simplifies things in a few places.
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 20, 2026

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in match lowering

cc @Nadrieril

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 20, 2026
@nnethercote
Copy link
Copy Markdown
Contributor Author

@mejrs: welcome to the review rotation! :)

// straight-forward (`TagEncoding::Direct`) or with a niche (`TagEncoding::Niche`).
let (tag_scalar_layout, tag_encoding, tag_field) = match op.layout().variants {
let layout = op.layout();
let (tag_scalar_layout, tag_encoding, tag_field) = match layout.variants {
Copy link
Copy Markdown
Member

@RalfJung RalfJung Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like here it doesn't actually simplify things, it forces us to manually spell out the temporary?

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The trade-off is that it's arguably worth having a vanilla Deref impl if it only causes one tiny piece of additional friction elsewhere.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look that bad to me. If I were to write this function, I'd probably hoist it regardless:

let layout = op.layout();
let ty = layout.ty;

and then op.layout() -> layout throughout this function.

Copy link
Copy Markdown
Member

@RalfJung RalfJung Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree the cost is small, but I also don't see any downside to the current Deref impls. They are a bit non-standard, sure, but... so what?

fn deref(&self) -> &&'a LayoutData<FieldIdx, VariantIdx> {
&self.0.0
type Target = LayoutData<FieldIdx, VariantIdx>;
fn deref(&self) -> &Self::Target {
Copy link
Copy Markdown
Member

@RalfJung RalfJung Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does make the type strictly weaker -- previously one could copy out the inner, longer-lived shared reference to get a 'a reference; now that information is lost. I am not sure I agree with this being an improvement, it seems more like a step backwards to me?

View changes since the review

Copy link
Copy Markdown
Contributor

@mejrs mejrs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it, I'm not feeling ralfs feedback though. I'll have to consider that some.

View changes since this review

@@ -3074,10 +3074,10 @@ struct CallCtxt<'a, 'b, 'tcx> {
}

impl<'a, 'b, 'tcx> Deref for CallCtxt<'a, 'b, 'tcx> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These can be changed to placeholder lifetimes:

Suggested change
impl<'a, 'b, 'tcx> Deref for CallCtxt<'a, 'b, 'tcx> {
impl<'b, 'tcx> Deref for CallCtxt<'_, 'b, 'tcx> {

Same for the other Deref impls you touched.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In #155549 I eliminaetd one of the lifetimes anyway.

// straight-forward (`TagEncoding::Direct`) or with a niche (`TagEncoding::Niche`).
let (tag_scalar_layout, tag_encoding, tag_field) = match op.layout().variants {
let layout = op.layout();
let (tag_scalar_layout, tag_encoding, tag_field) = match layout.variants {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look that bad to me. If I were to write this function, I'd probably hoist it regardless:

let layout = op.layout();
let ty = layout.ty;

and then op.layout() -> layout throughout this function.

@mejrs
Copy link
Copy Markdown
Contributor

mejrs commented Apr 20, 2026

I don't have a strong opinion actually. I would approve these changes but I can see Ralfs perspective too.

r? @RalfJung

@rustbot rustbot assigned RalfJung and unassigned mejrs Apr 20, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 20, 2026

RalfJung is not on the review rotation at the moment.
They may take a while to respond.

@RalfJung
Copy link
Copy Markdown
Member

My objections are minor, but then the entire PR looks like a minor drive-by improvement (or is this working towards something bigger?).

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented Apr 20, 2026

☔ The latest upstream changes (presumably #155552) made this pull request unmergeable. Please resolve the merge conflicts.

@nnethercote
Copy link
Copy Markdown
Contributor Author

Ok, I have learned that returning a double reference from deref is reasonable if the struct only has a pointer to another thing rather than owning it. So no need to continue with this.

@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 20, 2026
@nnethercote nnethercote deleted the fix-deref-Target branch April 20, 2026 22:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants