Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop using PolyTraitRef for closure/coroutine predicates already instantiated w placeholders #123900

Merged
merged 2 commits into from
Apr 15, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -367,7 +367,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}),
) = error.code
&& let ty::Closure(def_id, _) | ty::Coroutine(def_id, ..) =
expected_trait_ref.skip_binder().self_ty().kind()
expected_trait_ref.self_ty().kind()
&& span.overlaps(self.tcx.def_span(*def_id))
{
true
20 changes: 1 addition & 19 deletions compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
@@ -424,25 +424,7 @@ impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> {
) -> TypeTrace<'tcx> {
TypeTrace {
cause: cause.clone(),
values: PolyTraitRefs(ExpectedFound::new(
a_is_expected,
ty::Binder::dummy(a),
ty::Binder::dummy(b),
)),
}
}
}

impl<'tcx> ToTrace<'tcx> for ty::PolyTraitRef<'tcx> {
fn to_trace(
cause: &ObligationCause<'tcx>,
a_is_expected: bool,
a: Self,
b: Self,
) -> TypeTrace<'tcx> {
TypeTrace {
cause: cause.clone(),
values: PolyTraitRefs(ExpectedFound::new(a_is_expected, a, b)),
values: TraitRefs(ExpectedFound::new(a_is_expected, a, b)),
}
}
}
8 changes: 4 additions & 4 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
@@ -1653,7 +1653,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
.report(diag);
(false, Mismatch::Fixed("signature"))
}
ValuePairs::PolyTraitRefs(_) => (false, Mismatch::Fixed("trait")),
ValuePairs::TraitRefs(_) => (false, Mismatch::Fixed("trait")),
ValuePairs::Aliases(infer::ExpectedFound { expected, .. }) => {
(false, Mismatch::Fixed(self.tcx.def_descr(expected.def_id)))
}
@@ -1969,8 +1969,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
self.note_and_explain_type_err(diag, exp_found, cause, span, cause.body_id.to_def_id());
}

