Don't structurally resolve during method ambiguity in probe
This commit is contained in:
parent
04075b3202
commit
afe36507e8
@ -12,6 +12,7 @@ use rustc_hir::def::DefKind;
|
||||
use rustc_hir_analysis::autoderef::{self, Autoderef};
|
||||
use rustc_infer::infer::canonical::OriginalQueryValues;
|
||||
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
|
||||
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
|
||||
use rustc_infer::infer::DefineOpaqueTypes;
|
||||
use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
|
||||
use rustc_middle::middle::stability;
|
||||
@ -448,15 +449,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Encountered a real ambiguity, so abort the lookup. If `ty` is not
|
||||
// an `Err`, report the right "type annotations needed" error pointing
|
||||
// to it.
|
||||
// Ended up encountering a type variable when doing autoderef,
|
||||
// but it may not be a type variable after processing obligations
|
||||
// in our local `FnCtxt`, so don't call `structurally_resolved_type`.
|
||||
let ty = &bad_ty.ty;
|
||||
let ty = self
|
||||
.probe_instantiate_query_response(span, &orig_values, ty)
|
||||
.unwrap_or_else(|_| span_bug!(span, "instantiating {:?} failed?", ty));
|
||||
let ty = self.structurally_resolved_type(span, ty.value);
|
||||
assert!(matches!(ty.kind(), ty::Error(_)));
|
||||
let ty = self.resolve_vars_if_possible(ty.value);
|
||||
let guar = match *ty.kind() {
|
||||
ty::Infer(ty::TyVar(_)) => self
|
||||
.err_ctxt()
|
||||
.emit_inference_failure_err(self.body_id, span, ty.into(), E0282, true)
|
||||
.emit(),
|
||||
ty::Error(guar) => guar,
|
||||
_ => bug!("unexpected bad final type in method autoderef"),
|
||||
};
|
||||
self.demand_eqtype(span, ty, self.tcx.ty_error(guar));
|
||||
return Err(MethodError::NoMatch(NoMatchData {
|
||||
static_candidates: Vec::new(),
|
||||
unsatisfied_predicates: Vec::new(),
|
||||
|
@ -0,0 +1,40 @@
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
|
||||
struct Value<T>(T);
|
||||
|
||||
pub trait Wrap<T> {
|
||||
fn wrap() -> Self;
|
||||
}
|
||||
|
||||
impl<R, A1, A2> Wrap<fn(A1, A2) -> R> for Value<fn(A1, A2) -> R> {
|
||||
fn wrap() -> Self {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, R, A1, A2> Wrap<F> for Value<Rc<dyn Fn(A1, A2) -> R>> {
|
||||
fn wrap() -> Self {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<F> Deref for Value<Rc<F>> {
|
||||
type Target = F;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&*self.0
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let var_fn = Value::wrap();
|
||||
//~^ ERROR type annotations needed for `Value<Rc<_>>`
|
||||
|
||||
// The combination of `Value: Wrap` obligation plus the autoderef steps
|
||||
// (caused by the `Deref` impl above) actually means that the self type
|
||||
// of the method fn below is constrained to be `Value<Rc<dyn Fn(?0, ?1) -> ?2>>`.
|
||||
// However, that's only known to us on the error path -- we still need
|
||||
// to emit an ambiguity error, though.
|
||||
let _ = var_fn.clone();
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
error[E0282]: type annotations needed for `Value<Rc<_>>`
|
||||
--> $DIR/deref-ambiguity-becomes-nonambiguous.rs:31:9
|
||||
|
|
||||
LL | let var_fn = Value::wrap();
|
||||
| ^^^^^^
|
||||
...
|
||||
LL | let _ = var_fn.clone();
|
||||
| ----- type must be known at this point
|
||||
|
|
||||
help: consider giving `var_fn` an explicit type, where the placeholders `_` are specified
|
||||
|
|
||||
LL | let var_fn: Value<Rc<_>> = Value::wrap();
|
||||
| ++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
Loading…
x
Reference in New Issue
Block a user