-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Replace structurally_resolved_type
in casts check.
#48270
Conversation
r? @estebank (rust_highfive has picked a reviewer for you, use r? to override) |
LGTM, I think we should run crater on this to verify that we're not breaking something in the wild. @bors try |
Replace `structurally_resolved_type` in casts check. The behaviour of `resolve_type_vars_if_possible` is simpler and infallible. Other minor refactorings. I'm not sure if this is backwards compatible, in theory resolving obligations between two cast checks could solve a dependency between them, but I don't know if that's actually possible and it doesn't sound like something we'd want to support.
☀️ Test successful - status-travis |
I've tacked on a similar refactoring to unary expr check. In theory this could make more code compile because we don't error or could ommit an otherwise useful error. In practice I couldn't observe any effect. |
cc @rust-lang/compiler |
r? @nikomatsakis -- I'd like to read this over |
@@ -64,7 +63,7 @@ impl<'tcx> CastTy<'tcx> { | |||
ty::TyBool => Some(CastTy::Int(IntTy::Bool)), | |||
ty::TyChar => Some(CastTy::Int(IntTy::Char)), | |||
ty::TyInt(_) => Some(CastTy::Int(IntTy::I)), | |||
ty::TyInfer(ty::InferTy::IntVar(_)) => Some(CastTy::Int(IntTy::Ivar)), | |||
ty::TyInfer(ty::InferTy::IntVar(_)) => Some(CastTy::Int(IntTy::I)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this Ivar
is basically unused I guess?
@@ -488,11 +488,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { | |||
ty::TypeVariants::TyInfer(t) => { | |||
match t { | |||
ty::InferTy::IntVar(_) | | |||
ty::InferTy::FloatVar(_) | | |||
ty::InferTy::FreshIntTy(_) | | |||
ty::InferTy::FreshFloatTy(_) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, the "fresh" variants here are just dead code I suppose
OK, well, the change basically makes sense, not a big diff obviously. crater run seems like a fine thing. cc @rust-lang/infra |
I'm not entirely happy with how casts fit into the pipeline, but I suppose we would probably prefer for them to apply "atomically" (maybe?). At least, I don't love the idea of the ordering being overly significant, although I guess it's not the end of the world if it is, since we already have some ordering dependencies from coercions. |
cc @rust-lang/infra -- or should it be @rust-lang/release ? -- any word on crater run? |
Crater run started; results expected in ~5 days. Our crater queue is quite full right now, so PRs are waiting for a week or two generally to get their turn at crater. |
Crater results: http://cargobomb-reports.s3.amazonaws.com/pr-48270/index.html. 'Blacklisted' crates (spurious failures etc) can be found here. If you see any spurious failures not on the list, please make a PR against that file. (looks like this broke nix and so broke half the world 😄) |
Thanks for the crater run! Interesting results. Curiously nix itself didn't regress because the newest version isn't affected. Anyways, the issue is that it's possible to depend on the order in which casts are checked, this compiles today: fn main() {
let x = &"hello";
let mut y = x as *const _;
y = 0 as *const _;
} But this does not compile today: fn main() {
let x = &"hello";
let mut y = 0 as *const _;
y = x as *const _;
^^^^^^^^ cannot cast to a pointer of an unknown kind.
} We should make a decision, either they should both compile, or none of them should compile. If they both should compile, then we should use a more robust fixed-point algorithm rather than check in arbitratry order. If none of them should compile, then we should introduce a future-compatibility warning. |
Ideally yes, but in fact order does matter to rustc type checking quite a lot -- all coercions operate on a "greedy basis" and it's going to be a long road getting away from it, if we ever fully do. |
So, like @leodasvacas, I am not thrilled with the order dependency on casts -- we had intended to avoid it. Though, iirc, I've noted it before, and decided that -- since it exists and code relies on it -- we ought to keep that code working as best we can. Perhaps the same rule of thumb applies here. I don't think that breaking the older version of nix is really an option. It might be ok if we can instead publish a patch for that older version. That's imperfect, since apps would still need to update their lock files, but better than the current status. We might then want to do a warning period as well. |
I'd like to nominate for discussion but I'm not sure where =) I guess we'll start with T-lang. |
@leodasvacas
So we were talking about this in the meeting. I find this idea appealing -- but I am a bit wary of building that on the current implementation. I wonder if you'd have interest in trying to extend Chalk to model coercions and casts? In such a context, I would feel much more confident that we aren't accidentally introducing ambiguity. In general, I have this feeling like the right way to correct things here is to try and leave the current implementation alone -- so as not to disturb existing code -- and transition towards a new implementation with a cleaner foundation. |
The behaviour of `resolve_type_vars_if_possible` is simpler and infallible.
`resolve_type_vars_with_obligations` is the same but doesn't error on unresolved type variables. In theory this could make more code compile because we don't error or could ommit an otherwise useful error. In practice I couldn't observe any effect.
05ceae5
to
04121c5
Compare
I've updated this PR to revert the problematic change and added tests for the current behavior.
Sounds interesting, I'll ping you on gitter. |
04121c5
to
0a5a5c3
Compare
What is the path forward with this PR? It sounds like "close" to me. |
This PR basically just adds tests now. It's mistagged, should be waiting-for-review. |
That's on you @nikomatsakis ! |
@bors r+ |
📌 Commit 0a5a5c3 has been approved by |
…atsakis Replace `structurally_resolved_type` in casts check. The behaviour of `resolve_type_vars_if_possible` is simpler and infallible. Other minor refactorings. I'm not sure if this is backwards compatible, in theory resolving obligations between two cast checks could solve a dependency between them, but I don't know if that's actually possible and it doesn't sound like something we'd want to support.
Rollup of 14 pull requests Successful merges: - #49525 (Use sort_by_cached_key where appropriate) - #49575 (Stabilize `Option::filter`.) - #49614 (in which the non-shorthand patterns lint keeps its own counsel in macros) - #49665 (Small nits to make couple of tests pass on mips targets.) - #49781 (add regression test for #16223 (NLL): use of collaterally moved value) - #49795 (Properly look for uninhabitedness of variants in niche-filling check) - #49809 (Stop emitting color codes on TERM=dumb) - #49856 (Do not uppercase-lint #[no_mangle] statics) - #49863 (fixed typo) - #49857 (Fix "fp" target feature for AArch64) - #49849 (Add --enable-debug flag to musl CI build script) - #49734 (proc_macro: Generalize `FromIterator` impl) - #49730 (Fix ICE with impl Trait) - #48270 (Replace `structurally_resolved_type` in casts check.) Failed merges:
The behaviour of
resolve_type_vars_if_possible
is simpler and infallible. Other minor refactorings.I'm not sure if this is backwards compatible, in theory resolving obligations between two cast checks could solve a dependency between them, but I don't know if that's actually possible and it doesn't sound like something we'd want to support.