Skip to content

Conversation

@kouhe3
Copy link
Contributor

@kouhe3 kouhe3 commented Jan 5, 2026

fix #19780

Add enum and field to track = and ..

Create a new function to determine match and missing msg

behavior

#![feature(default_field_values)]
fn main() {
    let u1 = UserInfo { id: 10, $0 ,.. }; // trigger suggestion: age,email
               ^^^^^^ 💡 missing field 
                    | -email
}

struct UserInfo {
    id: i32,
    age: f32 = 1.0,
    email: String,
}

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 5, 2026
@kouhe3 kouhe3 marked this pull request as draft January 5, 2026 13:07
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 5, 2026
@kouhe3 kouhe3 force-pushed the default_field_values branch from c06113d to 046077b Compare January 6, 2026 15:53
@kouhe3 kouhe3 marked this pull request as ready for review January 6, 2026 16:36
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 6, 2026
}
}
_ => {
let missing_fields = ctx.sema.record_literal_missing_fields(record_expr);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Due to miss != match commit. I suggest here use new record_literal_matched_fields function

}
}

#[derive(Debug, Clone, Eq, PartialEq)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Derive Copy.

#[derive(Debug, Clone, Eq, PartialEq)]
pub enum RecordSpread {
None,
Empty,
Copy link
Contributor

Choose a reason for hiding this comment

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

I dislike calling this Empty as it does not explain what it does, especially to users unfamiliar with the unstable feature. However I don't really have a good name... rustc calls this Rest (in the context of them calling the enum StructRest) which is also not a good name. Perhaps pub enum RecordSpread { None, FieldDefaults, FromBase(ExprId) }?

pub type_ref: TypeRefId,
pub visibility: RawVisibility,
pub is_unsafe: bool,
pub has_default_value: bool,
Copy link
Contributor

Choose a reason for hiding this comment

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

We will likely want the default for some things, so it makes sense to store an Option<ExprId> here and lower the expression.

}
if let &Some(expr) = spread {
f(expr);
if let RecordSpread::Expr(ref expr) = *spread {
Copy link
Contributor

Choose a reason for hiding this comment

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

Redundant ref then *, ditto below.


for (_, data) in fields.fields().iter() {
let FieldData { name, type_ref, visibility, is_unsafe } = data;
let FieldData { name, type_ref, visibility, is_unsafe, .. } = data;
Copy link
Contributor

Choose a reason for hiding this comment

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

Please ignore only specific fields (no .. patterns, only field: _), we do not want to miss new fields here.

Also we probably want to print the default value, but we can't since we don't store it - relevant to what I said in the other comment.

Some((variant_def, missed_fields))
}

pub fn record_literal_matched_fields(
Copy link
Contributor

Choose a reason for hiding this comment

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

This and its friend record_pattern_matched_fields() don't belong in this file, record_literal_missing_fields() and record_pattern_missing_fields() are here because they're used by diagnostics.

Also "missing" vs. "matched" doesn't really capture the distinction, both are both missing and non-matched (which I suppose was the intent). Something like missing_considering_spread and missing_without_spread is better.

Expr::RecordLit { path: _, fields, spread, .. } => {
self.infer_mut_not_expr_iter(fields.iter().map(|it| it.expr));
if let RecordSpread::Expr(expr) = *spread {
self.infer_mut_not_expr_iter(std::iter::once(expr));
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
self.infer_mut_not_expr_iter(std::iter::once(expr));
self.infer_mut_expr(expr, Mutability::Not);

Some(p)
}
None => None,
RecordSpread::None | RecordSpread::Empty => None,
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should separate them, and for RecordSpread::Empty cause not_supported!(), because it needs a different implementation.

return;
}
missing_fields
if update_exists {
Copy link
Contributor

Choose a reason for hiding this comment

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

This if should not exist here, instead call record_literal_matched_fields() to begin with.

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.

incorrect "missing structure fields" on-the-fly diagnostic

3 participants