if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values
&& let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind()
if let Some(ValuePairs::TraitRefs(exp_found)) = values
&& let ty::Closure(def_id, _) = exp_found.expected.self_ty().kind()
&& let Some(def_id) = def_id.as_local()
&& terr.involves_regions()
{
@@ -2188,7 +2188,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
infer::Aliases(exp_found) => self.expected_found_str(exp_found),
infer::ExistentialTraitRef(exp_found) => self.expected_found_str(exp_found),
infer::ExistentialProjection(exp_found) => self.expected_found_str(exp_found),
infer::PolyTraitRefs(exp_found) => {
infer::TraitRefs(exp_found) => {
let pretty_exp_found = ty::error::ExpectedFound {
expected: exp_found.expected.print_trait_sugared(),
found: exp_found.found.print_trait_sugared(),
Original file line number Diff line number Diff line change
@@ -195,13 +195,13 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
value_pairs: &ValuePairs<'tcx>,
) -> Option<Diag<'tcx>> {
let (expected_args, found_args, trait_def_id) = match value_pairs {
ValuePairs::PolyTraitRefs(ExpectedFound { expected, found })
if expected.def_id() == found.def_id() =>
ValuePairs::TraitRefs(ExpectedFound { expected, found })
if expected.def_id == found.def_id =>
{
// It's possible that the placeholders come from a binder
// outside of this value pair. Use `no_bound_vars` as a
// simple heuristic for that.
(expected.no_bound_vars()?.args, found.no_bound_vars()?.args, expected.def_id())
(expected.args, found.args, expected.def_id)
}
_ => return None,
};
6 changes: 3 additions & 3 deletions compiler/rustc_infer/src/infer/error_reporting/suggest.rs
Original file line number Diff line number Diff line change
@@ -599,7 +599,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&self,
span: Span,
hir: hir::Node<'_>,
exp_found: &ty::error::ExpectedFound<ty::PolyTraitRef<'tcx>>,
exp_found: &ty::error::ExpectedFound<ty::TraitRef<'tcx>>,
diag: &mut Diag<'_>,
) {
// 0. Extract fn_decl from hir
@@ -614,10 +614,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {

// 1. Get the args of the closure.
// 2. Assume exp_found is FnOnce / FnMut / Fn, we can extract function parameters from [1].
let Some(expected) = exp_found.expected.skip_binder().args.get(1) else {
let Some(expected) = exp_found.expected.args.get(1) else {
return;
};
let Some(found) = exp_found.found.skip_binder().args.get(1) else {
let Some(found) = exp_found.found.args.get(1) else {
return;
};
let expected = expected.unpack();
10 changes: 5 additions & 5 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
@@ -403,7 +403,7 @@ pub enum ValuePairs<'tcx> {
Regions(ExpectedFound<ty::Region<'tcx>>),
Terms(ExpectedFound<ty::Term<'tcx>>),
Aliases(ExpectedFound<ty::AliasTy<'tcx>>),
PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
PolySigs(ExpectedFound<ty::PolyFnSig<'tcx>>),
ExistentialTraitRef(ExpectedFound<ty::PolyExistentialTraitRef<'tcx>>),
ExistentialProjection(ExpectedFound<ty::PolyExistentialProjection<'tcx>>),
@@ -1882,15 +1882,15 @@ impl<'tcx> TypeTrace<'tcx> {
}
}

pub fn poly_trait_refs(
pub fn trait_refs(
cause: &ObligationCause<'tcx>,
a_is_expected: bool,
a: ty::PolyTraitRef<'tcx>,
b: ty::PolyTraitRef<'tcx>,
a: ty::TraitRef<'tcx>,
b: ty::TraitRef<'tcx>,
) -> TypeTrace<'tcx> {
TypeTrace {
cause: cause.clone(),
values: PolyTraitRefs(ExpectedFound::new(a_is_expected, a, b)),
values: TraitRefs(ExpectedFound::new(a_is_expected, a, b)),
}
}

5 changes: 2 additions & 3 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
@@ -620,11 +620,10 @@ pub enum SelectionError<'tcx> {
OpaqueTypeAutoTraitLeakageUnknown(DefId),
}

// FIXME(@lcnr): The `Binder` here should be unnecessary. Just use `TraitRef` instead.
#[derive(Clone, Debug, TypeVisitable)]
pub struct SignatureMismatchData<'tcx> {
pub found_trait_ref: ty::PolyTraitRef<'tcx>,
pub expected_trait_ref: ty::PolyTraitRef<'tcx>,
pub found_trait_ref: ty::TraitRef<'tcx>,
pub expected_trait_ref: ty::TraitRef<'tcx>,
pub terr: ty::error::TypeError<'tcx>,
}

Original file line number Diff line number Diff line change
@@ -1879,19 +1879,19 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&self,
span: Span,
found_span: Option<Span>,
found: ty::PolyTraitRef<'tcx>,
expected: ty::PolyTraitRef<'tcx>,
found: ty::TraitRef<'tcx>,
expected: ty::TraitRef<'tcx>,
cause: &ObligationCauseCode<'tcx>,
found_node: Option<Node<'_>>,
param_env: ty::ParamEnv<'tcx>,
) -> Diag<'tcx> {
pub(crate) fn build_fn_sig_ty<'tcx>(
infcx: &InferCtxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
trait_ref: ty::TraitRef<'tcx>,
) -> Ty<'tcx> {
let inputs = trait_ref.skip_binder().args.type_at(1);
let inputs = trait_ref.args.type_at(1);
let sig = match inputs.kind() {
ty::Tuple(inputs) if infcx.tcx.is_fn_trait(trait_ref.def_id()) => {
ty::Tuple(inputs) if infcx.tcx.is_fn_trait(trait_ref.def_id) => {
infcx.tcx.mk_fn_sig(
*inputs,
infcx.next_ty_var(TypeVariableOrigin {
@@ -1915,10 +1915,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
),
};

Ty::new_fn_ptr(infcx.tcx, trait_ref.rebind(sig))
Ty::new_fn_ptr(infcx.tcx, ty::Binder::dummy(sig))
}

let argument_kind = match expected.skip_binder().self_ty().kind() {
let argument_kind = match expected.self_ty().kind() {
ty::Closure(..) => "closure",
ty::Coroutine(..) => "coroutine",
_ => "function",
Original file line number Diff line number Diff line change
@@ -3380,11 +3380,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn report_cyclic_signature_error(
&self,
obligation: &PredicateObligation<'tcx>,
found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
found_trait_ref: ty::TraitRef<'tcx>,
expected_trait_ref: ty::TraitRef<'tcx>,
terr: TypeError<'tcx>,
) -> Diag<'tcx> {
let self_ty = found_trait_ref.self_ty().skip_binder();
let self_ty = found_trait_ref.self_ty();
let (cause, terr) = if let ty::Closure(def_id, _) = self_ty.kind() {
(
ObligationCause::dummy_with_span(self.tcx.def_span(def_id)),
@@ -3394,7 +3394,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
(obligation.cause.clone(), terr)
};
self.report_and_explain_type_error(
TypeTrace::poly_trait_refs(&cause, true, expected_trait_ref, found_trait_ref),
TypeTrace::trait_refs(&cause, true, expected_trait_ref, found_trait_ref),
terr,
)
}
@@ -3434,17 +3434,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&self,
obligation: &PredicateObligation<'tcx>,
span: Span,
found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
found_trait_ref: ty::TraitRef<'tcx>,
expected_trait_ref: ty::TraitRef<'tcx>,
) -> Result<Diag<'tcx>, ErrorGuaranteed> {
let found_trait_ref = self.resolve_vars_if_possible(found_trait_ref);
let expected_trait_ref = self.resolve_vars_if_possible(expected_trait_ref);

expected_trait_ref.self_ty().error_reported()?;

let Some(found_trait_ty) = found_trait_ref.self_ty().no_bound_vars() else {
self.dcx().bug("bound vars outside binder");
};
let found_trait_ty = found_trait_ref.self_ty();

let found_did = match *found_trait_ty.kind() {
ty::Closure(did, _) | ty::FnDef(did, _) | ty::Coroutine(did, ..) => Some(did),
@@ -3462,15 +3459,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {

let mut not_tupled = false;

let found = match found_trait_ref.skip_binder().args.type_at(1).kind() {
let found = match found_trait_ref.args.type_at(1).kind() {
ty::Tuple(tys) => vec![ArgKind::empty(); tys.len()],
_ => {
not_tupled = true;
vec![ArgKind::empty()]
}
};

let expected_ty = expected_trait_ref.skip_binder().args.type_at(1);
let expected_ty = expected_trait_ref.args.type_at(1);
let expected = match expected_ty.kind() {
ty::Tuple(tys) => {
tys.iter().map(|t| ArgKind::from_expected_ty(t, Some(span))).collect()
@@ -3487,11 +3484,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// traits manually, but don't make it more confusing when it does
// happen.
Ok(
if Some(expected_trait_ref.def_id()) != self.tcx.lang_items().coroutine_trait()
if Some(expected_trait_ref.def_id) != self.tcx.lang_items().coroutine_trait()
&& not_tupled
{
self.report_and_explain_type_error(
TypeTrace::poly_trait_refs(
TypeTrace::trait_refs(
&obligation.cause,
true,
expected_trait_ref,
Original file line number Diff line number Diff line change
@@ -1079,8 +1079,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
})
.map_err(|terr| {
SignatureMismatch(Box::new(SignatureMismatchData {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is that sometimes used with an uninstantiated binder?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, it's always instantiated

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then we can remove the Binder from SignatureMismatchData 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't that what this PR is doing? 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?????????????????????????????????????????????? I might have been utterly confused

god knows what i was thinking. sorry

expected_trait_ref: ty::Binder::dummy(obligation_trait_ref),
found_trait_ref: ty::Binder::dummy(found_trait_ref),
expected_trait_ref: obligation_trait_ref,
found_trait_ref,
terr,
}))
})