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

Add functional updates #879

Merged
merged 16 commits into from
Nov 20, 2024
Merged

Add functional updates #879

merged 16 commits into from
Nov 20, 2024

Conversation

vrindisbacher
Copy link
Collaborator

closes (#870)

@vrindisbacher vrindisbacher force-pushed the vrindisbacher/functional-updates branch from 9a4b0ff to 564a23c Compare November 7, 2024 22:44
@vrindisbacher vrindisbacher force-pushed the vrindisbacher/functional-updates branch 6 times, most recently from ebba28c to ffac9c9 Compare November 15, 2024 02:18
@ranjitjhala
Copy link
Contributor

Is this still WIP? Looks like only the formatter is grumbling?

@vrindisbacher
Copy link
Collaborator Author

Yes, I still need to work on sort checking but hoping to have this done soon.

@vrindisbacher vrindisbacher force-pushed the vrindisbacher/functional-updates branch from b40814d to 5bfa567 Compare November 15, 2024 21:50
@vrindisbacher vrindisbacher marked this pull request as ready for review November 15, 2024 22:09
@vrindisbacher
Copy link
Collaborator Author

vrindisbacher commented Nov 15, 2024

@nilehmann, do you want to wait until I have spreads added or do you want to take a look at this now?

@vrindisbacher vrindisbacher force-pushed the vrindisbacher/functional-updates branch from 8f94777 to 8b35e2c Compare November 15, 2024 22:25
@nilehmann
Copy link
Member

@vrindisbacher I'll take a look now

crates/flux-fhir-analysis/src/wf/param_usage.rs Outdated Show resolved Hide resolved
crates/flux-fhir-analysis/src/conv/mod.rs Outdated Show resolved Hide resolved
crates/flux-desugar/src/resolver/refinement_resolver.rs Outdated Show resolved Hide resolved
crates/flux-fhir-analysis/src/wf/sortck.rs Outdated Show resolved Hide resolved
tests/tests/neg/constructors/test00.rs Outdated Show resolved Hide resolved
crates/flux-fhir-analysis/locales/en-US.ftl Outdated Show resolved Hide resolved
crates/flux-fhir-analysis/src/wf/sortck.rs Outdated Show resolved Hide resolved
@vrindisbacher vrindisbacher force-pushed the vrindisbacher/functional-updates branch from b4d735e to 18f6a6c Compare November 18, 2024 19:46
@vrindisbacher vrindisbacher force-pushed the vrindisbacher/functional-updates branch from 99e627f to 42b0eda Compare November 19, 2024 16:00
@vrindisbacher vrindisbacher force-pushed the vrindisbacher/functional-updates branch from 13bd9af to 3cfee1f Compare November 19, 2024 17:43
Copy link
Member

@nilehmann nilehmann left a comment

Choose a reason for hiding this comment

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

Ok cool, this looks great.

I left some stylistic suggestions, but it looks good to go. There are also some clippy warnings.

}

#[derive(Debug)]
pub enum ConstructorArgs {
Copy link
Member

Choose a reason for hiding this comment

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

I'd use singular

Suggested change
pub enum ConstructorArgs {
pub enum ConstructorArg {

Comment on lines 120 to 125
let mut map = FxIndexMap::default();
let folded = self.0.sorts.fold_with(&mut SortSubst::new(args));
std::iter::zip(folded.iter(), self.0.field_names.iter()).for_each(|(sort, field_name)| {
map.insert(*field_name, sort.clone());
});
map
Copy link
Member

Choose a reason for hiding this comment

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

The following reads better in my opinion (or some variation of it)

Suggested change
let mut map = FxIndexMap::default();
let folded = self.0.sorts.fold_with(&mut SortSubst::new(args));
std::iter::zip(folded.iter(), self.0.field_names.iter()).for_each(|(sort, field_name)| {
map.insert(*field_name, sort.clone());
});
map
std::iter::zip(&self.0.field_names, &self.0.sorts.fold_with(&mut SortSubst::new(args)))
.map(|(name, sort)| (*name, sort.clone()))
.collect()

Comment on lines 1364 to 1380
let spread = if spreads.len() == 0 {
None
} else if spreads.len() == 1 {
let s = spreads[0];
let spread = fhir::Spread {
expr: self.desugar_expr(&s.expr)?,
span: s.span,
fhir_id: self.next_fhir_id(),
};
Some(self.genv().alloc(spread))
} else {
// Multiple spreads found - emit and error
return Err(self.emit_err(errors::MultipleSpreadsInConstructor::new(
spreads[1].span,
spreads[0].span,
)));
};
Copy link
Member

Choose a reason for hiding this comment

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

maybe

Suggested change
let spread = if spreads.len() == 0 {
None
} else if spreads.len() == 1 {
let s = spreads[0];
let spread = fhir::Spread {
expr: self.desugar_expr(&s.expr)?,
span: s.span,
fhir_id: self.next_fhir_id(),
};
Some(self.genv().alloc(spread))
} else {
// Multiple spreads found - emit and error
return Err(self.emit_err(errors::MultipleSpreadsInConstructor::new(
spreads[1].span,
spreads[0].span,
)));
};
let spread = match &spreads[..] {
[] => None.
[s] => {
let spread = fhir::Spread {
expr: self.desugar_expr(&s.expr)?,
span: s.span,
fhir_id: self.next_fhir_id(),
};
Some(self.genv().alloc(spread))
}
[s1, s2, ..] => {
// Multiple spreads found - emit and error
return Err(self.emit_err(errors::MultipleSpreadsInConstructor::new(
s1.span,
s2.span,
)));
}
};

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh cool I didn't know you could do that actually

spread: &Option<&fhir::Spread>,
) -> QueryResult<List<rty::Expr>> {
let struct_adt = self.genv.adt_sort_def_of(struct_def_id)?;
let sort_by_field = FxIndexSet::from_iter(struct_adt.field_names());
Copy link
Member

Choose a reason for hiding this comment

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

We could make struct_adt.field_names() return an &FxIndexSet<Symbol>. and even more, we can make the field field_names in AdtSortDefData an FxIndexSet<Symbol> instead of a Vec<Symbol>.

Also,

Suggested change
let sort_by_field = FxIndexSet::from_iter(struct_adt.field_names());
let field_names = FxIndexSet::from_iter(struct_adt.field_names());

Copy link
Member

Choose a reason for hiding this comment

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

Or maybe we can invert this, map exprs by name, and iterate over the field names. Something like

let spread = spread
    .map(|spread| self.conv_expr(env, &spread.expr))
    .transpose()?;
let field_exprs_by_name: FxIndexMap<Symbol, &fhir::FieldExpr> =
    exprs.iter().map(|e| (e.ident.name, e)).collect();
for (idx, field_name) in struct_adt.field_names().enumerate() {
    if let Some(field_expr) = field_exprs_by_name.get(field_name) {
        assns.push(self.conv_expr(env, &field_expr.expr)?);
    } else if Some(spread) = spread {
        let proj = rty::FieldProj::Adt { def_id: struct_def_id, field: idx as u32 };
        assns.push(rty::Expr::field_proj(spread, proj));
    }
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Nice I like that one.

@vrindisbacher vrindisbacher merged commit 90c7f42 into main Nov 20, 2024
7 checks passed
@vrindisbacher vrindisbacher deleted the vrindisbacher/functional-updates branch November 20, 2024 19:02
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.

3 participants