Skip to content

Commit a65ced5

Browse files
committed
rustc: avoid using MethodCallee's signature where possible.
1 parent 22510f3 commit a65ced5

File tree

12 files changed

+147
-163
lines changed

12 files changed

+147
-163
lines changed

src/librustc/cfg/construct.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -412,15 +412,10 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
412412
pred: CFGIndex,
413413
func_or_rcvr: &hir::Expr,
414414
args: I) -> CFGIndex {
415-
let fn_ty = match self.tables.method_map.get(&call_expr.id) {
416-
Some(method) => method.ty,
417-
None => self.tables.expr_ty_adjusted(func_or_rcvr),
418-
};
419-
420415
let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);
421416
let ret = self.straightline(call_expr, func_or_rcvr_exit, args);
422417
// FIXME(canndrew): This is_never should probably be an is_uninhabited.
423-
if fn_ty.fn_ret().0.is_never() {
418+
if self.tables.expr_ty(call_expr).is_never() {
424419
self.add_unreachable_node()
425420
} else {
426421
ret

src/librustc/middle/effect.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,11 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
173173
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
174174
match expr.node {
175175
hir::ExprMethodCall(..) => {
176-
let method_sig = self.tables.method_map[&expr.id].sig;
176+
let method = self.tables.method_map[&expr.id];
177+
let base_type = self.tcx.type_of(method.def_id);
177178
debug!("effect: method call case, base type is {:?}",
178-
method_sig);
179-
if method_sig.unsafety == hir::Unsafety::Unsafe {
179+
base_type);
180+
if type_is_unsafe_function(base_type) {
180181
self.require_unsafe(expr.span,
181182
"invocation of unsafe method")
182183
}

src/librustc/middle/expr_use_visitor.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,8 +761,10 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
761761
let bk = ty::BorrowKind::from_mutbl(m);
762762
self.delegate.borrow(expr.id, expr.span, cmt.clone(),
763763
r, bk, AutoRef);
764+
cmt = self.mc.cat_overloaded_autoderef(expr, method)?;
765+
} else {
766+
cmt = self.mc.cat_deref(expr, cmt, false)?;
764767
}
765-
cmt = self.mc.cat_deref(expr, cmt, overloaded)?;
766768
}
767769
Ok(cmt)
768770
}

src/librustc/middle/liveness.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,9 +1072,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
10721072

10731073
hir::ExprCall(ref f, ref args) => {
10741074
// FIXME(canndrew): This is_never should really be an is_uninhabited
1075-
let diverges = !self.tables.is_method_call(expr.id) &&
1076-
self.tables.expr_ty_adjusted(&f).fn_sig().output().0.is_never();
1077-
let succ = if diverges {
1075+
let succ = if self.tables.expr_ty(expr).is_never() {
10781076
self.s.exit_ln
10791077
} else {
10801078
succ
@@ -1084,9 +1082,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
10841082
}
10851083

10861084
hir::ExprMethodCall(.., ref args) => {
1087-
let ret_ty = self.tables.method_map[&expr.id].sig.output();
10881085
// FIXME(canndrew): This is_never should really be an is_uninhabited
1089-
let succ = if ret_ty.is_never() {
1086+
let succ = if self.tables.expr_ty(expr).is_never() {
10901087
self.s.exit_ln
10911088
} else {
10921089
succ

src/librustc/middle/mem_categorization.rs

Lines changed: 89 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@
6363
pub use self::PointerKind::*;
6464
pub use self::InteriorKind::*;
6565
pub use self::FieldName::*;
66-
pub use self::ElementKind::*;
6766
pub use self::MutabilityCategory::*;
6867
pub use self::AliasableReason::*;
6968
pub use self::Note::*;
@@ -129,7 +128,7 @@ pub enum PointerKind<'tcx> {
129128
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
130129
pub enum InteriorKind {
131130
InteriorField(FieldName),
132-
InteriorElement(InteriorOffsetKind, ElementKind),
131+
InteriorElement(InteriorOffsetKind),
133132
}
134133

135134
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
@@ -144,12 +143,6 @@ pub enum InteriorOffsetKind {
144143
Pattern, // e.g. `fn foo([_, a, _, _]: [A; 4]) { ... }`
145144
}
146145

147-
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
148-
pub enum ElementKind {
149-
VecElement,
150-
OtherElement,
151-
}
152-
153146
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
154147
pub enum MutabilityCategory {
155148
McImmutable, // Immutable.
@@ -492,7 +485,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
492485
debug!("cat_expr: autoderefs={:?}, cmt={:?}",
493486
autoderefs, cmt);
494487
for &overloaded in autoderefs {
495-
cmt = self.cat_deref(expr, cmt, overloaded)?;
488+
if let Some(method) = overloaded {
489+
cmt = self.cat_overloaded_autoderef(expr, method)?;
490+
} else {
491+
cmt = self.cat_deref(expr, cmt, false)?;
492+
}
496493
}
497494
return Ok(cmt);
498495
}
@@ -518,10 +515,12 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
518515
let expr_ty = self.expr_ty(expr)?;
519516
match expr.node {
520517
hir::ExprUnary(hir::UnDeref, ref e_base) => {
521-
let base_cmt = self.cat_expr(&e_base)?;
522-
let method = self.infcx.tables.borrow().method_map
523-
.get(&expr.id).cloned();
524-
self.cat_deref(expr, base_cmt, method)
518+
if self.infcx.tables.borrow().is_method_call(expr.id) {
519+
self.cat_overloaded_lvalue(expr, e_base, false)
520+
} else {
521+
let base_cmt = self.cat_expr(&e_base)?;
522+
self.cat_deref(expr, base_cmt, false)
523+
}
525524
}
526525

527526
hir::ExprField(ref base, f_name) => {
@@ -539,33 +538,16 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
539538
}
540539

541540
hir::ExprIndex(ref base, _) => {
542-
let method = self.infcx.tables.borrow().method_map.get(&expr.id()).cloned();
543-
match method {
544-
Some(method) => {
545-
// If this is an index implemented by a method call, then it
546-
// will include an implicit deref of the result.
547-
let ret_ty = self.overloaded_method_return_ty(method);
548-
549-
// The index method always returns an `&T`, so
550-
// dereference it to find the result type.
551-
let elem_ty = match ret_ty.sty {
552-
ty::TyRef(_, mt) => mt.ty,
553-
_ => {
554-
debug!("cat_expr_unadjusted: return type of overloaded index is {:?}?",
555-
ret_ty);
556-
return Err(());
557-
}
558-
};
559-
560-
// The call to index() returns a `&T` value, which
561-
// is an rvalue. That is what we will be
562-
// dereferencing.
563-
let base_cmt = self.cat_rvalue_node(expr.id(), expr.span(), ret_ty);
564-
Ok(self.cat_deref_common(expr, base_cmt, elem_ty, true))
565-
}
566-
None => {
567-
self.cat_index(expr, self.cat_expr(&base)?, InteriorOffsetKind::Index)
568-
}
541+
if self.infcx.tables.borrow().is_method_call(expr.id()) {
542+
// If this is an index implemented by a method call, then it
543+
// will include an implicit deref of the result.
544+
// The call to index() returns a `&T` value, which
545+
// is an rvalue. That is what we will be
546+
// dereferencing.
547+
self.cat_overloaded_lvalue(expr, base, true)
548+
} else {
549+
let base_cmt = self.cat_expr(&base)?;
550+
self.cat_index(expr, base_cmt, expr_ty, InteriorOffsetKind::Index)
569551
}
570552
}
571553

@@ -924,50 +906,71 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
924906
ret
925907
}
926908

909+
fn cat_overloaded_lvalue(&self,
910+
expr: &hir::Expr,
911+
base: &hir::Expr,
912+
implicit: bool)
913+
-> McResult<cmt<'tcx>> {
914+
debug!("cat_overloaded_lvalue: implicit={}", implicit);
915+
916+
// Reconstruct the output assuming it's a reference with the
917+
// same region and mutability as the receiver. This holds for
918+
// `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`.
919+
let lvalue_ty = self.expr_ty(expr)?;
920+
let base_ty = self.expr_ty_adjusted(base)?;
921+
922+
let (region, mutbl) = match base_ty.sty {
923+
ty::TyRef(region, mt) => (region, mt.mutbl),
924+
_ => {
925+
span_bug!(expr.span, "cat_overloaded_lvalue: base is not a reference")
926+
}
927+
};
928+
let ref_ty = self.tcx().mk_ref(region, ty::TypeAndMut {
929+
ty: lvalue_ty,
930+
mutbl,
931+
});
932+
933+
let base_cmt = self.cat_rvalue_node(expr.id, expr.span, ref_ty);
934+
self.cat_deref(expr, base_cmt, implicit)
935+
}
936+
937+
pub fn cat_overloaded_autoderef(&self,
938+
expr: &hir::Expr,
939+
method: ty::MethodCallee<'tcx>)
940+
-> McResult<cmt<'tcx>> {
941+
debug!("cat_overloaded_autoderef: method={:?}", method);
942+
943+
let ref_ty = method.sig.output();
944+
let ref_ty = self.infcx.resolve_type_vars_if_possible(&ref_ty);
945+
let base_cmt = self.cat_rvalue_node(expr.id, expr.span, ref_ty);
946+
self.cat_deref(expr, base_cmt, false)
947+
}
948+
927949
pub fn cat_deref<N:ast_node>(&self,
928950
node: &N,
929951
base_cmt: cmt<'tcx>,
930-
overloaded: Option<ty::MethodCallee<'tcx>>)
952+
implicit: bool)
931953
-> McResult<cmt<'tcx>> {
932-
debug!("cat_deref: overloaded={:?}", overloaded);
954+
debug!("cat_deref: base_cmt={:?}", base_cmt);
933955

934-
let base_cmt = match overloaded {
935-
Some(method) => {
936-
let ref_ty = self.overloaded_method_return_ty(method);
937-
self.cat_rvalue_node(node.id(), node.span(), ref_ty)
938-
}
939-
None => base_cmt
940-
};
941956
let base_cmt_ty = base_cmt.ty;
942-
match base_cmt_ty.builtin_deref(true, ty::NoPreference) {
943-
Some(mt) => {
944-
let ret = self.cat_deref_common(node, base_cmt, mt.ty, false);
945-
debug!("cat_deref ret {:?}", ret);
946-
Ok(ret)
947-
}
957+
let deref_ty = match base_cmt_ty.builtin_deref(true, ty::NoPreference) {
958+
Some(mt) => mt.ty,
948959
None => {
949960
debug!("Explicit deref of non-derefable type: {:?}",
950961
base_cmt_ty);
951962
return Err(());
952963
}
953-
}
954-
}
964+
};
955965

956-
fn cat_deref_common<N:ast_node>(&self,
957-
node: &N,
958-
base_cmt: cmt<'tcx>,
959-
deref_ty: Ty<'tcx>,
960-
implicit: bool)
961-
-> cmt<'tcx>
962-
{
963966
let ptr = match base_cmt.ty.sty {
964967
ty::TyAdt(def, ..) if def.is_box() => Unique,
965968
ty::TyRawPtr(ref mt) => UnsafePtr(mt.mutbl),
966969
ty::TyRef(r, mt) => {
967970
let bk = ty::BorrowKind::from_mutbl(mt.mutbl);
968971
if implicit { Implicit(bk, r) } else { BorrowedPtr(bk, r) }
969972
}
970-
ref ty => bug!("unexpected type in cat_deref_common: {:?}", ty)
973+
ref ty => bug!("unexpected type in cat_deref: {:?}", ty)
971974
};
972975
let ret = Rc::new(cmt_ {
973976
id: node.id(),
@@ -978,15 +981,16 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
978981
ty: deref_ty,
979982
note: NoteNone
980983
});
981-
debug!("cat_deref_common ret {:?}", ret);
982-
ret
984+
debug!("cat_deref ret {:?}", ret);
985+
Ok(ret)
983986
}
984987

985-
pub fn cat_index<N:ast_node>(&self,
986-
elt: &N,
987-
mut base_cmt: cmt<'tcx>,
988-
context: InteriorOffsetKind)
989-
-> McResult<cmt<'tcx>> {
988+
fn cat_index<N:ast_node>(&self,
989+
elt: &N,
990+
base_cmt: cmt<'tcx>,
991+
element_ty: Ty<'tcx>,
992+
context: InteriorOffsetKind)
993+
-> McResult<cmt<'tcx>> {
990994
//! Creates a cmt for an indexing operation (`[]`).
991995
//!
992996
//! One subtle aspect of indexing that may not be
@@ -1004,29 +1008,9 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
10041008
//! - `elt`: the AST node being indexed
10051009
//! - `base_cmt`: the cmt of `elt`
10061010
1007-
let method = self.infcx.tables.borrow().method_map.get(&elt.id()).cloned();
1008-
let (element_ty, element_kind) = match method {
1009-
Some(method) => {
1010-
let ref_ty = self.overloaded_method_return_ty(method);
1011-
base_cmt = self.cat_rvalue_node(elt.id(), elt.span(), ref_ty);
1012-
1013-
(ref_ty.builtin_deref(false, ty::NoPreference).unwrap().ty,
1014-
ElementKind::OtherElement)
1015-
}
1016-
None => {
1017-
match base_cmt.ty.builtin_index() {
1018-
Some(ty) => (ty, ElementKind::VecElement),
1019-
None => {
1020-
debug!("Explicit index of non-indexable type {:?}", base_cmt);
1021-
return Err(());
1022-
}
1023-
}
1024-
}
1025-
};
1026-
1027-
let interior_elem = InteriorElement(context, element_kind);
1011+
let interior_elem = InteriorElement(context);
10281012
let ret =
1029-
self.cat_imm_interior(elt, base_cmt.clone(), element_ty, interior_elem);
1013+
self.cat_imm_interior(elt, base_cmt, element_ty, interior_elem);
10301014
debug!("cat_index ret {:?}", ret);
10311015
return Ok(ret);
10321016
}
@@ -1216,15 +1200,20 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
12161200
// box p1, &p1, &mut p1. we can ignore the mutability of
12171201
// PatKind::Ref since that information is already contained
12181202
// in the type.
1219-
let method = self.infcx.tables.borrow().method_map
1220-
.get(&pat.id).cloned();
1221-
let subcmt = self.cat_deref(pat, cmt, method)?;
1203+
let subcmt = self.cat_deref(pat, cmt, false)?;
12221204
self.cat_pattern_(subcmt, &subpat, op)?;
12231205
}
12241206

12251207
PatKind::Slice(ref before, ref slice, ref after) => {
1208+
let element_ty = match cmt.ty.builtin_index() {
1209+
Some(ty) => ty,
1210+
None => {
1211+
debug!("Explicit index of non-indexable type {:?}", cmt);
1212+
return Err(());
1213+
}
1214+
};
12261215
let context = InteriorOffsetKind::Pattern;
1227-
let elt_cmt = self.cat_index(pat, cmt, context)?;
1216+
let elt_cmt = self.cat_index(pat, cmt, element_ty, context)?;
12281217
for before_pat in before {
12291218
self.cat_pattern_(elt_cmt.clone(), &before_pat, op)?;
12301219
}
@@ -1244,16 +1233,6 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
12441233

12451234
Ok(())
12461235
}
1247-
1248-
fn overloaded_method_return_ty(&self,
1249-
method: ty::MethodCallee<'tcx>)
1250-
-> Ty<'tcx>
1251-
{
1252-
// When we process an overloaded `*` or `[]` etc, we often
1253-
// need to extract the return type of the method.
1254-
let ret_ty = method.sig.output();
1255-
self.infcx.resolve_type_vars_if_possible(&ret_ty)
1256-
}
12571236
}
12581237

12591238
#[derive(Clone, Debug)]
@@ -1401,16 +1380,10 @@ impl<'tcx> cmt_<'tcx> {
14011380
Categorization::Interior(_, InteriorField(PositionalField(_))) => {
14021381
"anonymous field".to_string()
14031382
}
1404-
Categorization::Interior(_, InteriorElement(InteriorOffsetKind::Index,
1405-
VecElement)) |
1406-
Categorization::Interior(_, InteriorElement(InteriorOffsetKind::Index,
1407-
OtherElement)) => {
1383+
Categorization::Interior(_, InteriorElement(InteriorOffsetKind::Index)) => {
14081384
"indexed content".to_string()
14091385
}
1410-
Categorization::Interior(_, InteriorElement(InteriorOffsetKind::Pattern,
1411-
VecElement)) |
1412-
Categorization::Interior(_, InteriorElement(InteriorOffsetKind::Pattern,
1413-
OtherElement)) => {
1386+
Categorization::Interior(_, InteriorElement(InteriorOffsetKind::Pattern)) => {
14141387
"pattern-bound indexed content".to_string()
14151388
}
14161389
Categorization::Upvar(ref var) => {

src/librustc_borrowck/borrowck/check_loans.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
805805
self.check_if_assigned_path_is_moved(id, span,
806806
use_kind, lp_base);
807807
}
808-
LpExtend(ref lp_base, _, LpInterior(_, InteriorElement(..))) |
808+
LpExtend(ref lp_base, _, LpInterior(_, InteriorElement)) |
809809
LpExtend(ref lp_base, _, LpDeref(_)) => {
810810
// assigning to `P[i]` requires `P` is initialized
811811
// assigning to `(*P)` requires `P` is initialized

0 commit comments

Comments
 (0)