Skip to content

Commit ddbd46c

Browse files
committed
Auto merge of rust-lang#124977 - compiler-errors:higher-ranked-err, r=<try>
Improve location reporting of trait placeholder error Self-explanatory
2 parents 6a19a87 + 70dcbe4 commit ddbd46c

File tree

24 files changed

+200
-104
lines changed

24 files changed

+200
-104
lines changed

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> {
6363
ConstraintCategory::OpaqueType => "opaque type ",
6464
ConstraintCategory::ClosureUpvar(_) => "closure capture ",
6565
ConstraintCategory::Usage => "this usage ",
66-
ConstraintCategory::Predicate(_)
66+
ConstraintCategory::Predicate(..)
6767
| ConstraintCategory::Boring
6868
| ConstraintCategory::BoringNoLocation
6969
| ConstraintCategory::Internal => "",

compiler/rustc_borrowck/src/region_infer/mod.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -2040,7 +2040,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20402040
continue;
20412041
};
20422042
debug!(?constraint, ?p);
2043-
let ConstraintCategory::Predicate(span) = constraint.category else {
2043+
let ConstraintCategory::Predicate(_, span) = constraint.category else {
20442044
continue;
20452045
};
20462046
extra_info.push(ExtraConstraintInfo::PlaceholderFromPredicate(span));
@@ -2055,14 +2055,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20552055
let cause_code = path
20562056
.iter()
20572057
.find_map(|constraint| {
2058-
if let ConstraintCategory::Predicate(predicate_span) = constraint.category {
2058+
if let ConstraintCategory::Predicate(source_def_id, predicate_span) =
2059+
constraint.category
2060+
{
20592061
// We currently do not store the `DefId` in the `ConstraintCategory`
20602062
// for performances reasons. The error reporting code used by NLL only
20612063
// uses the span, so this doesn't cause any problems at the moment.
2062-
Some(ObligationCauseCode::BindingObligation(
2063-
CRATE_DEF_ID.to_def_id(),
2064-
predicate_span,
2065-
))
2064+
Some(ObligationCauseCode::BindingObligation(source_def_id, predicate_span))
20662065
} else {
20672066
None
20682067
}
@@ -2156,7 +2155,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
21562155
| ConstraintCategory::Boring
21572156
| ConstraintCategory::BoringNoLocation
21582157
| ConstraintCategory::Internal
2159-
| ConstraintCategory::Predicate(_) => false,
2158+
| ConstraintCategory::Predicate(..) => false,
21602159
ConstraintCategory::TypeAnnotation
21612160
| ConstraintCategory::Return(_)
21622161
| ConstraintCategory::Yield => true,
@@ -2169,7 +2168,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
21692168
| ConstraintCategory::Boring
21702169
| ConstraintCategory::BoringNoLocation
21712170
| ConstraintCategory::Internal
2172-
| ConstraintCategory::Predicate(_)
2171+
| ConstraintCategory::Predicate(..)
21732172
)
21742173
}
21752174
};

compiler/rustc_borrowck/src/type_check/canonical.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
101101
&mut self,
102102
// Keep this parameter for now, in case we start using
103103
// it in `ConstraintCategory` at some point.
104-
_def_id: DefId,
104+
def_id: DefId,
105105
instantiated_predicates: ty::InstantiatedPredicates<'tcx>,
106106
locations: Locations,
107107
) {
108108
for (predicate, span) in instantiated_predicates {
109109
debug!(?span, ?predicate);
110-
let category = ConstraintCategory::Predicate(span);
110+
let category = ConstraintCategory::Predicate(def_id, span);
111111
let predicate = self.normalize_with_category(predicate, locations, category);
112112
self.prove_predicate(predicate, locations, category);
113113
}

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs

+15-14
Original file line numberDiff line numberDiff line change
@@ -239,20 +239,21 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
239239
) -> Diag<'tcx> {
240240
let span = cause.span();
241241

242-
let (leading_ellipsis, satisfy_span, where_span, dup_span, def_id) =
243-
if let ObligationCauseCode::ItemObligation(def_id)
244-
| ObligationCauseCode::ExprItemObligation(def_id, ..) = *cause.code()
245-
{
246-
(
247-
true,
248-
Some(span),
249-
Some(self.tcx().def_span(def_id)),
250-
None,
251-
self.tcx().def_path_str(def_id),
252-
)
253-
} else {
254-
(false, None, None, Some(span), String::new())
255-
};
242+
let (leading_ellipsis, satisfy_span, where_span, dup_span, def_id) = match *cause.code() {
243+
ObligationCauseCode::ItemObligation(def_id)
244+
| ObligationCauseCode::ExprItemObligation(def_id, ..) => (
245+
true,
246+
Some(span),
247+
self.tcx().def_ident_span(def_id),
248+
None,
249+
self.tcx().def_path_str(def_id),
250+
),
251+
ObligationCauseCode::BindingObligation(def_id, pred_span)
252+
| ObligationCauseCode::ExprBindingObligation(def_id, pred_span, ..) => {
253+
(true, Some(span), Some(pred_span), None, self.tcx().def_path_str(def_id))
254+
}
255+
_ => (false, None, None, Some(span), String::new()),
256+
};
256257

