Skip to content

Commit b4a4e71

Browse files
committed
typeck/pat.rs: extract check_pat_ref.
1 parent 3de221a commit b4a4e71

File tree

1 file changed

+55
-44
lines changed
  • src/librustc_typeck/check

1 file changed

+55
-44
lines changed

src/librustc_typeck/check/pat.rs

Lines changed: 55 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -111,50 +111,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
111111
self.check_pat_box(pat.span, inner, expected, def_bm, discrim_span)
112112
}
113113
PatKind::Ref(ref inner, mutbl) => {
114-
let expected = self.shallow_resolve(expected);
115-
if self.check_dereferencable(pat.span, expected, &inner) {
116-
// `demand::subtype` would be good enough, but using
117-
// `eqtype` turns out to be equally general. See (*)
118-
// below for details.
119-
120-
// Take region, inner-type from expected type if we
121-
// can, to avoid creating needless variables. This
122-
// also helps with the bad interactions of the given
123-
// hack detailed in (*) below.
124-
debug!("check_pat_walk: expected={:?}", expected);
125-
let (rptr_ty, inner_ty) = match expected.sty {
126-
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => {
127-
(expected, r_ty)
128-
}
129-
_ => {
130-
let inner_ty = self.next_ty_var(
131-
TypeVariableOrigin {
132-
kind: TypeVariableOriginKind::TypeInference,
133-
span: inner.span,
134-
}
135-
);
136-
let mt = ty::TypeAndMut { ty: inner_ty, mutbl: mutbl };
137-
let region = self.next_region_var(infer::PatternRegion(pat.span));
138-
let rptr_ty = tcx.mk_ref(region, mt);
139-
debug!("check_pat_walk: demanding {:?} = {:?}", expected, rptr_ty);
140-
let err = self.demand_eqtype_diag(pat.span, expected, rptr_ty);
141-
142-
// Look for a case like `fn foo(&foo: u32)` and suggest
143-
// `fn foo(foo: &u32)`
144-
if let Some(mut err) = err {
145-
self.borrow_pat_suggestion(&mut err, &pat, &inner, &expected);
146-
err.emit();
147-
}
148-
(rptr_ty, inner_ty)
149-
}
150-
};
151-
152-
self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
153-
rptr_ty
154-
} else {
155-
self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
156-
tcx.types.err
157-
}
114+
self.check_pat_ref(pat, inner, mutbl, expected, def_bm, discrim_span)
158115
}
159116
PatKind::Slice(ref before, ref slice, ref after) => {
160117
let expected_ty = self.structurally_resolved_type(pat.span, expected);
@@ -1059,4 +1016,58 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10591016
tcx.types.err
10601017
}
10611018
}
1019+
1020+
fn check_pat_ref(
1021+
&self,
1022+
pat: &hir::Pat,
1023+
inner: &'tcx hir::Pat,
1024+
mutbl: hir::Mutability,
1025+
expected: Ty<'tcx>,
1026+
def_bm: ty::BindingMode,
1027+
discrim_span: Option<Span>,
1028+
) -> Ty<'tcx> {
1029+
let tcx = self.tcx;
1030+
let expected = self.shallow_resolve(expected);
1031+
if self.check_dereferencable(pat.span, expected, &inner) {
1032+
// `demand::subtype` would be good enough, but using `eqtype` turns
1033+
// out to be equally general. See (*) below for details.
1034+
1035+
// Take region, inner-type from expected type if we can,
1036+
// to avoid creating needless variables. This also helps with
1037+
// the bad interactions of the given hack detailed in (*) below.
1038+
debug!("check_pat_ref: expected={:?}", expected);
1039+
let (rptr_ty, inner_ty) = match expected.sty {
1040+
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => {
1041+
(expected, r_ty)
1042+
}
1043+
_ => {
1044+
let inner_ty = self.next_ty_var(
1045+
TypeVariableOrigin {
1046+
kind: TypeVariableOriginKind::TypeInference,
1047+
span: inner.span,
1048+
}
1049+
);
1050+
let mt = ty::TypeAndMut { ty: inner_ty, mutbl };
1051+
let region = self.next_region_var(infer::PatternRegion(pat.span));
1052+
let rptr_ty = tcx.mk_ref(region, mt);
1053+
debug!("check_pat_ref: demanding {:?} = {:?}", expected, rptr_ty);
1054+
let err = self.demand_eqtype_diag(pat.span, expected, rptr_ty);
1055+
1056+
// Look for a case like `fn foo(&foo: u32)` and suggest
1057+
// `fn foo(foo: &u32)`
1058+
if let Some(mut err) = err {
1059+
self.borrow_pat_suggestion(&mut err, &pat, &inner, &expected);
1060+
err.emit();
1061+
}
1062+
(rptr_ty, inner_ty)
1063+
}
1064+
};
1065+
1066+
self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
1067+
rptr_ty
1068+
} else {
1069+
self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
1070+
tcx.types.err
1071+
}
1072+
}
10621073
}

0 commit comments

Comments
 (0)