Rollup merge of #106173 - compiler-errors:deduplicate-op-methods, r=jackh726
Deduplicate `op` methods There are some operator-checking flavored methods in `FnCtxt` that can be deduplicated.
This commit is contained in:
commit
c991c243b7
4 changed files with 52 additions and 159 deletions
|
@ -241,7 +241,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(ok) = self.lookup_method_in_trait(
|
if let Some(ok) = self.lookup_method_in_trait(
|
||||||
call_expr.span,
|
self.misc(call_expr.span),
|
||||||
method_name,
|
method_name,
|
||||||
trait_def_id,
|
trait_def_id,
|
||||||
adjusted_ty,
|
adjusted_ty,
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub use self::suggest::SelfSource;
|
||||||
pub use self::MethodError::*;
|
pub use self::MethodError::*;
|
||||||
|
|
||||||
use crate::errors::OpMethodGenericParams;
|
use crate::errors::OpMethodGenericParams;
|
||||||
use crate::{Expectation, FnCtxt};
|
use crate::FnCtxt;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_errors::{Applicability, Diagnostic};
|
use rustc_errors::{Applicability, Diagnostic};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
@ -264,7 +264,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
pub(super) fn obligation_for_method(
|
pub(super) fn obligation_for_method(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
cause: ObligationCause<'tcx>,
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
self_ty: Ty<'tcx>,
|
self_ty: Ty<'tcx>,
|
||||||
opt_input_types: Option<&[Ty<'tcx>]>,
|
opt_input_types: Option<&[Ty<'tcx>]>,
|
||||||
|
@ -282,71 +282,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.var_for_def(span, param)
|
self.var_for_def(cause.span, param)
|
||||||
});
|
});
|
||||||
|
|
||||||
let trait_ref = self.tcx.mk_trait_ref(trait_def_id, substs);
|
let trait_ref = self.tcx.mk_trait_ref(trait_def_id, substs);
|
||||||
|
|
||||||
// Construct an obligation
|
// Construct an obligation
|
||||||
let poly_trait_ref = ty::Binder::dummy(trait_ref);
|
let poly_trait_ref = ty::Binder::dummy(trait_ref);
|
||||||
(
|
|
||||||
traits::Obligation::misc(
|
|
||||||
self.tcx,
|
|
||||||
span,
|
|
||||||
self.body_id,
|
|
||||||
self.param_env,
|
|
||||||
poly_trait_ref.without_const(),
|
|
||||||
),
|
|
||||||
substs,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn obligation_for_op_method(
|
|
||||||
&self,
|
|
||||||
span: Span,
|
|
||||||
trait_def_id: DefId,
|
|
||||||
self_ty: Ty<'tcx>,
|
|
||||||
opt_input_type: Option<Ty<'tcx>>,
|
|
||||||
opt_input_expr: Option<&'tcx hir::Expr<'tcx>>,
|
|
||||||
expected: Expectation<'tcx>,
|
|
||||||
) -> (traits::Obligation<'tcx, ty::Predicate<'tcx>>, &'tcx ty::List<ty::subst::GenericArg<'tcx>>)
|
|
||||||
{
|
|
||||||
// Construct a trait-reference `self_ty : Trait<input_tys>`
|
|
||||||
let substs = InternalSubsts::for_item(self.tcx, trait_def_id, |param, _| {
|
|
||||||
match param.kind {
|
|
||||||
GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => {}
|
|
||||||
GenericParamDefKind::Type { .. } => {
|
|
||||||
if param.index == 0 {
|
|
||||||
return self_ty.into();
|
|
||||||
} else if let Some(input_type) = opt_input_type {
|
|
||||||
return input_type.into();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.var_for_def(span, param)
|
|
||||||
});
|
|
||||||
|
|
||||||
let trait_ref = self.tcx.mk_trait_ref(trait_def_id, substs);
|
|
||||||
|
|
||||||
// Construct an obligation
|
|
||||||
let poly_trait_ref = ty::Binder::dummy(trait_ref);
|
|
||||||
let output_ty = expected.only_has_type(self).and_then(|ty| (!ty.needs_infer()).then(|| ty));
|
|
||||||
|
|
||||||
(
|
(
|
||||||
traits::Obligation::new(
|
traits::Obligation::new(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
traits::ObligationCause::new(
|
cause,
|
||||||
span,
|
|
||||||
self.body_id,
|
|
||||||
traits::BinOp {
|
|
||||||
rhs_span: opt_input_expr.map(|expr| expr.span),
|
|
||||||
is_lit: opt_input_expr
|
|
||||||
.map_or(false, |expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
|
|
||||||
output_ty,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
self.param_env,
|
self.param_env,
|
||||||
poly_trait_ref,
|
poly_trait_ref.without_const(),
|
||||||
),
|
),
|
||||||
substs,
|
substs,
|
||||||
)
|
)
|
||||||
|
@ -357,55 +305,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
/// In particular, it doesn't really do any probing: it simply constructs
|
/// In particular, it doesn't really do any probing: it simply constructs
|
||||||
/// an obligation for a particular trait with the given self type and checks
|
/// an obligation for a particular trait with the given self type and checks
|
||||||
/// whether that trait is implemented.
|
/// whether that trait is implemented.
|
||||||
#[instrument(level = "debug", skip(self, span))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
pub(super) fn lookup_method_in_trait(
|
pub(super) fn lookup_method_in_trait(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
cause: ObligationCause<'tcx>,
|
||||||
m_name: Ident,
|
m_name: Ident,
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
self_ty: Ty<'tcx>,
|
self_ty: Ty<'tcx>,
|
||||||
opt_input_types: Option<&[Ty<'tcx>]>,
|
opt_input_types: Option<&[Ty<'tcx>]>,
|
||||||
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
|
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
|
||||||
let (obligation, substs) =
|
let (obligation, substs) =
|
||||||
self.obligation_for_method(span, trait_def_id, self_ty, opt_input_types);
|
self.obligation_for_method(cause, trait_def_id, self_ty, opt_input_types);
|
||||||
self.construct_obligation_for_trait(
|
self.construct_obligation_for_trait(m_name, trait_def_id, obligation, substs)
|
||||||
span,
|
|
||||||
m_name,
|
|
||||||
trait_def_id,
|
|
||||||
obligation,
|
|
||||||
substs,
|
|
||||||
None,
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn lookup_op_method_in_trait(
|
|
||||||
&self,
|
|
||||||
span: Span,
|
|
||||||
m_name: Ident,
|
|
||||||
trait_def_id: DefId,
|
|
||||||
self_ty: Ty<'tcx>,
|
|
||||||
opt_input_type: Option<Ty<'tcx>>,
|
|
||||||
opt_input_expr: Option<&'tcx hir::Expr<'tcx>>,
|
|
||||||
expected: Expectation<'tcx>,
|
|
||||||
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
|
|
||||||
let (obligation, substs) = self.obligation_for_op_method(
|
|
||||||
span,
|
|
||||||
trait_def_id,
|
|
||||||
self_ty,
|
|
||||||
opt_input_type,
|
|
||||||
opt_input_expr,
|
|
||||||
expected,
|
|
||||||
);
|
|
||||||
self.construct_obligation_for_trait(
|
|
||||||
span,
|
|
||||||
m_name,
|
|
||||||
trait_def_id,
|
|
||||||
obligation,
|
|
||||||
substs,
|
|
||||||
opt_input_expr,
|
|
||||||
true,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(#18741): it seems likely that we can consolidate some of this
|
// FIXME(#18741): it seems likely that we can consolidate some of this
|
||||||
|
@ -413,13 +324,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// of this method is basically the same as confirmation.
|
// of this method is basically the same as confirmation.
|
||||||
fn construct_obligation_for_trait(
|
fn construct_obligation_for_trait(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
|
||||||
m_name: Ident,
|
m_name: Ident,
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
obligation: traits::PredicateObligation<'tcx>,
|
obligation: traits::PredicateObligation<'tcx>,
|
||||||
substs: &'tcx ty::List<ty::subst::GenericArg<'tcx>>,
|
substs: &'tcx ty::List<ty::subst::GenericArg<'tcx>>,
|
||||||
opt_input_expr: Option<&'tcx hir::Expr<'tcx>>,
|
|
||||||
is_op: bool,
|
|
||||||
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
|
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
|
||||||
debug!(?obligation);
|
debug!(?obligation);
|
||||||
|
|
||||||
|
@ -435,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let Some(method_item) = self.associated_value(trait_def_id, m_name) else {
|
let Some(method_item) = self.associated_value(trait_def_id, m_name) else {
|
||||||
tcx.sess.delay_span_bug(
|
tcx.sess.delay_span_bug(
|
||||||
span,
|
obligation.cause.span,
|
||||||
"operator trait does not have corresponding operator method",
|
"operator trait does not have corresponding operator method",
|
||||||
);
|
);
|
||||||
return None;
|
return None;
|
||||||
|
@ -461,24 +369,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// with bound regions.
|
// with bound regions.
|
||||||
let fn_sig = tcx.bound_fn_sig(def_id);
|
let fn_sig = tcx.bound_fn_sig(def_id);
|
||||||
let fn_sig = fn_sig.subst(self.tcx, substs);
|
let fn_sig = fn_sig.subst(self.tcx, substs);
|
||||||
let fn_sig = self.replace_bound_vars_with_fresh_vars(span, infer::FnCall, fn_sig);
|
let fn_sig =
|
||||||
|
self.replace_bound_vars_with_fresh_vars(obligation.cause.span, infer::FnCall, fn_sig);
|
||||||
|
|
||||||
let cause = if is_op {
|
let InferOk { value, obligations: o } =
|
||||||
ObligationCause::new(
|
self.at(&obligation.cause, self.param_env).normalize(fn_sig);
|
||||||
span,
|
|
||||||
self.body_id,
|
|
||||||
traits::BinOp {
|
|
||||||
rhs_span: opt_input_expr.map(|expr| expr.span),
|
|
||||||
is_lit: opt_input_expr
|
|
||||||
.map_or(false, |expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
|
|
||||||
output_ty: None,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
traits::ObligationCause::misc(span, self.body_id)
|
|
||||||
};
|
|
||||||
|
|
||||||
let InferOk { value, obligations: o } = self.at(&cause, self.param_env).normalize(fn_sig);
|
|
||||||
let fn_sig = {
|
let fn_sig = {
|
||||||
obligations.extend(o);
|
obligations.extend(o);
|
||||||
value
|
value
|
||||||
|
@ -494,7 +389,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// any late-bound regions appearing in its bounds.
|
// any late-bound regions appearing in its bounds.
|
||||||
let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, substs);
|
let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, substs);
|
||||||
|
|
||||||
let InferOk { value, obligations: o } = self.at(&cause, self.param_env).normalize(bounds);
|
let InferOk { value, obligations: o } =
|
||||||
|
self.at(&obligation.cause, self.param_env).normalize(bounds);
|
||||||
let bounds = {
|
let bounds = {
|
||||||
obligations.extend(o);
|
obligations.extend(o);
|
||||||
value
|
value
|
||||||
|
@ -502,7 +398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
assert!(!bounds.has_escaping_bound_vars());
|
assert!(!bounds.has_escaping_bound_vars());
|
||||||
|
|
||||||
let predicates_cause = cause.clone();
|
let predicates_cause = obligation.cause.clone();
|
||||||
obligations.extend(traits::predicates_for_generics(
|
obligations.extend(traits::predicates_for_generics(
|
||||||
move |_, _| predicates_cause.clone(),
|
move |_, _| predicates_cause.clone(),
|
||||||
self.param_env,
|
self.param_env,
|
||||||
|
@ -517,7 +413,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
obligations.push(traits::Obligation::new(
|
obligations.push(traits::Obligation::new(
|
||||||
tcx,
|
tcx,
|
||||||
cause,
|
obligation.cause,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(method_ty.into())),
|
ty::Binder::dummy(ty::PredicateKind::WellFormed(method_ty.into())),
|
||||||
));
|
));
|
||||||
|
|
|
@ -12,14 +12,16 @@ use rustc_middle::ty::adjustment::{
|
||||||
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
|
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||||
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitable};
|
use rustc_middle::ty::{
|
||||||
|
self, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitable,
|
||||||
|
};
|
||||||
use rustc_session::errors::ExprParenthesesNeeded;
|
use rustc_session::errors::ExprParenthesesNeeded;
|
||||||
use rustc_span::source_map::Spanned;
|
use rustc_span::source_map::Spanned;
|
||||||
use rustc_span::symbol::{sym, Ident};
|
use rustc_span::symbol::{sym, Ident};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::infer::InferCtxtExt;
|
use rustc_trait_selection::infer::InferCtxtExt;
|
||||||
use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt as _;
|
use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::FulfillmentError;
|
use rustc_trait_selection::traits::{self, FulfillmentError};
|
||||||
use rustc_type_ir::sty::TyKind::*;
|
use rustc_type_ir::sty::TyKind::*;
|
||||||
|
|
||||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
@ -48,8 +50,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
if self
|
if self
|
||||||
.lookup_op_method(
|
.lookup_op_method(
|
||||||
lhs_deref_ty,
|
lhs_deref_ty,
|
||||||
Some(rhs_ty),
|
Some((rhs, rhs_ty)),
|
||||||
Some(rhs),
|
|
||||||
Op::Binary(op, IsAssign::Yes),
|
Op::Binary(op, IsAssign::Yes),
|
||||||
expected,
|
expected,
|
||||||
)
|
)
|
||||||
|
@ -60,8 +61,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
if self
|
if self
|
||||||
.lookup_op_method(
|
.lookup_op_method(
|
||||||
lhs_ty,
|
lhs_ty,
|
||||||
Some(rhs_ty),
|
Some((rhs, rhs_ty)),
|
||||||
Some(rhs),
|
|
||||||
Op::Binary(op, IsAssign::Yes),
|
Op::Binary(op, IsAssign::Yes),
|
||||||
expected,
|
expected,
|
||||||
)
|
)
|
||||||
|
@ -248,8 +248,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
let result = self.lookup_op_method(
|
let result = self.lookup_op_method(
|
||||||
lhs_ty,
|
lhs_ty,
|
||||||
Some(rhs_ty_var),
|
Some((rhs_expr, rhs_ty_var)),
|
||||||
Some(rhs_expr),
|
|
||||||
Op::Binary(op, is_assign),
|
Op::Binary(op, is_assign),
|
||||||
expected,
|
expected,
|
||||||
);
|
);
|
||||||
|
@ -382,8 +381,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
if self
|
if self
|
||||||
.lookup_op_method(
|
.lookup_op_method(
|
||||||
lhs_deref_ty,
|
lhs_deref_ty,
|
||||||
Some(rhs_ty),
|
Some((rhs_expr, rhs_ty)),
|
||||||
Some(rhs_expr),
|
|
||||||
Op::Binary(op, is_assign),
|
Op::Binary(op, is_assign),
|
||||||
expected,
|
expected,
|
||||||
)
|
)
|
||||||
|
@ -410,8 +408,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let is_compatible = |lhs_ty, rhs_ty| {
|
let is_compatible = |lhs_ty, rhs_ty| {
|
||||||
self.lookup_op_method(
|
self.lookup_op_method(
|
||||||
lhs_ty,
|
lhs_ty,
|
||||||
Some(rhs_ty),
|
Some((rhs_expr, rhs_ty)),
|
||||||
Some(rhs_expr),
|
|
||||||
Op::Binary(op, is_assign),
|
Op::Binary(op, is_assign),
|
||||||
expected,
|
expected,
|
||||||
)
|
)
|
||||||
|
@ -471,8 +468,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let errors = self
|
let errors = self
|
||||||
.lookup_op_method(
|
.lookup_op_method(
|
||||||
lhs_ty,
|
lhs_ty,
|
||||||
Some(rhs_ty),
|
Some((rhs_expr, rhs_ty)),
|
||||||
Some(rhs_expr),
|
|
||||||
Op::Binary(op, is_assign),
|
Op::Binary(op, is_assign),
|
||||||
expected,
|
expected,
|
||||||
)
|
)
|
||||||
|
@ -492,6 +488,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
if let Some(output_def_id) = output_def_id
|
if let Some(output_def_id) = output_def_id
|
||||||
&& let Some(trait_def_id) = trait_def_id
|
&& let Some(trait_def_id) = trait_def_id
|
||||||
&& self.tcx.parent(output_def_id) == trait_def_id
|
&& self.tcx.parent(output_def_id) == trait_def_id
|
||||||
|
&& output_ty.is_suggestable(self.tcx, false)
|
||||||
{
|
{
|
||||||
Some(("Output", *output_ty))
|
Some(("Output", *output_ty))
|
||||||
} else {
|
} else {
|
||||||
|
@ -625,7 +622,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
expected: Expectation<'tcx>,
|
expected: Expectation<'tcx>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
assert!(op.is_by_value());
|
assert!(op.is_by_value());
|
||||||
match self.lookup_op_method(operand_ty, None, None, Op::Unary(op, ex.span), expected) {
|
match self.lookup_op_method(operand_ty, None, Op::Unary(op, ex.span), expected) {
|
||||||
Ok(method) => {
|
Ok(method) => {
|
||||||
self.write_method_call(ex.hir_id, method);
|
self.write_method_call(ex.hir_id, method);
|
||||||
method.sig.output()
|
method.sig.output()
|
||||||
|
@ -712,8 +709,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
fn lookup_op_method(
|
fn lookup_op_method(
|
||||||
&self,
|
&self,
|
||||||
lhs_ty: Ty<'tcx>,
|
lhs_ty: Ty<'tcx>,
|
||||||
other_ty: Option<Ty<'tcx>>,
|
opt_rhs: Option<(&'tcx hir::Expr<'tcx>, Ty<'tcx>)>,
|
||||||
other_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
|
|
||||||
op: Op,
|
op: Op,
|
||||||
expected: Expectation<'tcx>,
|
expected: Expectation<'tcx>,
|
||||||
) -> Result<MethodCallee<'tcx>, Vec<FulfillmentError<'tcx>>> {
|
) -> Result<MethodCallee<'tcx>, Vec<FulfillmentError<'tcx>>> {
|
||||||
|
@ -742,20 +738,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
Op::Unary(..) => 0,
|
Op::Unary(..) => 0,
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
|
self.tcx
|
||||||
|
.sess
|
||||||
|
.delay_span_bug(span, "operator didn't have the right number of generic args");
|
||||||
return Err(vec![]);
|
return Err(vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let opname = Ident::with_dummy_span(opname);
|
let opname = Ident::with_dummy_span(opname);
|
||||||
|
let input_types =
|
||||||
|
opt_rhs.as_ref().map(|(_, ty)| std::slice::from_ref(ty)).unwrap_or_default();
|
||||||
|
let cause = self.cause(
|
||||||
|
span,
|
||||||
|
traits::BinOp {
|
||||||
|
rhs_span: opt_rhs.map(|(expr, _)| expr.span),
|
||||||
|
is_lit: opt_rhs
|
||||||
|
.map_or(false, |(expr, _)| matches!(expr.kind, hir::ExprKind::Lit(_))),
|
||||||
|
output_ty: expected.only_has_type(self),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let method = trait_did.and_then(|trait_did| {
|
let method = trait_did.and_then(|trait_did| {
|
||||||
self.lookup_op_method_in_trait(
|
self.lookup_method_in_trait(cause.clone(), opname, trait_did, lhs_ty, Some(input_types))
|
||||||
span,
|
|
||||||
opname,
|
|
||||||
trait_did,
|
|
||||||
lhs_ty,
|
|
||||||
other_ty,
|
|
||||||
other_ty_expr,
|
|
||||||
expected,
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
match (method, trait_did) {
|
match (method, trait_did) {
|
||||||
|
@ -766,14 +769,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
(None, None) => Err(vec![]),
|
(None, None) => Err(vec![]),
|
||||||
(None, Some(trait_did)) => {
|
(None, Some(trait_did)) => {
|
||||||
let (obligation, _) = self.obligation_for_op_method(
|
let (obligation, _) =
|
||||||
span,
|
self.obligation_for_method(cause, trait_did, lhs_ty, Some(input_types));
|
||||||
trait_did,
|
|
||||||
lhs_ty,
|
|
||||||
other_ty,
|
|
||||||
other_ty_expr,
|
|
||||||
expected,
|
|
||||||
);
|
|
||||||
Err(rustc_trait_selection::traits::fully_solve_obligation(self, obligation))
|
Err(rustc_trait_selection::traits::fully_solve_obligation(self, obligation))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,7 +225,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
imm_tr.and_then(|trait_did| {
|
imm_tr.and_then(|trait_did| {
|
||||||
self.lookup_method_in_trait(
|
self.lookup_method_in_trait(
|
||||||
span,
|
self.misc(span),
|
||||||
Ident::with_dummy_span(imm_op),
|
Ident::with_dummy_span(imm_op),
|
||||||
trait_did,
|
trait_did,
|
||||||
base_ty,
|
base_ty,
|
||||||
|
@ -264,7 +264,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
mut_tr.and_then(|trait_did| {
|
mut_tr.and_then(|trait_did| {
|
||||||
self.lookup_method_in_trait(
|
self.lookup_method_in_trait(
|
||||||
span,
|
self.misc(span),
|
||||||
Ident::with_dummy_span(mut_op),
|
Ident::with_dummy_span(mut_op),
|
||||||
trait_did,
|
trait_did,
|
||||||
base_ty,
|
base_ty,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue