Skip to content

Commit e03aed3

Browse files
committed
Auto merge of rust-lang#115625 - compiler-errors:hrtb-infer-err, r=b-naber
Explain HRTB + infer limitations of old solver Add a helpful message when we hit the limitation of the old trait solver where we don't properly normalize GATs with infer vars + bound vars, leading to too-eagerly reporting trait errors that would be later satisfied due to inference.
2 parents e5fedce + d122155 commit e03aed3

File tree

6 files changed

+104
-0
lines changed

6 files changed

+104
-0
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
986986
}
987987
}
988988

989+
self.explain_hrtb_projection(&mut err, trait_predicate, obligation.param_env, &obligation.cause);
990+
989991
// Return early if the trait is Debug or Display and the invocation
990992
// originates within a standard library macro, because the output
991993
// is otherwise overwhelming and unhelpful (see #85844 for an

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+73
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,14 @@ pub trait TypeErrCtxtExt<'tcx> {
406406
candidate_impls: &[ImplCandidate<'tcx>],
407407
span: Span,
408408
);
409+
410+
fn explain_hrtb_projection(
411+
&self,
412+
diag: &mut Diagnostic,
413+
pred: ty::PolyTraitPredicate<'tcx>,
414+
param_env: ty::ParamEnv<'tcx>,
415+
cause: &ObligationCause<'tcx>,
416+
);
409417
}
410418

411419
fn predicate_constraint(generics: &hir::Generics<'_>, pred: ty::Predicate<'_>) -> (Span, String) {
@@ -4027,6 +4035,71 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
40274035
}
40284036
}
40294037
}
4038+
4039+
fn explain_hrtb_projection(
4040+
&self,
4041+
diag: &mut Diagnostic,
4042+
pred: ty::PolyTraitPredicate<'tcx>,
4043+
param_env: ty::ParamEnv<'tcx>,
4044+
cause: &ObligationCause<'tcx>,
4045+
) {
4046+
if pred.skip_binder().has_escaping_bound_vars() && pred.skip_binder().has_non_region_infer()
4047+
{
4048+
self.probe(|_| {
4049+
let ocx = ObligationCtxt::new(self);
4050+
let pred = self.instantiate_binder_with_placeholders(pred);
4051+
let pred = ocx.normalize(&ObligationCause::dummy(), param_env, pred);
4052+
ocx.register_obligation(Obligation::new(
4053+
self.tcx,
4054+
ObligationCause::dummy(),
4055+
param_env,
4056+
pred,
4057+
));
4058+
if !ocx.select_where_possible().is_empty() {
4059+
// encountered errors.
4060+
return;
4061+
}
4062+
4063+
if let ObligationCauseCode::FunctionArgumentObligation {
4064+
call_hir_id,
4065+
arg_hir_id,
4066+
parent_code: _,
4067+
} = cause.code()
4068+
{
4069+
let arg_span = self.tcx.hir().span(*arg_hir_id);
4070+
let mut sp: MultiSpan = arg_span.into();
4071+
4072+
sp.push_span_label(
4073+
arg_span,
4074+
"the trait solver is unable to infer the \
4075+
generic types that should be inferred from this argument",
4076+
);
4077+
sp.push_span_label(
4078+
self.tcx.hir().span(*call_hir_id),
4079+
"add turbofish arguments to this call to \
4080+
specify the types manually, even if it's redundant",
4081+
);
4082+
diag.span_note(
4083+
sp,
4084+
"this is a known limitation of the trait solver that \
4085+
will be lifted in the future",
4086+
);
4087+
} else {
4088+
let mut sp: MultiSpan = cause.span.into();
4089+
sp.push_span_label(
4090+
cause.span,
4091+
"try adding turbofish arguments to this expression to \
4092+
specify the types manually, even if it's redundant",
4093+
);
4094+
diag.span_note(
4095+
sp,
4096+
"this is a known limitation of the trait solver that \
4097+
will be lifted in the future",
4098+
);
4099+
}
4100+
});
4101+
}
4102+
}
40304103
}
40314104

40324105
/// Add a hint to add a missing borrow or remove an unnecessary one.

tests/ui/generic-associated-types/bugs/issue-88460.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ LL | test(Foo);
77
| required by a bound introduced by this call
88
|
99
= help: the trait `Marker` is implemented for `()`
10+
note: this is a known limitation of the trait solver that will be lifted in the future
11+
--> $DIR/issue-88460.rs:28:10
12+
|
13+
LL | test(Foo);
14+
| -----^^^-
15+
| | |
16+
| | the trait solver is unable to infer the generic types that should be inferred from this argument
17+
| add turbofish arguments to this call to specify the types manually, even if it's redundant
1018
note: required by a bound in `test`
1119
--> $DIR/issue-88460.rs:15:27
1220
|

tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ LL | call(f, ());
88
|
99
= note: expected a closure with arguments `((),)`
1010
found a closure with arguments `(<_ as ATC<'a>>::Type,)`
11+
note: this is a known limitation of the trait solver that will be lifted in the future
12+
--> $DIR/issue-62529-3.rs:25:14
13+
|
14+
LL | call(f, ());
15+
| -----^-----
16+
| | |
17+
| | the trait solver is unable to infer the generic types that should be inferred from this argument
18+
| add turbofish arguments to this call to specify the types manually, even if it's redundant
1119
note: required by a bound in `call`
1220
--> $DIR/issue-62529-3.rs:9:36
1321
|

tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ LL | upcast(y)
77
| required by a bound introduced by this call
88
|
99
= help: the trait `IsCovariant<'a>` is implemented for `std::borrow::Cow<'a, T>`
10+
note: this is a known limitation of the trait solver that will be lifted in the future
11+
--> $DIR/issue-90950.rs:50:12
12+
|
13+
LL | upcast(y)
14+
| -------^-
15+
| | |
16+
| | the trait solver is unable to infer the generic types that should be inferred from this argument
17+
| add turbofish arguments to this call to specify the types manually, even if it's redundant
1018
note: required by a bound in `upcast`
1119
--> $DIR/issue-90950.rs:27:42
1220
|

tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ error[E0277]: the trait bound `for<'a> <_ as Trait<'a>>::Out: Copy` is not satis
44
LL | let _: () = weird_bound();
55
| ^^^^^^^^^^^ the trait `for<'a> Copy` is not implemented for `<_ as Trait<'a>>::Out`
66
|
7+
note: this is a known limitation of the trait solver that will be lifted in the future
8+
--> $DIR/norm-before-method-resolution.rs:22:17
9+
|
10+
LL | let _: () = weird_bound();
11+
| ^^^^^^^^^^^ try adding turbofish arguments to this expression to specify the types manually, even if it's redundant
712
note: required by a bound in `weird_bound`
813
--> $DIR/norm-before-method-resolution.rs:18:40
914
|

0 commit comments

Comments
 (0)