Skip to content

Commit 5adc7a5

Browse files
author
Yuki Okushi
authored
Rollup merge of #106785 - compiler-errors:better-impl-wf-spans, r=estebank
Make blame spans better for impl wfcheck r? types
2 parents 796847a + 5924c25 commit 5adc7a5

21 files changed

+106
-83
lines changed

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -1254,7 +1254,11 @@ fn check_impl<'tcx>(
12541254
// therefore don't need to be WF (the trait's `Self: Trait` predicate
12551255
// won't hold).
12561256
let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap();
1257-
let trait_ref = wfcx.normalize(ast_trait_ref.path.span, None, trait_ref);
1257+
let trait_ref = wfcx.normalize(
1258+
ast_trait_ref.path.span,
1259+
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
1260+
trait_ref,
1261+
);
12581262
let trait_pred = ty::TraitPredicate {
12591263
trait_ref,
12601264
constness: match constness {
@@ -1263,14 +1267,21 @@ fn check_impl<'tcx>(
12631267
},
12641268
polarity: ty::ImplPolarity::Positive,
12651269
};
1266-
let obligations = traits::wf::trait_obligations(
1270+
let mut obligations = traits::wf::trait_obligations(
12671271
wfcx.infcx,
12681272
wfcx.param_env,
12691273
wfcx.body_id,
12701274
&trait_pred,
12711275
ast_trait_ref.path.span,
12721276
item,
12731277
);
1278+
for obligation in &mut obligations {
1279+
if let Some(pred) = obligation.predicate.to_opt_poly_trait_pred()
1280+
&& pred.self_ty().skip_binder() == trait_ref.self_ty()
1281+
{
1282+
obligation.cause.span = ast_self_ty.span;
1283+
}
1284+
}
12741285
debug!(?obligations);
12751286
wfcx.register_obligations(obligations);
12761287
}

compiler/rustc_hir_analysis/src/hir_wf_check.rs

+29-17
Original file line numberDiff line numberDiff line change
@@ -114,51 +114,63 @@ fn diagnostic_hir_wf_check<'tcx>(
114114
// Get the starting `hir::Ty` using our `WellFormedLoc`.
115115
// We will walk 'into' this type to try to find
116116
// a more precise span for our predicate.
117-
let ty = match loc {
117+
let tys = match loc {
118118
WellFormedLoc::Ty(_) => match hir.get(hir_id) {
119119
hir::Node::ImplItem(item) => match item.kind {
120-
hir::ImplItemKind::Type(ty) => Some(ty),
121-
hir::ImplItemKind::Const(ty, _) => Some(ty),
120+
hir::ImplItemKind::Type(ty) => vec![ty],
121+
hir::ImplItemKind::Const(ty, _) => vec![ty],
122122
ref item => bug!("Unexpected ImplItem {:?}", item),
123123
},
124124
hir::Node::TraitItem(item) => match item.kind {
125-
hir::TraitItemKind::Type(_, ty) => ty,
126-
hir::TraitItemKind::Const(ty, _) => Some(ty),
125+
hir::TraitItemKind::Type(_, ty) => ty.into_iter().collect(),
126+
hir::TraitItemKind::Const(ty, _) => vec![ty],
127127
ref item => bug!("Unexpected TraitItem {:?}", item),
128128
},
129129
hir::Node::Item(item) => match item.kind {
130-
hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => Some(ty),
131-
hir::ItemKind::Impl(ref impl_) => {
132-
assert!(impl_.of_trait.is_none(), "Unexpected trait impl: {:?}", impl_);
133-
Some(impl_.self_ty)
134-
}
130+
hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => vec![ty],
131+
hir::ItemKind::Impl(ref impl_) => match &impl_.of_trait {
132+
Some(t) => t
133+
.path
134+
.segments
135+
.last()
136+
.iter()
137+
.flat_map(|seg| seg.args().args)
138+
.filter_map(|arg| {
139+
if let hir::GenericArg::Type(ty) = arg { Some(*ty) } else { None }
140+
})
141+
.chain([impl_.self_ty])
142+
.collect(),
143+
None => {
144+
vec![impl_.self_ty]
145+
}
146+
},
135147
ref item => bug!("Unexpected item {:?}", item),
136148
},
137-
hir::Node::Field(field) => Some(field.ty),
149+
hir::Node::Field(field) => vec![field.ty],
138150
hir::Node::ForeignItem(ForeignItem {
139151
kind: ForeignItemKind::Static(ty, _), ..
140-
}) => Some(*ty),
152+
}) => vec![*ty],
141153
hir::Node::GenericParam(hir::GenericParam {
142154
kind: hir::GenericParamKind::Type { default: Some(ty), .. },
143155
..
144-
}) => Some(*ty),
156+
}) => vec![*ty],
145157
ref node => bug!("Unexpected node {:?}", node),
146158
},
147159
WellFormedLoc::Param { function: _, param_idx } => {
148160
let fn_decl = hir.fn_decl_by_hir_id(hir_id).unwrap();
149161
// Get return type
150162
if param_idx as usize == fn_decl.inputs.len() {
151163
match fn_decl.output {
152-
hir::FnRetTy::Return(ty) => Some(ty),
164+
hir::FnRetTy::Return(ty) => vec![ty],
153165
// The unit type `()` is always well-formed
154-
hir::FnRetTy::DefaultReturn(_span) => None,
166+
hir::FnRetTy::DefaultReturn(_span) => vec![],
155167
}
156168
} else {
157-
Some(&fn_decl.inputs[param_idx as usize])
169+
vec![&fn_decl.inputs[param_idx as usize]]
158170
}
159171
}
160172
};
161-
if let Some(ty) = ty {
173+
for ty in tys {
162174
visitor.visit_ty(ty);
163175
}
164176
visitor.cause

tests/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: `T` cannot be sent between threads safely
2-
--> $DIR/builtin-superkinds-double-superkind.rs:6:24
2+
--> $DIR/builtin-superkinds-double-superkind.rs:6:32
33
|
44
LL | impl <T: Sync+'static> Foo for (T,) { }
5-
| ^^^ `T` cannot be sent between threads safely
5+
| ^^^^ `T` cannot be sent between threads safely
66
|
77
= note: required because it appears within the type `(T,)`
88
note: required by a bound in `Foo`
@@ -16,10 +16,10 @@ LL | impl <T: Sync+'static + std::marker::Send> Foo for (T,) { }
1616
| +++++++++++++++++++
1717

1818
error[E0277]: `T` cannot be shared between threads safely
19-
--> $DIR/builtin-superkinds-double-superkind.rs:9:16
19+
--> $DIR/builtin-superkinds-double-superkind.rs:9:24
2020
|
2121
LL | impl <T: Send> Foo for (T,T) { }
22-
| ^^^ `T` cannot be shared between threads safely
22+
| ^^^^^ `T` cannot be shared between threads safely
2323
|
2424
= note: required because it appears within the type `(T, T)`
2525
note: required by a bound in `Foo`

tests/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: `T` cannot be sent between threads safely
2-
--> $DIR/builtin-superkinds-in-metadata.rs:13:23
2+
--> $DIR/builtin-superkinds-in-metadata.rs:13:56
33
|
44
LL | impl <T:Sync+'static> RequiresRequiresShareAndSend for X<T> { }
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `T` cannot be sent between threads safely
5+
| ^^^^ `T` cannot be sent between threads safely
66
|
77
note: required because it appears within the type `X<T>`
88
--> $DIR/builtin-superkinds-in-metadata.rs:9:8

tests/ui/builtin-superkinds/builtin-superkinds-simple.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: `Rc<i8>` cannot be sent between threads safely
2-
--> $DIR/builtin-superkinds-simple.rs:6:6
2+
--> $DIR/builtin-superkinds-simple.rs:6:14
33
|
44
LL | impl Foo for std::rc::Rc<i8> { }
5-
| ^^^ `Rc<i8>` cannot be sent between threads safely
5+
| ^^^^^^^^^^^^^^^ `Rc<i8>` cannot be sent between threads safely
66
|
77
= help: the trait `Send` is not implemented for `Rc<i8>`
88
note: required by a bound in `Foo`

tests/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: `T` cannot be sent between threads safely
2-
--> $DIR/builtin-superkinds-typaram-not-send.rs:5:24
2+
--> $DIR/builtin-superkinds-typaram-not-send.rs:5:32
33
|
44
LL | impl <T: Sync+'static> Foo for T { }
5-
| ^^^ `T` cannot be sent between threads safely
5+
| ^ `T` cannot be sent between threads safely
66
|
77
note: required by a bound in `Foo`
88
--> $DIR/builtin-superkinds-typaram-not-send.rs:3:13

tests/ui/chalkify/impl_wf.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the size for values of type `str` cannot be known at compilation time
2-
--> $DIR/impl_wf.rs:11:6
2+
--> $DIR/impl_wf.rs:11:14
33
|
44
LL | impl Foo for str { }
5-
| ^^^ doesn't have a size known at compile-time
5+
| ^^^ doesn't have a size known at compile-time
66
|
77
= help: the trait `Sized` is not implemented for `str`
88
note: required by a bound in `Foo`
@@ -12,10 +12,10 @@ LL | trait Foo: Sized { }
1212
| ^^^^^ required by this bound in `Foo`
1313

1414
error[E0277]: the trait bound `f32: Foo` is not satisfied
15-
--> $DIR/impl_wf.rs:22:6
15+
--> $DIR/impl_wf.rs:22:19
1616
|
1717
LL | impl Baz<f32> for f32 { }
18-
| ^^^^^^^^ the trait `Foo` is not implemented for `f32`
18+
| ^^^ the trait `Foo` is not implemented for `f32`
1919
|
2020
= help: the trait `Foo` is implemented for `i32`
2121
note: required by a bound in `Baz`

tests/ui/coherence/coherence-overlap-trait-alias.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0283]: type annotations needed: cannot satisfy `u32: C`
2-
--> $DIR/coherence-overlap-trait-alias.rs:15:6
2+
--> $DIR/coherence-overlap-trait-alias.rs:15:12
33
|
44
LL | impl C for u32 {}
5-
| ^
5+
| ^^^
66
|
77
note: multiple `impl`s satisfying `u32: C` found
88
--> $DIR/coherence-overlap-trait-alias.rs:14:1

tests/ui/dst/dst-sized-trait-param.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ LL | trait Foo<T: ?Sized> : Sized { fn take(self, x: &T) { } } // Note: T is siz
1616
| ++++++++
1717

1818
error[E0277]: the size for values of type `[usize]` cannot be known at compilation time
19-
--> $DIR/dst-sized-trait-param.rs:10:6
19+
--> $DIR/dst-sized-trait-param.rs:10:21
2020
|
2121
LL | impl Foo<isize> for [usize] { }
22-
| ^^^^^^^^^^ doesn't have a size known at compile-time
22+
| ^^^^^^^ doesn't have a size known at compile-time
2323
|
2424
= help: the trait `Sized` is not implemented for `[usize]`
2525
note: required by a bound in `Foo`

tests/ui/error-codes/E0308-2.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0308]: mismatched types
2-
--> $DIR/E0308-2.rs:9:6
2+
--> $DIR/E0308-2.rs:9:13
33
|
44
LL | impl Eq for &dyn DynEq {}
5-
| ^^ lifetime mismatch
5+
| ^^^^^^^^^^ lifetime mismatch
66
|
77
= note: expected trait `<&dyn DynEq as PartialEq>`
88
found trait `<&(dyn DynEq + 'static) as PartialEq>`

tests/ui/issues/issue-65230.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0308]: mismatched types
2-
--> $DIR/issue-65230.rs:8:6
2+
--> $DIR/issue-65230.rs:8:13
33
|
44
LL | impl T1 for &dyn T2 {}
5-
| ^^ lifetime mismatch
5+
| ^^^^^^^ lifetime mismatch
66
|
77
= note: expected trait `<&dyn T2 as T0>`
88
found trait `<&(dyn T2 + 'static) as T0>`

tests/ui/marker_trait_attr/overlap-marker-trait-with-underscore-lifetime.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0283]: type annotations needed: cannot satisfy `&(): Marker`
2-
--> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:6:6
2+
--> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:6:17
33
|
44
LL | impl Marker for &'_ () {}
5-
| ^^^^^^
5+
| ^^^^^^
66
|
77
note: multiple `impl`s satisfying `&(): Marker` found
88
--> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:6:1
@@ -13,10 +13,10 @@ LL | impl Marker for &'_ () {}
1313
| ^^^^^^^^^^^^^^^^^^^^^^
1414

1515
error[E0283]: type annotations needed: cannot satisfy `&(): Marker`
16-
--> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:7:6
16+
--> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:7:17
1717
|
1818
LL | impl Marker for &'_ () {}
19-
| ^^^^^^
19+
| ^^^^^^
2020
|
2121
note: multiple `impl`s satisfying `&(): Marker` found
2222
--> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:6:1

tests/ui/marker_trait_attr/region-overlap.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0283]: type annotations needed: cannot satisfy `(&'static (), &'a ()): A`
2-
--> $DIR/region-overlap.rs:5:10
2+
--> $DIR/region-overlap.rs:5:16
33
|
44
LL | impl<'a> A for (&'static (), &'a ()) {}
5-
| ^
5+
| ^^^^^^^^^^^^^^^^^^^^^
66
|
77
note: multiple `impl`s satisfying `(&'static (), &'a ()): A` found
88
--> $DIR/region-overlap.rs:5:1
@@ -13,10 +13,10 @@ LL | impl<'a> A for (&'a (), &'static ()) {}
1313
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1414

1515
error[E0283]: type annotations needed: cannot satisfy `(&'a (), &'static ()): A`
16-
--> $DIR/region-overlap.rs:6:10
16+
--> $DIR/region-overlap.rs:6:16
1717
|
1818
LL | impl<'a> A for (&'a (), &'static ()) {}
19-
| ^
19+
| ^^^^^^^^^^^^^^^^^^^^^
2020
|
2121
note: multiple `impl`s satisfying `(&'a (), &'static ()): A` found
2222
--> $DIR/region-overlap.rs:5:1

tests/ui/rfc-2632-const-trait-impl/super-traits-fail.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
error[E0277]: the trait bound `S: ~const Foo` is not satisfied
2-
--> $DIR/super-traits-fail.rs:15:12
2+
--> $DIR/super-traits-fail.rs:15:20
33
|
44
LL | impl const Bar for S {}
5-
| ^^^ the trait `~const Foo` is not implemented for `S`
5+
| ^ the trait `~const Foo` is not implemented for `S`
66
|
77
note: the trait `Foo` is implemented for `S`, but that implementation is not `const`
8-
--> $DIR/super-traits-fail.rs:15:12
8+
--> $DIR/super-traits-fail.rs:15:20
99
|
1010
LL | impl const Bar for S {}
11-
| ^^^
11+
| ^
1212
note: required by a bound in `Bar`
1313
--> $DIR/super-traits-fail.rs:8:12
1414
|

tests/ui/span/issue-71363.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
error[E0277]: `MyError` doesn't implement `std::fmt::Display`
2-
--> $DIR/issue-71363.rs:4:6
2+
--> $DIR/issue-71363.rs:4:28
33
|
44
4 | impl std::error::Error for MyError {}
5-
| ^^^^^^^^^^^^^^^^^ `MyError` cannot be formatted with the default formatter
5+
| ^^^^^^^ `MyError` cannot be formatted with the default formatter
66
|
77
= help: the trait `std::fmt::Display` is not implemented for `MyError`
88
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
99
note: required by a bound in `std::error::Error`
1010
--> $SRC_DIR/core/src/error.rs:LL:COL
1111

1212
error[E0277]: `MyError` doesn't implement `Debug`
13-
--> $DIR/issue-71363.rs:4:6
13+
--> $DIR/issue-71363.rs:4:28
1414
|
1515
4 | impl std::error::Error for MyError {}
16-
| ^^^^^^^^^^^^^^^^^ `MyError` cannot be formatted using `{:?}`
16+
| ^^^^^^^ `MyError` cannot be formatted using `{:?}`
1717
|
1818
= help: the trait `Debug` is not implemented for `MyError`
1919
= note: add `#[derive(Debug)]` to `MyError` or manually `impl Debug for MyError`

tests/ui/specialization/min_specialization/issue-79224.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `B: Clone` is not satisfied
2-
--> $DIR/issue-79224.rs:18:17
2+
--> $DIR/issue-79224.rs:18:29
33
|
44
LL | impl<B: ?Sized> Display for Cow<'_, B> {
5-
| ^^^^^^^ the trait `Clone` is not implemented for `B`
5+
| ^^^^^^^^^^ the trait `Clone` is not implemented for `B`
66
|
77
= note: required for `B` to implement `ToOwned`
88
help: consider further restricting this bound

0 commit comments

Comments
 (0)