review comments
This commit is contained in:
parent
a9ce33c059
commit
141f5a7558
2 changed files with 62 additions and 58 deletions
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue