use rustc_front::intravisit::{self, Visitor};
use rustc_front::hir;
-use rustc_front::hir::Visibility;
+use rustc_front::hir::{Visibility, PatKind};
use rustc_front::print::pprust;
use rustc_back::slice;
// Add pattern bindings.
fn visit_pat(&mut self, p: &'tcx hir::Pat) {
- if let hir::PatIdent(_, ref path1, _) = p.node {
+ if let PatKind::Ident(_, ref path1, _) = p.node {
if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map.borrow(), p) {
let var_ty = self.assign(p.span, p.id, None);
check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
return;
}
- let (adt, variant) = match fcx.def_struct_variant(def, path.span) {
- Some((adt, variant)) => (adt, variant),
+ let variant = match fcx.def_struct_variant(def, path.span) {
+ Some((_, variant)) => variant,
None => {
span_err!(fcx.tcx().sess, path.span, E0071,
"`{}` does not name a structure",
check_expr_struct_fields(fcx, expr_ty, expr.span, variant, fields,
base_expr.is_none());
-
if let &Some(ref base_expr) = base_expr {
check_expr_has_type(fcx, base_expr, expr_ty);
- if adt.adt_kind() == ty::AdtKind::Enum {
- span_err!(tcx.sess, base_expr.span, E0436,
- "functional record update syntax requires a struct");
+ match expr_ty.sty {
+ ty::TyStruct(adt, substs) => {
+ fcx.inh.tables.borrow_mut().fru_field_types.insert(
+ expr.id,
+ adt.struct_variant().fields.iter().map(|f| {
+ fcx.normalize_associated_types_in(
+ expr.span, &f.ty(tcx, substs)
+ )
+ }).collect()
+ );
+ }
+ _ => {
+ span_err!(tcx.sess, base_expr.span, E0436,
+ "functional record update syntax requires a struct");
+ }
}
}
}
}
}
}
- hir::ExprRange(ref start, ref end) => {
- let t_start = start.as_ref().map(|e| {
- check_expr(fcx, &e);
- fcx.expr_ty(&e)
- });
- let t_end = end.as_ref().map(|e| {
- check_expr(fcx, &e);
- fcx.expr_ty(&e)
- });
-
- let idx_type = match (t_start, t_end) {
- (Some(ty), None) | (None, Some(ty)) => {
- Some(ty)
- }
- (Some(t_start), Some(t_end)) if (t_start.references_error() ||
- t_end.references_error()) => {
- Some(fcx.tcx().types.err)
- }
- (Some(t_start), Some(t_end)) => {
- Some(infer::common_supertype(fcx.infcx(),
- TypeOrigin::RangeExpression(expr.span),
- true,
- t_start,
- t_end))
- }
- _ => None
- };
-
- // Note that we don't check the type of start/end satisfy any
- // bounds because right now the range structs do not have any. If we add
- // some bounds, then we'll need to check `t_start` against them here.
-
- let range_type = match idx_type {
- Some(idx_type) if idx_type.references_error() => {
- fcx.tcx().types.err
- }
- Some(idx_type) => {
- // Find the did from the appropriate lang item.
- let did = match (start, end) {
- (&Some(_), &Some(_)) => tcx.lang_items.range_struct(),
- (&Some(_), &None) => tcx.lang_items.range_from_struct(),
- (&None, &Some(_)) => tcx.lang_items.range_to_struct(),
- (&None, &None) => {
- tcx.sess.span_bug(expr.span, "full range should be dealt with above")
- }
- };
-
- if let Some(did) = did {
- let def = tcx.lookup_adt_def(did);
- let predicates = tcx.lookup_predicates(did);
- let substs = Substs::new_type(vec![idx_type], vec![]);
- let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
- fcx.add_obligations_for_parameters(
- traits::ObligationCause::new(expr.span,
- fcx.body_id,
- traits::ItemObligation(did)),
- &bounds);
-
- tcx.mk_struct(def, tcx.mk_substs(substs))
- } else {
- span_err!(tcx.sess, expr.span, E0236, "no lang item for range syntax");
- fcx.tcx().types.err
- }
- }
- None => {
- // Neither start nor end => RangeFull
- if let Some(did) = tcx.lang_items.range_full_struct() {
- tcx.mk_struct(
- tcx.lookup_adt_def(did),
- tcx.mk_substs(Substs::empty())
- )
- } else {
- span_err!(tcx.sess, expr.span, E0237, "no lang item for range syntax");
- fcx.tcx().types.err
- }
- }
- };
-
- fcx.write_ty(id, range_type);
- }
-
}
debug!("type of expr({}) {} is...", expr.id,