Skip to content

Commit 23ad7a7

Browse files
authored
Rollup merge of rust-lang#90884 - Nilstrieb:fix-span-trivial-trait-bound, r=estebank
Fix span for non-satisfied trivial trait bounds The spans for "trait bound not satisfied" errors in trivial trait bounds referenced the entire item (fn, impl, struct) before. Now they only reference the obligation itself (`String: Copy`) Address rust-lang#90869
2 parents ab958a7 + 24acf86 commit 23ad7a7

File tree

8 files changed

+102
-104
lines changed

8 files changed

+102
-104
lines changed

compiler/rustc_infer/src/traits/util.rs

+17
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::traits::{Obligation, ObligationCause, PredicateObligation};
55
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
66
use rustc_middle::ty::{self, ToPredicate, TyCtxt, WithConstness};
77
use rustc_span::symbol::Ident;
8+
use rustc_span::Span;
89

910
pub fn anonymize_predicate<'tcx>(
1011
tcx: TyCtxt<'tcx>,
@@ -97,6 +98,22 @@ pub fn elaborate_predicates<'tcx>(
9798
elaborate_obligations(tcx, obligations)
9899
}
99100

101+
pub fn elaborate_predicates_with_span<'tcx>(
102+
tcx: TyCtxt<'tcx>,
103+
predicates: impl Iterator<Item = (ty::Predicate<'tcx>, Span)>,
104+
) -> Elaborator<'tcx> {
105+
let obligations = predicates
106+
.map(|(predicate, span)| {
107+
predicate_obligation(
108+
predicate,
109+
ty::ParamEnv::empty(),
110+
ObligationCause::dummy_with_span(span),
111+
)
112+
})
113+
.collect();
114+
elaborate_obligations(tcx, obligations)
115+
}
116+
100117
pub fn elaborate_obligations<'tcx>(
101118
tcx: TyCtxt<'tcx>,
102119
mut obligations: Vec<PredicateObligation<'tcx>>,