257258
let expected_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new(
258259
self.cx.tcx,

compiler/rustc_infer/src/infer/error_reporting/note.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
6363
infer::CheckAssociatedTypeBounds { ref parent, .. } => {
6464
self.note_region_origin(err, parent);
6565
}
66-
infer::AscribeUserTypeProvePredicate(span) => {
66+
infer::AscribeUserTypeProvePredicate(_, span) => {
6767
RegionOriginNote::Plain {
6868
span,
6969
msg: fluent::infer_ascribe_user_type_prove_predicate,
@@ -259,7 +259,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
259259
);
260260
err
261261
}
262-
infer::AscribeUserTypeProvePredicate(span) => {
262+
infer::AscribeUserTypeProvePredicate(_, span) => {
263263
let instantiated = note_and_explain::RegionExplanation::new(
264264
self.tcx,
265265
sup,

compiler/rustc_infer/src/infer/mod.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ pub enum SubregionOrigin<'tcx> {
474474
trait_item_def_id: DefId,
475475
},
476476

477-
AscribeUserTypeProvePredicate(Span),
477+
AscribeUserTypeProvePredicate(DefId, Span),
478478
}
479479

480480
// `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger.
@@ -485,7 +485,9 @@ impl<'tcx> SubregionOrigin<'tcx> {
485485
pub fn to_constraint_category(&self) -> ConstraintCategory<'tcx> {
486486
match self {
487487
Self::Subtype(type_trace) => type_trace.cause.to_constraint_category(),
488-
Self::AscribeUserTypeProvePredicate(span) => ConstraintCategory::Predicate(*span),
488+
Self::AscribeUserTypeProvePredicate(def_id, span) => {
489+
ConstraintCategory::Predicate(*def_id, *span)
490+
}
489491
_ => ConstraintCategory::BoringNoLocation,
490492
}
491493
}
@@ -1862,7 +1864,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
18621864
Reborrow(a) => a,
18631865
ReferenceOutlivesReferent(_, a) => a,
18641866
CompareImplItemObligation { span, .. } => span,
1865-
AscribeUserTypeProvePredicate(span) => span,
1867+
AscribeUserTypeProvePredicate(_, span) => span,
18661868
CheckAssociatedTypeBounds { ref parent, .. } => parent.span(),
18671869
}
18681870
}
@@ -1895,8 +1897,8 @@ impl<'tcx> SubregionOrigin<'tcx> {
18951897
parent: Box::new(default()),
18961898
},
18971899

1898-
traits::ObligationCauseCode::AscribeUserTypeProvePredicate(span) => {
1899-
SubregionOrigin::AscribeUserTypeProvePredicate(span)
1900+
traits::ObligationCauseCode::AscribeUserTypeProvePredicate(def_id, span) => {
1901+
SubregionOrigin::AscribeUserTypeProvePredicate(def_id, span)
19001902
}
19011903

19021904
_ => default(),

compiler/rustc_infer/src/infer/outlives/obligations.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ use crate::infer::snapshot::undo_log::UndoLog;
6767
use crate::infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound};
6868
use crate::traits::{ObligationCause, ObligationCauseCode};
6969
use rustc_data_structures::undo_log::UndoLogs;
70+
use rustc_hir::def_id::CRATE_DEF_ID;
7071
use rustc_middle::mir::ConstraintCategory;
7172
use rustc_middle::traits::query::NoSolution;
7273
use rustc_middle::ty::{
@@ -148,11 +149,20 @@ impl<'tcx> InferCtxt<'tcx> {
148149
Some(
149150
deeply_normalize_ty(
150151
outlives,
151-
SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP),
152+
SubregionOrigin::AscribeUserTypeProvePredicate(
153+
CRATE_DEF_ID.to_def_id(),
154+
DUMMY_SP,
155+
),
152156
)
153157
// FIXME(-Znext-solver): How do we accurately report an error span here :(
154158
.map_err(|NoSolution| {
155-
(outlives, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP))
159+
(
160+
outlives,
161+
SubregionOrigin::AscribeUserTypeProvePredicate(
162+
CRATE_DEF_ID.to_def_id(),
163+
DUMMY_SP,
164+
),
165+
)
156166
}),
157167
)
158168
})

