Don't record adjustments twice in note_source_of_type_mismatch_constraint
This commit is contained in:
parent
397641f3bd
commit
696cd98e6b
5 changed files with 93 additions and 7 deletions
|
@ -370,13 +370,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// Fudge the receiver, so we can do new inference on it.
|
// Fudge the receiver, so we can do new inference on it.
|
||||||
let possible_rcvr_ty = possible_rcvr_ty.fold_with(&mut fudger);
|
let possible_rcvr_ty = possible_rcvr_ty.fold_with(&mut fudger);
|
||||||
let method = self
|
let method = self
|
||||||
.lookup_method(
|
.lookup_method_for_diagnostic(
|
||||||
possible_rcvr_ty,
|
possible_rcvr_ty,
|
||||||
segment,
|
segment,
|
||||||
DUMMY_SP,
|
DUMMY_SP,
|
||||||
call_expr,
|
call_expr,
|
||||||
binding,
|
binding,
|
||||||
args,
|
|
||||||
)
|
)
|
||||||
.ok()?;
|
.ok()?;
|
||||||
// Unify the method signature with our incompatible arg, to
|
// Unify the method signature with our incompatible arg, to
|
||||||
|
@ -435,14 +434,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let Some(rcvr_ty) = self.node_ty_opt(rcvr.hir_id) else { continue; };
|
let Some(rcvr_ty) = self.node_ty_opt(rcvr.hir_id) else { continue; };
|
||||||
let rcvr_ty = rcvr_ty.fold_with(&mut fudger);
|
let rcvr_ty = rcvr_ty.fold_with(&mut fudger);
|
||||||
let Ok(method) =
|
let Ok(method) =
|
||||||
self.lookup_method(rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr, args)
|
self.lookup_method_for_diagnostic(rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr)
|
||||||
else {
|
else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
let ideal_rcvr_ty = rcvr_ty.fold_with(&mut fudger);
|
let ideal_rcvr_ty = rcvr_ty.fold_with(&mut fudger);
|
||||||
let ideal_method = self
|
let ideal_method = self
|
||||||
.lookup_method(ideal_rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr, args)
|
.lookup_method_for_diagnostic(ideal_rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr)
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|method| {
|
.and_then(|method| {
|
||||||
let _ = self.at(&ObligationCause::dummy(), self.param_env)
|
let _ = self.at(&ObligationCause::dummy(), self.param_env)
|
||||||
|
|
|
@ -26,6 +26,7 @@ struct ConfirmContext<'a, 'tcx> {
|
||||||
span: Span,
|
span: Span,
|
||||||
self_expr: &'tcx hir::Expr<'tcx>,
|
self_expr: &'tcx hir::Expr<'tcx>,
|
||||||
call_expr: &'tcx hir::Expr<'tcx>,
|
call_expr: &'tcx hir::Expr<'tcx>,
|
||||||
|
skip_record_for_diagnostics: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Deref for ConfirmContext<'a, 'tcx> {
|
impl<'a, 'tcx> Deref for ConfirmContext<'a, 'tcx> {
|
||||||
|
@ -59,6 +60,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let mut confirm_cx = ConfirmContext::new(self, span, self_expr, call_expr);
|
let mut confirm_cx = ConfirmContext::new(self, span, self_expr, call_expr);
|
||||||
confirm_cx.confirm(unadjusted_self_ty, pick, segment)
|
confirm_cx.confirm(unadjusted_self_ty, pick, segment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn confirm_method_for_diagnostic(
|
||||||
|
&self,
|
||||||
|
span: Span,
|
||||||
|
self_expr: &'tcx hir::Expr<'tcx>,
|
||||||
|
call_expr: &'tcx hir::Expr<'tcx>,
|
||||||
|
unadjusted_self_ty: Ty<'tcx>,
|
||||||
|
pick: &probe::Pick<'tcx>,
|
||||||
|
segment: &hir::PathSegment<'_>,
|
||||||
|
) -> ConfirmResult<'tcx> {
|
||||||
|
let mut confirm_cx = ConfirmContext::new(self, span, self_expr, call_expr);
|
||||||
|
confirm_cx.skip_record_for_diagnostics = true;
|
||||||
|
confirm_cx.confirm(unadjusted_self_ty, pick, segment)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||||
|
@ -68,7 +83,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||||
self_expr: &'tcx hir::Expr<'tcx>,
|
self_expr: &'tcx hir::Expr<'tcx>,
|
||||||
call_expr: &'tcx hir::Expr<'tcx>,
|
call_expr: &'tcx hir::Expr<'tcx>,
|
||||||
) -> ConfirmContext<'a, 'tcx> {
|
) -> ConfirmContext<'a, 'tcx> {
|
||||||
ConfirmContext { fcx, span, self_expr, call_expr }
|
ConfirmContext { fcx, span, self_expr, call_expr, skip_record_for_diagnostics: false }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm(
|
fn confirm(
|
||||||
|
@ -219,7 +234,9 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||||
self.register_predicates(autoderef.into_obligations());
|
self.register_predicates(autoderef.into_obligations());
|
||||||
|
|
||||||
// Write out the final adjustments.
|
// Write out the final adjustments.
|
||||||
self.apply_adjustments(self.self_expr, adjustments);
|
if !self.skip_record_for_diagnostics {
|
||||||
|
self.apply_adjustments(self.self_expr, adjustments);
|
||||||
|
}
|
||||||
|
|
||||||
target
|
target
|
||||||
}
|
}
|
||||||
|
@ -453,7 +470,10 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||||
});
|
});
|
||||||
|
|
||||||
debug!("instantiate_method_substs: user_type_annotation={:?}", user_type_annotation);
|
debug!("instantiate_method_substs: user_type_annotation={:?}", user_type_annotation);
|
||||||
self.fcx.write_user_type_annotation(self.call_expr.hir_id, user_type_annotation);
|
|
||||||
|
if !self.skip_record_for_diagnostics {
|
||||||
|
self.fcx.write_user_type_annotation(self.call_expr.hir_id, user_type_annotation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.normalize(self.span, substs)
|
self.normalize(self.span, substs)
|
||||||
|
|
|
@ -254,6 +254,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
Ok(result.callee)
|
Ok(result.callee)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lookup_method_for_diagnostic(
|
||||||
|
&self,
|
||||||
|
self_ty: Ty<'tcx>,
|
||||||
|
segment: &hir::PathSegment<'_>,
|
||||||
|
span: Span,
|
||||||
|
call_expr: &'tcx hir::Expr<'tcx>,
|
||||||
|
self_expr: &'tcx hir::Expr<'tcx>,
|
||||||
|
) -> Result<MethodCallee<'tcx>, MethodError<'tcx>> {
|
||||||
|
let pick = self.lookup_probe_for_diagnostic(
|
||||||
|
segment.ident,
|
||||||
|
self_ty,
|
||||||
|
call_expr,
|
||||||
|
ProbeScope::TraitsInScope,
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(self
|
||||||
|
.confirm_method_for_diagnostic(span, self_expr, call_expr, self_ty, &pick, segment)
|
||||||
|
.callee)
|
||||||
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self, call_expr))]
|
#[instrument(level = "debug", skip(self, call_expr))]
|
||||||
pub fn lookup_probe(
|
pub fn lookup_probe(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
pub trait NSWindow: Sized {
|
||||||
|
fn frame(self) -> () {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn setFrame_display_(self, display: ()) {}
|
||||||
|
}
|
||||||
|
impl NSWindow for () {}
|
||||||
|
|
||||||
|
pub struct NSRect {}
|
||||||
|
|
||||||
|
use std::ops::Deref;
|
||||||
|
struct MainThreadSafe<T = ()>(T);
|
||||||
|
impl<T> Deref for MainThreadSafe<T> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &T {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
|| {
|
||||||
|
let ns_window = MainThreadSafe(());
|
||||||
|
// Don't record adjustments twice for `*ns_window`
|
||||||
|
(*ns_window).frame();
|
||||||
|
ns_window.setFrame_display_(0);
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/dont-record-adjustments-when-pointing-at-arg.rs:26:37
|
||||||
|
|
|
||||||
|
LL | ns_window.setFrame_display_(0);
|
||||||
|
| ----------------- ^ expected `()`, found integer
|
||||||
|
| |
|
||||||
|
| arguments to this method are incorrect
|
||||||
|
|
|
||||||
|
note: method defined here
|
||||||
|
--> $DIR/dont-record-adjustments-when-pointing-at-arg.rs:5:8
|
||||||
|
|
|
||||||
|
LL | fn setFrame_display_(self, display: ()) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^ -----------
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Add table
Add a link
Reference in a new issue