-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
implement rfc-2528 type_changing-struct-update #90035
Conversation
r? @jackh726 (rust-highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
#89730 is smaller, just the feature gate - let's land that first, then rebase on that |
OK, that sounds good |
☔ The latest upstream changes (presumably #90188) made this pull request unmergeable. Please resolve the merge conflicts. |
@SparrowLii can you rebase on master now that #89730 has been merged? I'm going to try to do a proper review here this weekend. |
That is encouraging! But I don't have a test environment at hand right now. I will resolve the conflict this Monday, as soon as possible |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
The rebasing and modification of tests are done. I think it is ready to be reviewed. |
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.
Overall pretty straightforward, a few nits. Can you squash the commits (other than spliting out that one commit)?
compiler/rustc_feature/src/active.rs
Outdated
@@ -686,7 +686,7 @@ declare_features! ( | |||
|
|||
/// Allows creation of instances of a struct by moving fields that have | |||
/// not changed from prior instances of the same struct (RFC #2528) | |||
(incomplete, type_changing_struct_update, "1.58.0", Some(86555), None), | |||
(active, type_changing_struct_update, "1.58.0", Some(86555), None), |
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.
I think this is still incomplete
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.
I say this because, even though it "works", I'd like a few more tests for better coverage before switching this to "active".
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.
OK, it is incomplete
now
src/doc/unstable-book/src/language-features/type-changing-struct-update.md
Show resolved
Hide resolved
let m1: Machine<State1> = Machine { | ||
state: State1, | ||
lt_str: &s, | ||
//~^ ERROR `s` does not live long enough [E0597] |
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.
So...this is behavior on nightly today. The intention is in fact to allow changing lifetime parameters, right? Probably, the error should get moved to line 20 (creating m1
should be fine, we should infer '_
as lifetime, but trying to create m2
without updating the lifetime on lt
is a problem.
I don't think this needs to be changed in this PR, but it does need a FIXME (and probably either an issue filed or a mention in the (implementation?) tracking issue)
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.
That's right. I added FIXME in lifetime-update.rs
LL | let m2: Machine<'static, State1> = Machine { | ||
| ------------------------ type annotation requires that `s` is borrowed for `'static` |
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.
Yeah, at least the information is around; just the span needs to change I think
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.
I added FIXME in lifetime-update.rs
@@ -1,3 +1,5 @@ | |||
// gate-test-type_changing_struct_update |
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.
Just noting that the FIXME
probably isn't correct. But, perhaps this should give a suggest to add the feature if on nightly.
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.
I correct the location of FIXME. But if we want to add a feature trigger, we can no longer use the original check_expr_has_type_or_error
function, because we need to know which field caused a type error. This may require us to merge the two feature branches. I will submit a new commit to try to implement it.
span: base_expr.span, | ||
}); | ||
}; | ||
variant |
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.
So, why use variant
here but non_enum_variant()
below? These should be the same thing, but just a bit weird. (Probably an opportunity for a bit of cleanup)
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.
Yep they both use variant
now. I didn’t find other code that need to be cleaned up, please let me know if there are any
error[E0308]: mismatched types | ||
--> $DIR/type-generic-update.rs:31:11 | ||
| | ||
LL | ..m1 | ||
| ^^ field type mismatch: Machine.state | ||
| | ||
= note: expected type `i32` | ||
found type `f64` |
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 is...fine...for now, but this needs better diagnostics. Should be a followup issue filed or noted on tracking issue.
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.
I added a FIXME to indicate that the diagnostic information needs to be enhanced
// the fields with the base_expr. This could cause us to hit errors later | ||
// when certain fields are assumed to exist that in fact do not. | ||
if !error_happened { | ||
let fru_tys = if self.tcx.features().type_changing_struct_update { |
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.
I think having these be two separate branches is fine for now, but I think it'd be nice to eventually merge them as much as possible. Can you add a FIXME?
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.
Yes, have add a FIXME here. In order to add a feature trigger, I think it is necessary to merge them. I will submit a new commit to try to implement it.
put the test dir in test/ui/rfcs
OK. Have made a squash. |
As stated by FIXME in |
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.
Last commit feels a bit messy to me; not sure how best to clean it up though.
Left a couple commits.
if ty.is_never() { | ||
assert!( | ||
!self.typeck_results.borrow().adjustments().contains_key(base_expr.hir_id), | ||
"expression with never type wound up being adjusted" | ||
); | ||
let adj_ty = self.next_ty_var(TypeVariableOrigin { | ||
kind: TypeVariableOriginKind::AdjustmentType, | ||
span: base_expr.span, | ||
}); | ||
self.apply_adjustments( | ||
base_expr, | ||
vec![Adjustment { kind: Adjust::NeverToAny, target: adj_ty }], | ||
); | ||
ty = adj_ty; | ||
} |
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.
Hmm, what is this needed for? If this is needed, can you add a test for it?
let cause = self.misc(base_expr.span); | ||
let mut fru_tys = None; | ||
let mut err = None; | ||
let is_struct; |
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.
Why define this here?
}; | ||
self.typeck_results.borrow_mut().fru_field_types_mut().insert(expr_id, fru_tys); | ||
err = self.demand_suptype_diag(base_expr.span, expected_ty, ty); | ||
is_struct = false; |
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.
Why not just emit the error here?
Or, better yet, any way we can just return early and do away with the nesting?
Thanks for reviewing. I manually copied most of the implementation of |
I think this can definitely be cleaned up a bit in the future, and there is a FIXME for that, so @bors r+ |
📌 Commit 926892d has been approved by |
…askrgr Rollup of 7 pull requests Successful merges: - rust-lang#89561 (Type inference for inline consts) - rust-lang#90035 (implement rfc-2528 type_changing-struct-update) - rust-lang#90613 (Allow to run a specific rustdoc-js* test) - rust-lang#90683 (Make `compiler-docs` only control the default instead of being a hard off-switch) - rust-lang#90685 (x.py: remove fixme by deleting code) - rust-lang#90701 (Record more artifact sizes during self-profiling.) - rust-lang#90723 (Better document `Box` and `alloc::alloc::box_free` connection) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This PR implement rfc2528-type_changing-struct-update.
The main change process is as follows:
base_expr
intocheck_expr_struct_fields
to avoid returningremaining_fields
(a relatively complex hash table)check_expr_has_type_or_error
), if thetype_changing_struct_update
feature is set, enter a different processing flow, otherwise keep the original flowremaining_fields
. If the field inbase_expr
is not the suptype of the field inadt_ty
, an error(FeildMisMatch
) will be reported.The MIR part does not need to be changed, because only the items contained in
remaining_fields
will be extracted frombase_expr
when MIR is generated. This means that fields with different types inbase_expr
will not be usedUpdates #86618
cc @nikomatsakis