Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1724,6 +1724,12 @@ pub enum StructRest {
Rest(Span),
/// No trailing `..` or expression.
None,
/// No trailing `..` or expression, and also, a parse error occurred inside the struct braces.
///
/// This struct should be treated similarly to as if it had an `..` in it,
/// in particular rather than reporting missing fields, because the parse error
/// makes which fields the struct was intended to have not fully known.
NoneWithError(ErrorGuaranteed),
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,12 +340,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.arena.alloc_from_iter(fields.iter().map(|&ident| self.lower_ident(ident))),
),
ExprKind::Struct(se) => {
let rest = match &se.rest {
StructRest::Base(e) => hir::StructTailExpr::Base(self.lower_expr(e)),
let rest = match se.rest {
StructRest::Base(ref e) => hir::StructTailExpr::Base(self.lower_expr(e)),
StructRest::Rest(sp) => {
hir::StructTailExpr::DefaultFields(self.lower_span(*sp))
hir::StructTailExpr::DefaultFields(self.lower_span(sp))
}
StructRest::None => hir::StructTailExpr::None,
StructRest::NoneWithError(guar) => hir::StructTailExpr::NoneWithError(guar),
};
hir::ExprKind::Struct(
self.arena.alloc(self.lower_qpath(
Expand Down Expand Up @@ -1435,7 +1436,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
Some(self.lower_span(e.span))
}
StructRest::Rest(span) => Some(self.lower_span(*span)),
StructRest::None => None,
StructRest::None | StructRest::NoneWithError(_) => None,
};
let struct_pat = hir::PatKind::Struct(qpath, field_pats, fields_omitted);
return self.pat_without_dbm(lhs.span, struct_pat);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_pretty/src/pprust/state/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ impl<'a> State<'a> {
self.word("{");
let has_rest = match rest {
ast::StructRest::Base(_) | ast::StructRest::Rest(_) => true,
ast::StructRest::None => false,
ast::StructRest::None | ast::StructRest::NoneWithError(_) => false,
};
if fields.is_empty() && !has_rest {
self.word("}");
Expand Down
10 changes: 9 additions & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2652,7 +2652,9 @@ impl Expr<'_> {
ExprKind::Struct(_, fields, init) => {
let init_side_effects = match init {
StructTailExpr::Base(init) => init.can_have_side_effects(),
StructTailExpr::DefaultFields(_) | StructTailExpr::None => false,
StructTailExpr::DefaultFields(_)
| StructTailExpr::None
| StructTailExpr::NoneWithError(_) => false,
};
fields.iter().map(|field| field.expr).any(|e| e.can_have_side_effects())
|| init_side_effects
Expand Down Expand Up @@ -2944,6 +2946,12 @@ pub enum StructTailExpr<'hir> {
/// fields' default values will be used to populate any fields not explicitly mentioned:
/// `Foo { .. }`.
DefaultFields(Span),
/// No trailing `..` was written, and also, a parse error occurred inside the struct braces.
///
/// This struct should be treated similarly to as if it had an `..` in it,
/// in particular rather than reporting missing fields, because the parse error
/// makes which fields the struct was intended to have not fully known.
NoneWithError(ErrorGuaranteed),
}

/// Represents an optionally `Self`-qualified value/type path or associated extension.
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
walk_list!(visitor, visit_expr_field, fields);
match optional_base {
StructTailExpr::Base(base) => try_visit!(visitor.visit_expr(base)),
StructTailExpr::None | StructTailExpr::DefaultFields(_) => {}
StructTailExpr::None
| StructTailExpr::NoneWithError(_)
| StructTailExpr::DefaultFields(_) => {}
}
}
ExprKind::Tup(subexpressions) => {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1303,6 +1303,7 @@ impl<'a> State<'a> {
self.end(ib);
}
hir::StructTailExpr::None => {}
hir::StructTailExpr::NoneWithError(_) => {}
}
self.space();
self.word("}");
Expand Down
Loading
Loading