compiler/rustc_trait_selection/src/traits/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ pub use self::specialize::{specialization_graph, translate_substs, OverlapError}
6565
pub use self::structural_match::search_for_structural_match_violation;
6666
pub use self::structural_match::NonStructuralMatchTy;
6767
pub use self::util::{
68-
elaborate_obligations, elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs,
68+
elaborate_obligations, elaborate_predicates, elaborate_predicates_with_span,
69+
elaborate_trait_ref, elaborate_trait_refs,
6970
};
7071
pub use self::util::{expand_trait_aliases, TraitAliasExpander};
7172
pub use self::util::{

compiler/rustc_typeck/src/check/wfcheck.rs

+22-3
Original file line numberDiff line numberDiff line change
@@ -1641,19 +1641,38 @@ fn report_bivariance(tcx: TyCtxt<'_>, param: &rustc_hir::GenericParam<'_>) {
16411641

16421642
/// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
16431643
/// aren't true.
1644-
fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, span: Span, id: hir::HirId) {
1644+
fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, mut span: Span, id: hir::HirId) {
16451645
let empty_env = ty::ParamEnv::empty();
16461646

16471647
let def_id = fcx.tcx.hir().local_def_id(id);
1648-
let predicates = fcx.tcx.predicates_of(def_id).predicates.iter().map(|(p, _)| *p);
1648+
let predicates_with_span =
1649+
fcx.tcx.predicates_of(def_id).predicates.iter().map(|(p, span)| (*p, *span));
16491650
// Check elaborated bounds.
1650-
let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates);
1651+
let implied_obligations = traits::elaborate_predicates_with_span(fcx.tcx, predicates_with_span);
16511652

16521653
for obligation in implied_obligations {
16531654
let pred = obligation.predicate;
16541655
// Match the existing behavior.
16551656
if pred.is_global(fcx.tcx) && !pred.has_late_bound_regions() {
16561657
let pred = fcx.normalize_associated_types_in(span, pred);
1658+
let hir_node = fcx.tcx.hir().find(id);
1659+
1660+
// only use the span of the predicate clause (#90869)
1661+
1662+
if let Some(hir::Generics { where_clause, .. }) =
1663+
hir_node.and_then(|node| node.generics())
1664+
{
1665+
let obligation_span = obligation.cause.span(fcx.tcx);
1666+
1667+
span = where_clause
1668+
.predicates
1669+
.iter()
1670+
// There seems to be no better way to find out which predicate we are in
1671+
.find(|pred| pred.span().contains(obligation_span))
1672+
.map(|pred| pred.span())
1673+
.unwrap_or(obligation_span);
1674+
}
1675+
16571676
let obligation = traits::Obligation::new(
16581677
traits::ObligationCause::new(span, id, traits::TrivialBound),
16591678
empty_env,

src/test/ui/const-generics/issues/issue-67185-2.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ trait Bar {}
99
impl Bar for [u16; 4] {}
1010
impl Bar for [[u16; 3]; 3] {}
1111

12-
trait Foo //~ ERROR the trait bound `[u16; 3]: Bar` is not satisfied [E0277]
13-
//~^ ERROR the trait bound `[[u16; 3]; 2]: Bar` is not satisfied [E0277]
14-
where
15-
[<u8 as Baz>::Quaks; 2]: Bar,
16-
<u8 as Baz>::Quaks: Bar,
12+
trait Foo
13+
where
14+
[<u8 as Baz>::Quaks; 2]: Bar, //~ ERROR the trait bound `[[u16; 3]; 2]: Bar` is not satisfied [E0277]
15+
<u8 as Baz>::Quaks: Bar, //~ ERROR the trait bound `[u16; 3]: Bar` is not satisfied [E0277]
1716
{
1817
}
1918

src/test/ui/const-generics/issues/issue-67185-2.stderr

+24-36
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
2-
--> $DIR/issue-67185-2.rs:12:1
2+
--> $DIR/issue-67185-2.rs:15:5
33
|
4-
LL | / trait Foo
5-
LL | |
6-
LL | | where
7-
LL | | [<u8 as Baz>::Quaks; 2]: Bar,
8-
LL | | <u8 as Baz>::Quaks: Bar,
9-
LL | | {
10-
LL | | }
11-
| |_^ the trait `Bar` is not implemented for `[u16; 3]`
4+
LL | <u8 as Baz>::Quaks: Bar,
5+
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `[u16; 3]`
126
|
137
= help: the following implementations were found:
148
<[[u16; 3]; 3] as Bar>
@@ -17,16 +11,10 @@ LL | | }
1711
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
1812

1913
error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
20-
--> $DIR/issue-67185-2.rs:12:1
14+
--> $DIR/issue-67185-2.rs:14:5
2115
|
22-
LL | / trait Foo
23-
LL | |
24-
LL | | where
25-
LL | | [<u8 as Baz>::Quaks; 2]: Bar,
26-
LL | | <u8 as Baz>::Quaks: Bar,
27-
LL | | {
28-
LL | | }
29-
| |_^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
16+
LL | [<u8 as Baz>::Quaks; 2]: Bar,
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
3018
|
3119
= help: the following implementations were found:
3220
<[[u16; 3]; 3] as Bar>
@@ -35,7 +23,7 @@ LL | | }
3523
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
3624

3725
error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
38-
--> $DIR/issue-67185-2.rs:22:6
26+
--> $DIR/issue-67185-2.rs:21:6
3927
|
4028
LL | impl Foo for FooImpl {}
4129
| ^^^ the trait `Bar` is not implemented for `[u16; 3]`
@@ -44,16 +32,16 @@ LL | impl Foo for FooImpl {}
4432
<[[u16; 3]; 3] as Bar>
4533
<[u16; 4] as Bar>
4634
note: required by a bound in `Foo`
47-
--> $DIR/issue-67185-2.rs:16:29
35+
--> $DIR/issue-67185-2.rs:15:25
4836
|
4937
LL | trait Foo
5038
| --- required by a bound in this
5139
...
52-
LL | <u8 as Baz>::Quaks: Bar,
53-
| ^^^ required by this bound in `Foo`
40+
LL | <u8 as Baz>::Quaks: Bar,
41+
| ^^^ required by this bound in `Foo`
5442

5543
error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
56-
--> $DIR/issue-67185-2.rs:22:6
44+
--> $DIR/issue-67185-2.rs:21:6
5745
|
5846
LL | impl Foo for FooImpl {}
5947
| ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
@@ -62,16 +50,16 @@ LL | impl Foo for FooImpl {}
6250
<[[u16; 3]; 3] as Bar>
6351
<[u16; 4] as Bar>
6452
note: required by a bound in `Foo`
65-
--> $DIR/issue-67185-2.rs:15:34
53+
--> $DIR/issue-67185-2.rs:14:30
6654
|
6755
LL | trait Foo
6856
| --- required by a bound in this
69-
...
70-
LL | [<u8 as Baz>::Quaks; 2]: Bar,
71-
| ^^^ required by this bound in `Foo`
57+
LL | where
58+
LL | [<u8 as Baz>::Quaks; 2]: Bar,
59+
| ^^^ required by this bound in `Foo`
7260

7361
error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
74-
--> $DIR/issue-67185-2.rs:26:14
62+
--> $DIR/issue-67185-2.rs:25:14
7563
|
7664
LL | fn f(_: impl Foo) {}
7765
| ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
@@ -80,16 +68,16 @@ LL | fn f(_: impl Foo) {}
8068
<[[u16; 3]; 3] as Bar>
8169
<[u16; 4] as Bar>
8270
note: required by a bound in `Foo`
83-
--> $DIR/issue-67185-2.rs:15:34
71+
--> $DIR/issue-67185-2.rs:14:30
8472
|
8573
LL | trait Foo
8674
| --- required by a bound in this
87-
...
88-
LL | [<u8 as Baz>::Quaks; 2]: Bar,
89-
| ^^^ required by this bound in `Foo`
75+
LL | where
76+
LL | [<u8 as Baz>::Quaks; 2]: Bar,
77+
| ^^^ required by this bound in `Foo`
9078

9179
error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
92-
--> $DIR/issue-67185-2.rs:26:14
80+
--> $DIR/issue-67185-2.rs:25:14
9381
|
9482
LL | fn f(_: impl Foo) {}
9583
| ^^^ the trait `Bar` is not implemented for `[u16; 3]`
@@ -98,13 +86,13 @@ LL | fn f(_: impl Foo) {}
9886
<[[u16; 3]; 3] as Bar>
9987
<[u16; 4] as Bar>
10088
note: required by a bound in `Foo`
101-
--> $DIR/issue-67185-2.rs:16:29
89+
--> $DIR/issue-67185-2.rs:15:25
10290
|
10391
LL | trait Foo
10492
| --- required by a bound in this
10593
...
106-
LL | <u8 as Baz>::Quaks: Bar,
107-
| ^^^ required by this bound in `Foo`
94+
LL | <u8 as Baz>::Quaks: Bar,
95+
| ^^^ required by this bound in `Foo`
10896

10997
error: aborting due to 6 previous errors
11098

src/test/ui/cross/cross-fn-cache-hole.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ trait Bar<X> { }
1212

1313
// We don't always check where clauses for sanity, but in this case
1414
// wfcheck does report an error here:
15-
fn vacuous<A>() //~ ERROR the trait bound `i32: Bar<u32>` is not satisfied
16-
where i32: Foo<u32, A>
15+
fn vacuous<A>()
16+
where i32: Foo<u32, A> //~ ERROR the trait bound `i32: Bar<u32>` is not satisfied
1717
{
1818
// ... the original intention was to check that we don't use that
1919
// vacuous where clause (which could never be satisfied) to accept

src/test/ui/cross/cross-fn-cache-hole.stderr

+3-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
error[E0277]: the trait bound `i32: Bar<u32>` is not satisfied
2-
--> $DIR/cross-fn-cache-hole.rs:15:1
2+
--> $DIR/cross-fn-cache-hole.rs:16:11
33
|
4-
LL | / fn vacuous<A>()
5-
LL | | where i32: Foo<u32, A>
6-
LL | | {
7-
LL | | // ... the original intention was to check that we don't use that
8-
... |
9-
LL | | require::<i32, u32>();
10-
LL | | }
11-
| |_^ the trait `Bar<u32>` is not implemented for `i32`
4+
LL | where i32: Foo<u32, A>
5+
| ^^^^^^^^^^^^^^^^ the trait `Bar<u32>` is not implemented for `i32`
126
|
137
= help: see issue #48214
148
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable

0 commit comments

Comments
 (0)