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

Decompose Adjustment into smaller steps and remove the method map. #42281

Merged
merged 14 commits into from
Jun 1, 2017

Conversation

eddyb
Copy link
Member

@eddyb eddyb commented May 28, 2017

The method map held method callee information for:

  • actual method calls (x.f(...))
  • overloaded unary, binary, indexing and call operators
  • every overloaded deref adjustment (many can exist for each expression)

That last one was a historical accident hack, and part of the motivation for this PR, along with:

  • a desire to compose adjustments more freely
  • containing the autoderef logic better to avoid mutation within an inference snapshot
  • not creating TyFnDef types which are incompatible with the original one
    • i.e. we used to take aTyFnDef's for<'a> &'a T -> &'a U signature and instantiate 'a using a region inference variable, then package the resulting &'b T -> &'b U signature in another TyFnDef, while keeping the same DefId and Substs
  • to fix port the "autoref-arg" code used in overloaded operators to use the ptr adjustment table #3548 by explicitly writing autorefs for the RHS of comparison operators

Individual commits tell their own story, of "atomic" changes avoiding breaking semantics.

Future work based on this PR could include:

  • removing the signature from TyFnDef, now that it's always "canonical"
    • some questions of variance remain, as subtyping still treats the signature differently
  • moving part of the typeck logic for methods, autoderef and coercion into rustc::traits
  • allowing LUB coercions (joining multiple expressions) to "stack up" many adjustments
  • transitive coercions (e.g. reify or unsize after multiple steps of autoderef)

r? @nikomatsakis

@eddyb eddyb added the S-waiting-on-crater Status: Waiting on a crater run to be completed. label May 28, 2017
@eddyb eddyb requested a review from nikomatsakis May 28, 2017 13:48
@eddyb
Copy link
Member Author

eddyb commented May 28, 2017

Started crater run.

@eddyb
Copy link
Member Author

eddyb commented May 28, 2017

The current Travis failures are in UI tests due to error output changed (intentionally), e.g.:

 error[E0277]: the trait bound `{integer}: std::ops::Mul<()>` is not satisfied
-  --> $DIR/binops.rs:14:5
+  --> $DIR/binops.rs:14:7
    |
 14 |     3 * ();
-   |     ^^^^^^ no implementation for `{integer} * ()`
+   |       ^ no implementation for `{integer} * ()`
    |
    = help: the trait `std::ops::Mul<()>` is not implemented for `{integer}`

cc @rust-lang/docs @nikomatsakis @jonathandturner Is this is an improvement?

@GuillaumeGomez
Copy link
Member

@eddyb: I don't think it is. It should still underline the whole expression.

@Mark-Simulacrum
Copy link
Member

I personally consider it an improvement, as it points at the thing that isn't implemented. The operands aren't really part of the problem; making the span as small as possible seems better.

@eddyb
Copy link
Member Author

eddyb commented May 28, 2017

Crater report is clean (modulo the usual network errors and lint plugins).

@eddyb eddyb removed the S-waiting-on-crater Status: Waiting on a crater run to be completed. label May 28, 2017
@QuietMisdreavus
Copy link
Member

I'm with @Mark-Simulacrum here. The error text still says which specific kind of multiplication isn't implemented, and pointing directly at the operator can save some confusion if it were part of a larger/more complicated expression.

@sophiajt
Copy link
Contributor

@eddyb - yes, pointing at the offending operator looks like an improvement to me. As @QuietMisdreavus points out, this becomes more important with larger expressions, but even small ones seem to be a little clearer

@eddyb
Copy link
Member Author

eddyb commented May 29, 2017

Thanks everyone! I pushed an update to the UI tests.

@carols10cents carols10cents added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 29, 2017
@bors
Copy link
Contributor

bors commented May 30, 2017

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

Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

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

a few nits, but r=me. Very cool!

/// Represents coercing a value to a different type of value.
///
/// We transform values by following the following steps in order:
/// 1. Apply a step of `Adjust` (see its variants for details).
Copy link
Contributor

Choose a reason for hiding this comment

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

this should say "apply the base transformation described by kind", right?

Copy link
Member Author

Choose a reason for hiding this comment

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

