Skip to content

Commit d388e48

Browse files
committed
i hate this :<
1 parent ef0226c commit d388e48

24 files changed

+103
-74
lines changed

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1634,7 +1634,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16341634
) -> Ty<'tcx> {
16351635
let rcvr_t = self.check_expr(rcvr);
16361636
// no need to check for bot/err -- callee does that
1637-
let rcvr_t = self.structurally_resolve_type(rcvr.span, rcvr_t);
1637+
let rcvr_t = self.try_structurally_resolve_type(rcvr.span, rcvr_t);
16381638

16391639
match self.lookup_method(rcvr_t, segment, segment.ident.span, expr, rcvr, args) {
16401640
Ok(method) => {

compiler/rustc_hir_typeck/src/method/confirm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
182182
assert_eq!(n, pick.autoderefs);
183183

184184
let mut adjustments = self.adjust_steps(&autoderef);
185-
let mut target = self.structurally_resolve_type(autoderef.span(), ty);
185+
let mut target = self.try_structurally_resolve_type(autoderef.span(), ty);
186186

187187
match pick.autoref_or_ptr_adjustment {
188188
Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl, unsize }) => {

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 60 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ use rustc_hir::HirId;
1212
use rustc_hir::def::DefKind;
1313
use rustc_hir_analysis::autoderef::{self, Autoderef};
1414
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
15-
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, TyCtxtInferExt};
15+
use rustc_infer::infer::{
16+
BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk, TyCtxtInferExt,
17+
};
1618
use rustc_infer::traits::ObligationCauseCode;
1719
use rustc_middle::middle::stability;
1820
use rustc_middle::ty::elaborate::supertrait_def_ids;
@@ -441,7 +443,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
441443
// If we encountered an `_` type or an error type during autoderef, this is
442444
// ambiguous.
443445
if let Some(bad_ty) = &steps.opt_bad_ty {
444-
if is_suggestion.0 {
446+
// Ended up encountering a type variable when doing autoderef,
447+
// but it may not be a type variable after processing obligations
448+
// in our local `FnCtxt`, so don't call `structurally_resolve_type`.
449+
let ty = &bad_ty.ty;
450+
let ty = self
451+
.probe_instantiate_query_response(span, &orig_values, ty)
452+
.unwrap_or_else(|_| span_bug!(span, "instantiating {:?} failed?", ty));
453+
if bad_ty.is_opaque_type || final_ty_is_opaque(&self.infcx, ty.value) {
454+
// FIXME(-Znext-solver): This isn't really what we want :<
455+
assert!(self.tcx.next_trait_solver_globally());
456+
} else if is_suggestion.0 {
445457
// Ambiguity was encountered during a suggestion. There's really
446458
// not much use in suggesting methods in this case.
447459
return Err(MethodError::NoMatch(NoMatchData {
@@ -467,13 +479,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
467479
},
468480
);
469481
} else {
470-
// Ended up encountering a type variable when doing autoderef,
471-
// but it may not be a type variable after processing obligations
472-
// in our local `FnCtxt`, so don't call `structurally_resolve_type`.
473-
let ty = &bad_ty.ty;
474-
let ty = self
475-
.probe_instantiate_query_response(span, &orig_values, ty)
476-
.unwrap_or_else(|_| span_bug!(span, "instantiating {:?} failed?", ty));
477482
let ty = self.resolve_vars_if_possible(ty.value);
478483
let guar = match *ty.kind() {
479484
ty::Infer(ty::TyVar(_)) => {
@@ -629,8 +634,14 @@ pub(crate) fn method_autoderef_steps<'tcx>(
629634
};
630635
let final_ty = autoderef_via_deref.final_ty();
631636
let opt_bad_ty = match final_ty.kind() {
632-
ty::Infer(ty::TyVar(_)) | ty::Error(_) => Some(MethodAutoderefBadTy {
637+
ty::Infer(ty::TyVar(_)) => Some(MethodAutoderefBadTy {
633638
reached_raw_pointer,
639+
is_opaque_type: final_ty_is_opaque(infcx, final_ty),
640+
ty: infcx.make_query_response_ignoring_pending_obligations(inference_vars, final_ty),
641+
}),
642+
ty::Error(_) => Some(MethodAutoderefBadTy {
643+
reached_raw_pointer,
644+
is_opaque_type: false,
634645
ty: infcx.make_query_response_ignoring_pending_obligations(inference_vars, final_ty),
635646
}),
636647
ty::Array(elem_ty, _) => {
@@ -663,6 +674,15 @@ pub(crate) fn method_autoderef_steps<'tcx>(
663674
}
664675
}
665676

677+
/// Returns `true` in case the final type is the hidden type of an opaque.
678+
#[instrument(level = "debug", skip(infcx), ret)]
679+
fn final_ty_is_opaque<'tcx>(infcx: &InferCtxt<'tcx>, final_ty: Ty<'tcx>) -> bool {
680+
let &ty::Infer(ty::TyVar(vid)) = final_ty.kind() else {
681+
return false;
682+
};
683+
infcx.has_opaques_with_sub_unified_hidden_type(vid)
684+
}
685+
666686
impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
667687
fn new(
668688
fcx: &'a FnCtxt<'a, 'tcx>,
@@ -1871,31 +1891,39 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
18711891
(xform_self_ty, xform_ret_ty) =
18721892
self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args);
18731893
xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty);
1874-
match self_ty.kind() {
1875-
// HACK: opaque types will match anything for which their bounds hold.
1876-
// Thus we need to prevent them from trying to match the `&_` autoref
1877-
// candidates that get created for `&self` trait methods.
1878-
ty::Alias(ty::Opaque, alias_ty)
1879-
if !self.next_trait_solver()
1880-
&& self.infcx.can_define_opaque_ty(alias_ty.def_id)
1881-
&& !xform_self_ty.is_ty_var() =>
1882-
{
1883-
return ProbeResult::NoMatch;
1884-
}
1885-
_ => match ocx.relate(
1886-
cause,
1887-
self.param_env,
1888-
self.variance(),
1889-
self_ty,
1890-
xform_self_ty,
1891-
) {
1892-
Ok(()) => {}
1893-
Err(err) => {
1894-
debug!("--> cannot relate self-types {:?}", err);
1894+
1895+
// HACK: opaque types will match anything for which their bounds hold.
1896+
// Thus we need to prevent them from trying to match the `&_` autoref
1897+
// candidates that get created for `&self` trait methods.
1898+
if self.mode == Mode::MethodCall {
1899+
match self_ty.kind() {
1900+
ty::Infer(ty::TyVar(_)) => {
1901+
assert!(self.infcx.next_trait_solver());
1902+
if !xform_self_ty.is_ty_var() {
1903+
return ProbeResult::NoMatch;
1904+
}
1905+
}
1906+
ty::Alias(ty::Opaque, alias_ty)
1907+
if !self.infcx.next_trait_solver()
1908+
&& self.infcx.can_define_opaque_ty(alias_ty.def_id)
1909+
&& !xform_self_ty.is_ty_var() =>
1910+
{
1911+
assert!(!self.infcx.next_trait_solver());
18951912
return ProbeResult::NoMatch;
18961913
}
1897-
},
1914+
_ => {}
1915+
}
1916+
}
1917+
1918+
match ocx.relate(cause, self.param_env, self.variance(), self_ty, xform_self_ty)
1919+
{
1920+
Ok(()) => {}
1921+
Err(err) => {
1922+
debug!("--> cannot relate self-types {:?}", err);
1923+
return ProbeResult::NoMatch;
1924+
}
18981925
}
1926+
18991927
let obligation = traits::Obligation::new(
19001928
self.tcx,
19011929
cause.clone(),

compiler/rustc_middle/src/traits/query.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ pub struct MethodAutoderefStepsResult<'tcx> {
178178
#[derive(Debug, HashStable)]
179179
pub struct MethodAutoderefBadTy<'tcx> {
180180
pub reached_raw_pointer: bool,
181+
pub is_opaque_type: bool,
181182
pub ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
182183
}
183184

tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.next.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | needs_foo(|x| {
55
| ^
66
...
77
LL | x.to_string();
8-
| - type must be known at this point
8+
| --------- type must be known at this point
99
|
1010
help: consider giving this closure parameter an explicit type
1111
|

tests/ui/impl-trait/call_method_ambiguous.next.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | let mut iter = foo(n - 1, m);
55
| ^^^^^^^^
66
LL |
77
LL | assert_eq!(iter.get(), 1);
8-
| ---- type must be known at this point
8+
| --- type must be known at this point
99
|
1010
help: consider giving `iter` an explicit type
1111
|

tests/ui/impl-trait/call_method_on_inherent_impl.next.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | let x = my_foo();
55
| ^
66
LL |
77
LL | x.my_debug();
8-
| - type must be known at this point
8+
| -------- type must be known at this point
99
|
1010
help: consider giving `x` an explicit type
1111
|

tests/ui/impl-trait/call_method_on_inherent_impl_ref.next.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | let x = my_foo();
55
| ^
66
LL |
77
LL | x.my_debug();
8-
| - type must be known at this point
8+
| -------- type must be known at this point
99
|
1010
help: consider giving `x` an explicit type
1111
|

tests/ui/impl-trait/hidden-type-is-opaque-2.default.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | Thunk::new(|mut cont| {
55
| ^^^^^^^^
66
LL |
77
LL | cont.reify_as();
8-
| ---- type must be known at this point
8+
| -------- type must be known at this point
99
|
1010
help: consider giving this closure parameter an explicit type
1111
|
@@ -19,7 +19,7 @@ LL | Thunk::new(|mut cont| {
1919
| ^^^^^^^^
2020
LL |
2121
LL | cont.reify_as();
22-
| ---- type must be known at this point
22+
| -------- type must be known at this point
2323
|
2424
help: consider giving this closure parameter an explicit type
2525
|

tests/ui/impl-trait/hidden-type-is-opaque-2.next.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | Thunk::new(|mut cont| {
55
| ^^^^^^^^
66
LL |
77
LL | cont.reify_as();
8-
| ---- type must be known at this point
8+
| -------- type must be known at this point
99
|
1010
help: consider giving this closure parameter an explicit type
1111
|
@@ -19,7 +19,7 @@ LL | Thunk::new(|mut cont| {
1919
| ^^^^^^^^
2020
LL |
2121
LL | cont.reify_as();
22-
| ---- type must be known at this point
22+
| -------- type must be known at this point
2323
|
2424
help: consider giving this closure parameter an explicit type
2525
|

0 commit comments

Comments
 (0)