From 141f5a7558289acb6c7aaf9c6500eb9f6dbeec1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 1 Sep 2019 11:20:33 -0700 Subject: [PATCH] review comments --- src/librustc/ty/context.rs | 16 +---- src/librustc_typeck/check/expr.rs | 104 +++++++++++++++++------------- 2 files changed, 62 insertions(+), 58 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index f355e231914d..17c9e520bcea 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2403,20 +2403,8 @@ impl<'tcx> TyCtxt<'tcx> { } #[inline] - pub fn mk_pin(self, ty: Ty<'tcx>) -> Ty<'tcx> { - let def_id = self.require_lang_item(lang_items::PinTypeLangItem, None); - self.mk_generic_adt(def_id, ty) - } - - #[inline] - pub fn mk_rc(self, ty: Ty<'tcx>) -> Ty<'tcx> { - let def_id = self.require_lang_item(lang_items::Rc, None); - self.mk_generic_adt(def_id, ty) - } - - #[inline] - pub fn mk_arc(self, ty: Ty<'tcx>) -> Ty<'tcx> { - let def_id = self.require_lang_item(lang_items::Arc, None); + pub fn mk_lang_item(self, ty: Ty<'tcx>, item: lang_items::LangItem) -> Ty<'tcx> { + let def_id = self.require_lang_item(item, None); self.mk_generic_adt(def_id, ty) } diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index efff8bcdacbc..fbaa9904d830 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -12,7 +12,7 @@ use crate::check::fatally_break_rust; use crate::check::report_unexpected_variant_res; use crate::check::Needs; use crate::check::TupleArgumentsFlag::DontTupleArguments; -use crate::check::method::{probe, SelfSource}; +use crate::check::method::{probe, SelfSource, MethodError}; use crate::util::common::ErrorReported; use crate::util::nodemap::FxHashMap; use crate::astconv::AstConv as _; @@ -29,6 +29,7 @@ use rustc::hir::def::{CtorKind, Res, DefKind}; use rustc::hir::ptr::P; use rustc::infer; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc::middle::lang_items; use rustc::mir::interpret::GlobalId; use rustc::ty; use rustc::ty::adjustment::{ @@ -775,6 +776,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // no need to check for bot/err -- callee does that let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t); + let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr) { + Ok(method) => { + self.write_method_call(expr.hir_id, method); + Ok(method) + } + Err(error) => { + if segment.ident.name != kw::Invalid { + self.report_extended_method_error(segment, span, args, rcvr_t, error); + } + Err(()) + } + }; + + // Call the generic checker. + self.check_method_argument_types( + span, + expr.span, + method, + &args[1..], + DontTupleArguments, + expected, + ) + } + + fn report_extended_method_error( + &self, + segment: &hir::PathSegment, + span: Span, + args: &'tcx [hir::Expr], + rcvr_t: Ty<'tcx>, + error: MethodError<'tcx> + ) { + let rcvr = &args[0]; let try_alt_rcvr = |err: &mut DiagnosticBuilder<'_>, new_rcvr_t| { if let Ok(pick) = self.lookup_probe( span, @@ -790,50 +824,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; - let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr) { - Ok(method) => { - self.write_method_call(expr.hir_id, method); - Ok(method) - } - Err(error) => { - if segment.ident.name != kw::Invalid { - if let Some(mut err) = self.report_method_error( - span, - rcvr_t, - segment.ident, - SelfSource::MethodCall(rcvr), - error, - Some(args), - ) { - if let ty::Adt(..) = rcvr_t.sty { - // Try alternative arbitrary self types that could fulfill this call. - // FIXME: probe for all types that *could* be arbitrary self-types, not - // just this whitelist. - let box_rcvr_t = self.tcx.mk_box(rcvr_t); - try_alt_rcvr(&mut err, box_rcvr_t); - let pin_rcvr_t = self.tcx.mk_pin(rcvr_t); - try_alt_rcvr(&mut err, pin_rcvr_t); - let arc_rcvr_t = self.tcx.mk_arc(rcvr_t); - try_alt_rcvr(&mut err, arc_rcvr_t); - let rc_rcvr_t = self.tcx.mk_rc(rcvr_t); - try_alt_rcvr(&mut err, rc_rcvr_t); - } - err.emit(); - } - } - Err(()) - } - }; - - // Call the generic checker. - self.check_method_argument_types( + if let Some(mut err) = self.report_method_error( span, - expr.span, - method, - &args[1..], - DontTupleArguments, - expected, - ) + rcvr_t, + segment.ident, + SelfSource::MethodCall(rcvr), + error, + Some(args), + ) { + if let ty::Adt(..) = rcvr_t.sty { + // Try alternative arbitrary self types that could fulfill this call. + // FIXME: probe for all types that *could* be arbitrary self-types, not + // just this whitelist. + let box_rcvr_t = self.tcx.mk_box(rcvr_t); + try_alt_rcvr(&mut err, box_rcvr_t); + let pin_rcvr_t = self.tcx.mk_lang_item( + rcvr_t, + lang_items::PinTypeLangItem, + ); + try_alt_rcvr(&mut err, pin_rcvr_t); + let arc_rcvr_t = self.tcx.mk_lang_item(rcvr_t, lang_items::Arc); + try_alt_rcvr(&mut err, arc_rcvr_t); + let rc_rcvr_t = self.tcx.mk_lang_item(rcvr_t, lang_items::Rc); + try_alt_rcvr(&mut err, rc_rcvr_t); + } + err.emit(); + } } fn check_expr_cast(