What do you mean by "base"? But yeah I could use kind and then refer to "variants of Adjust".

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh look at the latest version of this comment, that was transient.

.map_or_else(|| self.expr_ty(expr), |adj| adj.target)
}

pub fn expr_ty_adjusted_opt(&self, expr: &hir::Expr) -> Option<Ty<'tcx>> {
self.adjustments.get(&expr.id)
self.expr_adjustments(expr).last()
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I'd find this easier to read if each step in the chain (i.e., .last(), .map(), and .or_else() were on their own line). Or at least .map() and .or_else().

@@ -134,22 +134,22 @@ fn test_push() {
fn test_push_unique() {
let mut heap = BinaryHeap::<Box<_>>::from(vec![box 2, box 4, box 9]);
assert_eq!(heap.len(), 3);
assert!(*heap.peek().unwrap() == box 9);
assert!(**heap.peek().unwrap() == 9);
Copy link
Contributor

Choose a reason for hiding this comment

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

what's happening here? some lints firing?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yupp! Comparison operators are now understood by the "unnecessary allocation" lint.

|
34 | n + sum_to(n - 1)
| ^^^^^^^^^^^^^^^^^ no implementation for `u32 + impl Foo`
| ^ no implementation for `u32 + impl Foo`
Copy link
Contributor

Choose a reason for hiding this comment

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

nice

@nikomatsakis
Copy link
Contributor

Regarding the new spans -- yes, I consider it an improvement. I believe this is what clang does. Part of the reason I think this is better: mutil-line spans are terrible, and this avoids that.

@nikomatsakis
Copy link
Contributor

nikomatsakis commented May 30, 2017

some questions of variance remain, as subtyping still treats the signature differently

I was wondering what happened to those changes....

@eddyb
Copy link
Member Author

eddyb commented May 30, 2017

@nikomatsakis I actually rebased those on top of this branch today, but tried to keep this PR separate.

@eddyb
Copy link
Member Author

eddyb commented May 31, 2017

@bors r=nikomatsakis

@bors
Copy link
Contributor

bors commented May 31, 2017

📌 Commit e3b49c5 has been approved by nikomatsakis

@bors
Copy link
Contributor

bors commented May 31, 2017

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

@eddyb
Copy link
Member Author

eddyb commented Jun 1, 2017

@bors r=nikomatsakis

@bors
Copy link
Contributor

bors commented Jun 1, 2017

📌 Commit 5fb37be has been approved by nikomatsakis

@bors
Copy link
Contributor

bors commented Jun 1, 2017

⌛ Testing commit 5fb37be with merge 4ed2eda...

bors added a commit that referenced this pull request Jun 1, 2017
Decompose Adjustment into smaller steps and remove the method map.

The method map held method callee information for:
* actual method calls (`x.f(...)`)
* overloaded unary, binary, indexing and call operators
* *every overloaded deref adjustment* (many can exist for each expression)

That last one was a historical ~~accident~~ hack, and part of the motivation for this PR, along with:
* a desire to compose adjustments more freely
* containing the autoderef logic better to avoid mutation within an inference snapshot
* not creating `TyFnDef` types which are incompatible with the original one
  * i.e. we used to take a`TyFnDef`'s `for<'a> &'a T -> &'a U` signature and instantiate `'a` using a region inference variable, *then* package the resulting `&'b T -> &'b U` signature in another `TyFnDef`, while keeping *the same* `DefId` and `Substs`
* to fix #3548 by explicitly writing autorefs for the RHS of comparison operators

Individual commits tell their own story, of "atomic" changes avoiding breaking semantics.

Future work based on this PR could include:
* removing the signature from `TyFnDef`, now that it's always "canonical"
  * some questions of variance remain, as subtyping *still* treats the signature differently
* moving part of the typeck logic for methods, autoderef and coercion into `rustc::traits`
* allowing LUB coercions (joining multiple expressions) to "stack up" many adjustments
* transitive coercions (e.g. reify or unsize after multiple steps of autoderef)

r? @nikomatsakis
@bors
Copy link
Contributor

bors commented Jun 1, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: nikomatsakis
Pushing 4ed2eda to master...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

port the "autoref-arg" code used in overloaded operators to use the ptr adjustment table
8 participants