compiler/rustc_middle/src/mir/query.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::mir;
44
use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt};
55
use rustc_data_structures::fx::FxIndexMap;
66
use rustc_errors::ErrorGuaranteed;
7-
use rustc_hir::def_id::LocalDefId;
7+
use rustc_hir::def_id::{DefId, LocalDefId};
88
use rustc_index::bit_set::BitMatrix;
99
use rustc_index::{Idx, IndexVec};
1010
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
@@ -263,7 +263,7 @@ pub enum ConstraintCategory<'tcx> {
263263
/// A constraint from a user-written predicate
264264
/// with the provided span, written on the item
265265
/// with the given `DefId`
266-
Predicate(Span),
266+
Predicate(#[derivative(PartialOrd = "ignore", Ord = "ignore")] DefId, Span),
267267

268268
/// A "boring" constraint (caused by the given location) is one that
269269
/// the user probably doesn't want to see described in diagnostics,

compiler/rustc_middle/src/traits/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,9 @@ impl<'tcx> ObligationCause<'tcx> {
189189

190190
pub fn to_constraint_category(&self) -> ConstraintCategory<'tcx> {
191191
match self.code() {
192-
MatchImpl(cause, _) => cause.to_constraint_category(),
193-
AscribeUserTypeProvePredicate(predicate_span) => {
194-
ConstraintCategory::Predicate(*predicate_span)
192+
ObligationCauseCode::MatchImpl(cause, _) => cause.to_constraint_category(),
193+
ObligationCauseCode::AscribeUserTypeProvePredicate(def_id, predicate_span) => {
194+
ConstraintCategory::Predicate(*def_id, *predicate_span)
195195
}
196196
_ => ConstraintCategory::BoringNoLocation,
197197
}
@@ -447,7 +447,7 @@ pub enum ObligationCauseCode<'tcx> {
447447
output_ty: Option<Ty<'tcx>>,
448448
},
449449

450-
AscribeUserTypeProvePredicate(Span),
450+
AscribeUserTypeProvePredicate(DefId, Span),
451451

452452
RustCall,
453453

compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ fn relate_mir_and_user_args<'tcx>(
107107
let span = if span == DUMMY_SP { predicate_span } else { span };
108108
let cause = ObligationCause::new(
109109
span,
110-
CRATE_DEF_ID,
111-
ObligationCauseCode::AscribeUserTypeProvePredicate(predicate_span),
110+
def_id.as_local().unwrap_or(CRATE_DEF_ID),
111+
ObligationCauseCode::AscribeUserTypeProvePredicate(def_id, predicate_span),
112112
);
113113
let instantiated_predicate =
114114
ocx.normalize(&cause.clone(), param_env, instantiated_predicate);
@@ -118,7 +118,7 @@ fn relate_mir_and_user_args<'tcx>(
118118

119119
// Now prove the well-formedness of `def_id` with `args`.
120120
// Note for some items, proving the WF of `ty` is not sufficient because the
121-
// well-formedness of an item may depend on the WF of gneneric args not present in the
121+
// well-formedness of an item may depend on the WF of generic args not present in the
122122
// item's type. Currently this is true for associated consts, e.g.:
123123
// ```rust
124124
// impl<T> MyTy<T> {

tests/ui/coroutine/resume-arg-late-bound.stderr

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
error: implementation of `Coroutine` is not general enough
22
--> $DIR/resume-arg-late-bound.rs:15:5
33
|
4+
LL | fn test(a: impl for<'a> Coroutine<&'a mut bool>) {}
5+
| ------------------------------- due to a where-clause on `test`...
6+
...
47
LL | test(gen);
5-
| ^^^^^^^^^ implementation of `Coroutine` is not general enough
8+
| ^^^^^^^^^ doesn't satisfy where-clause
69
|
7-
= note: `{coroutine@$DIR/resume-arg-late-bound.rs:11:28: 11:44}` must implement `Coroutine<&'1 mut bool>`, for any lifetime `'1`...
10+
= note: ...`{coroutine@$DIR/resume-arg-late-bound.rs:11:28: 11:44}` must implement `Coroutine<&'1 mut bool>`, for any lifetime `'1`...
811
= note: ...but it actually implements `Coroutine<&'2 mut bool>`, for some specific lifetime `'2`
912

1013
error: aborting due to 1 previous error

tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
error: implementation of `Trait` is not general enough
22
--> $DIR/candidate-from-env-universe-err-project.rs:28:5
33
|
4+
LL | fn trait_bound<T: for<'a> Trait<'a>>() {}
5+
| ----------------- due to a where-clause on `trait_bound`...
6+
...
47
LL | trait_bound::<T>();
5-
| ^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
8+
| ^^^^^^^^^^^^^^^^^^ doesn't satisfy where-clause
69
|
7-
= note: `T` must implement `Trait<'0>`, for any lifetime `'0`...
10+
= note: ...`T` must implement `Trait<'0>`, for any lifetime `'0`...
811
= note: ...but it actually implements `Trait<'static>`
912

1013
error: implementation of `Trait` is not general enough
1114
--> $DIR/candidate-from-env-universe-err-project.rs:39:5
1215
|
16+
LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
17+
| -------------------------------- due to a where-clause on `projection_bound`...
18+
...
1319
LL | projection_bound::<T>();
14-
| ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
20+
| ^^^^^^^^^^^^^^^^^^^^^^^ doesn't satisfy where-clause
1521
|
16-
= note: `T` must implement `Trait<'0>`, for any lifetime `'0`...
22+
= note: ...`T` must implement `Trait<'0>`, for any lifetime `'0`...
1723
= note: ...but it actually implements `Trait<'static>`
1824

1925
error[E0308]: mismatched types

tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
error: implementation of `Bar` is not general enough
22
--> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:5
33
|
4+
LL | where B : for<'ccx> Bar<'ccx>
5+
| ------------------- due to a where-clause on `want_bar_for_any_ccx`...
6+
...
47
LL | want_bar_for_any_ccx(b);
5-
| ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough
8+
| ^^^^^^^^^^^^^^^^^^^^^^^ doesn't satisfy where-clause
69
|
7-
= note: `B` must implement `Bar<'0>`, for any lifetime `'0`...
10+
= note: ...`B` must implement `Bar<'0>`, for any lifetime `'0`...
811
= note: ...but it actually implements `Bar<'static>`
912

1013
error: aborting due to 1 previous error

tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr

+10-4
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@ error: implementation of `Foo` is not general enough
1717
--> $DIR/hrtb-higher-ranker-supertraits.rs:14:5
1818
|
1919
LL | want_foo_for_any_tcx(f);
20-
| ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
20+
| ^^^^^^^^^^^^^^^^^^^^^^^ doesn't satisfy where-clause
21+
...
22+
LL | fn want_foo_for_any_tcx<F: for<'tcx> Foo<'tcx>>(f: &F) {
23+
| ------------------- due to a where-clause on `want_foo_for_any_tcx`...
2124
|
22-
= note: `F` must implement `Foo<'0>`, for any lifetime `'0`...
25+
= note: ...`F` must implement `Foo<'0>`, for any lifetime `'0`...
2326
= note: ...but it actually implements `Foo<'1>`, for some specific lifetime `'1`
2427

2528
error: lifetime may not live long enough
@@ -41,9 +44,12 @@ error: implementation of `Bar` is not general enough
4144
--> $DIR/hrtb-higher-ranker-supertraits.rs:29:5
4245
|
4346
LL | want_bar_for_any_ccx(b);
44-
| ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough
47+
| ^^^^^^^^^^^^^^^^^^^^^^^ doesn't satisfy where-clause
48+
...
49+
LL | fn want_bar_for_any_ccx<B: for<'ccx> Bar<'ccx>>(b: &B) {
50+
| ------------------- due to a where-clause on `want_bar_for_any_ccx`...
4551
|
46-
= note: `B` must implement `Bar<'0>`, for any lifetime `'0`...
52+
= note: ...`B` must implement `Bar<'0>`, for any lifetime `'0`...
4753
= note: ...but it actually implements `Bar<'1>`, for some specific lifetime `'1`
4854

4955
error: aborting due to 4 previous errors

tests/ui/higher-ranked/trait-bounds/issue-59311.stderr

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
error: implementation of `Trait` is not general enough
22
--> $DIR/issue-59311.rs:17:5
33
|
4+
LL | for<'a> &'a V: Trait + 'static,
5+
| ----- due to a where-clause on `crash`...
6+
LL | {
47
LL | v.t(|| {});
5-
| ^^^^^^^^^^ implementation of `Trait` is not general enough
8+
| ^^^^^^^^^^ doesn't satisfy where-clause
69
|
7-
= note: `Trait` would have to be implemented for the type `&'a V`
10+
= note: ...`Trait` would have to be implemented for the type `&'a V`
811
= note: ...but `Trait` is actually implemented for the type `&'0 V`, for some specific lifetime `'0`
912

1013
error: implementation of `Trait` is not general enough
1114
--> $DIR/issue-59311.rs:17:5
1215
|
16+
LL | for<'a> &'a V: Trait + 'static,
17+
| ----- due to a where-clause on `crash`...
18+
LL | {
1319
LL | v.t(|| {});
14-
| ^^^^^^^^^^ implementation of `Trait` is not general enough
20+
| ^^^^^^^^^^ doesn't satisfy where-clause
1521
|
16-
= note: `Trait` would have to be implemented for the type `&'a V`
22+
= note: ...`Trait` would have to be implemented for the type `&'a V`
1723
= note: ...but `Trait` is actually implemented for the type `&'0 V`, for some specific lifetime `'0`
1824
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
1925

0 commit comments

Comments
 (0)