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

rustc_typeck: unify expected return types with formal return types to propagate coercions through calls of generic functions. #20415

Merged
merged 4 commits into from
Jan 12, 2015

Conversation

eddyb
Copy link
Member

@eddyb eddyb commented Jan 2, 2015

This allows passing Some(free_fn) to something expecting Option<fn()>, dealing with most of the fallout from #19891.
Fixes #20178.

@rust-highfive
Copy link
Collaborator

r? @luqmana

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

@nikomatsakis nikomatsakis assigned nikomatsakis and unassigned luqmana Jan 2, 2015
@nikomatsakis
Copy link
Contributor

assigning myself as reviewer

@nikomatsakis
Copy link
Contributor

This looks really nice but not quite there. Look at what I wrote and let me know if you have questions.

fcx.infcx().probe(|_| {
use rustc::middle::infer::combine::Combine;
let trace = infer::TypeTrace::dummy(fcx.tcx());
match fcx.infcx().equate(false, trace).tys(ret_ty, formal_ret_ty) {
Copy link
Contributor

Choose a reason for hiding this comment

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

One last comment: I'd rather not see the Combine trait used outside of infer. You can just invoke infer::mk_eqty() instead, it's equivalent and shorter.

Copy link
Contributor

Choose a reason for hiding this comment

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

(Better yet, move it to a method :)

Copy link
Member Author

Choose a reason for hiding this comment

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

It's not equivalent, what I have here could be with_eqty or resolve_with_eqty.

Copy link
Contributor

Choose a reason for hiding this comment

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

in what way is it not equivalent? it looks equivalent to me.

Copy link
Member Author

Choose a reason for hiding this comment

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

I execute code in the Ok case, before rolling back the snapshot, while mk_eqty would commit it. Unless you mean it's okay to have nested snapshots like this, in which case I have to wonder what the cost is.

Copy link
Contributor

Choose a reason for hiding this comment

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

It is fine to have nested snapshots and the cost is nothing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Commit within a nested snapshot in particular is basically a no-op.

@eddyb eddyb force-pushed the unify-expected-return branch from d23810a to b1027b9 Compare January 8, 2015 16:26
@eddyb
Copy link
Member Author

eddyb commented Jan 8, 2015

I've switched back to subtyping and used a modified version of commit_if_ok that commits region vars (which can be created during subtyping) but discards the type bindings (which could be incorrect and are only usable for expectations).

@@ -613,6 +613,36 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
self.commit_unconditionally(move || self.try(move |_| f()))
}

/// Execute `f` and commit the region bindings if successful
Copy link
Contributor

Choose a reason for hiding this comment

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

We probably want a more detailed comment here. "...commit only the region bindings if successful. The function f must be very careful not to leak any non-region variables that get created."

@nikomatsakis
Copy link
Contributor

@eddyb ok I have to admit, I have my reservations but this looks pretty nice.

r+ modulo nits (and maybe a cleaned up commit history?)

@@ -2750,7 +2773,25 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
AutorefArgs::No => {}
}

check_expr_coercable_to_type(fcx, &***arg, formal_ty);
// The special-cased logic below has three functions:
// 1. Provide as good of an expectated type as possible.
Copy link
Contributor

Choose a reason for hiding this comment

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

"expected type"

@eddyb eddyb force-pushed the unify-expected-return branch from a25307b to 4748721 Compare January 11, 2015 20:10
bors added a commit that referenced this pull request Jan 12, 2015
rustc_typeck: unify expected return types with formal return types to propagate coercions through calls of generic functions.

Reviewed-by: nikomatsakis
@bors bors merged commit 4748721 into rust-lang:master Jan 12, 2015
@eddyb eddyb deleted the unify-expected-return branch January 12, 2015 04:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fn item/fn pointer distinction breaks fn pointer generics
6 participants