Skip to content

Commit 1aa068a

Browse files
committed
typeck/expr.rs: move check_expr_struct here.
1 parent bb93488 commit 1aa068a

File tree

2 files changed

+61
-60
lines changed

2 files changed

+61
-60
lines changed

src/librustc_typeck/check/expr.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::util::common::ErrorReported;
1616

1717
use errors::Applicability;
1818
use syntax::ast;
19+
use syntax::ptr::P;
1920
use syntax::symbol::sym;
2021
use rustc::hir;
2122
use rustc::hir::{ExprKind, QPath};
@@ -844,4 +845,64 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
844845
tuple
845846
}
846847
}
848+
849+
fn check_expr_struct(
850+
&self,
851+
expr: &hir::Expr,
852+
expected: Expectation<'tcx>,
853+
qpath: &QPath,
854+
fields: &'tcx [hir::Field],
855+
base_expr: &'tcx Option<P<hir::Expr>>,
856+
) -> Ty<'tcx> {
857+
// Find the relevant variant
858+
let (variant, adt_ty) =
859+
if let Some(variant_ty) = self.check_struct_path(qpath, expr.hir_id) {
860+
variant_ty
861+
} else {
862+
self.check_struct_fields_on_error(fields, base_expr);
863+
return self.tcx.types.err;
864+
};
865+
866+
let path_span = match *qpath {
867+
QPath::Resolved(_, ref path) => path.span,
868+
QPath::TypeRelative(ref qself, _) => qself.span
869+
};
870+
871+
// Prohibit struct expressions when non-exhaustive flag is set.
872+
let adt = adt_ty.ty_adt_def().expect("`check_struct_path` returned non-ADT type");
873+
if !adt.did.is_local() && variant.is_field_list_non_exhaustive() {
874+
span_err!(self.tcx.sess, expr.span, E0639,
875+
"cannot create non-exhaustive {} using struct expression",
876+
adt.variant_descr());
877+
}
878+
879+
let error_happened = self.check_expr_struct_fields(adt_ty, expected, expr.hir_id, path_span,
880+
variant, fields, base_expr.is_none());
881+
if let &Some(ref base_expr) = base_expr {
882+
// If check_expr_struct_fields hit an error, do not attempt to populate
883+
// the fields with the base_expr. This could cause us to hit errors later
884+
// when certain fields are assumed to exist that in fact do not.
885+
if !error_happened {
886+
self.check_expr_has_type_or_error(base_expr, adt_ty);
887+
match adt_ty.sty {
888+
ty::Adt(adt, substs) if adt.is_struct() => {
889+
let fru_field_types = adt.non_enum_variant().fields.iter().map(|f| {
890+
self.normalize_associated_types_in(expr.span, &f.ty(self.tcx, substs))
891+
}).collect();
892+
893+
self.tables
894+
.borrow_mut()
895+
.fru_field_types_mut()
896+
.insert(expr.hir_id, fru_field_types);
897+
}
898+
_ => {
899+
span_err!(self.tcx.sess, base_expr.span, E0436,
900+
"functional record update syntax requires a struct");
901+
}
902+
}
903+
}
904+
}
905+
self.require_type_is_sized(adt_ty, expr.span, traits::StructInitializerSized);
906+
adt_ty
907+
}
847908
}

src/librustc_typeck/check/mod.rs

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -3864,66 +3864,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38643864
}
38653865
}
38663866

3867-
fn check_expr_struct(
3868-
&self,
3869-
expr: &hir::Expr,
3870-
expected: Expectation<'tcx>,
3871-
qpath: &QPath,
3872-
fields: &'tcx [hir::Field],
3873-
base_expr: &'tcx Option<P<hir::Expr>>,
3874-
) -> Ty<'tcx> {
3875-
// Find the relevant variant
3876-
let (variant, adt_ty) =
3877-
if let Some(variant_ty) = self.check_struct_path(qpath, expr.hir_id) {
3878-
variant_ty
3879-
} else {
3880-
self.check_struct_fields_on_error(fields, base_expr);
3881-
return self.tcx.types.err;
3882-
};
3883-
3884-
let path_span = match *qpath {
3885-
QPath::Resolved(_, ref path) => path.span,
3886-
QPath::TypeRelative(ref qself, _) => qself.span
3887-
};
3888-
3889-
// Prohibit struct expressions when non-exhaustive flag is set.
3890-
let adt = adt_ty.ty_adt_def().expect("`check_struct_path` returned non-ADT type");
3891-
if !adt.did.is_local() && variant.is_field_list_non_exhaustive() {
3892-
span_err!(self.tcx.sess, expr.span, E0639,
3893-
"cannot create non-exhaustive {} using struct expression",
3894-
adt.variant_descr());
3895-
}
3896-
3897-
let error_happened = self.check_expr_struct_fields(adt_ty, expected, expr.hir_id, path_span,
3898-
variant, fields, base_expr.is_none());
3899-
if let &Some(ref base_expr) = base_expr {
3900-
// If check_expr_struct_fields hit an error, do not attempt to populate
3901-
// the fields with the base_expr. This could cause us to hit errors later
3902-
// when certain fields are assumed to exist that in fact do not.
3903-
if !error_happened {
3904-
self.check_expr_has_type_or_error(base_expr, adt_ty);
3905-
match adt_ty.sty {
3906-
ty::Adt(adt, substs) if adt.is_struct() => {
3907-
let fru_field_types = adt.non_enum_variant().fields.iter().map(|f| {
3908-
self.normalize_associated_types_in(expr.span, &f.ty(self.tcx, substs))
3909-
}).collect();
3910-
3911-
self.tables
3912-
.borrow_mut()
3913-
.fru_field_types_mut()
3914-
.insert(expr.hir_id, fru_field_types);
3915-
}
3916-
_ => {
3917-
span_err!(self.tcx.sess, base_expr.span, E0436,
3918-
"functional record update syntax requires a struct");
3919-
}
3920-
}
3921-
}
3922-
}
3923-
self.require_type_is_sized(adt_ty, expr.span, traits::StructInitializerSized);
3924-
adt_ty
3925-
}
3926-
39273867
/// Invariant:
39283868
/// If an expression has any sub-expressions that result in a type error,
39293869
/// inspecting that expression's type with `ty.references_error()` will return

0 commit comments

Comments
 (0)