Skip to content

Commit 8ba7436

Browse files
better ObligationCause for normalization errors in can_type_implement_copy
1 parent 3d127e2 commit 8ba7436

File tree

8 files changed

+71
-22
lines changed

8 files changed

+71
-22
lines changed

compiler/rustc_lint/src/builtin.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ use rustc_span::source_map::Spanned;
5151
use rustc_span::symbol::{kw, sym, Ident, Symbol};
5252
use rustc_span::{BytePos, InnerSpan, MultiSpan, Span};
5353
use rustc_target::abi::VariantIdx;
54-
use rustc_trait_selection::traits::misc::can_type_implement_copy;
54+
use rustc_trait_selection::traits::{self, misc::can_type_implement_copy};
5555

5656
use crate::nonstandard_style::{method_context, MethodLateContext};
5757

@@ -764,7 +764,14 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
764764
if ty.is_copy_modulo_regions(cx.tcx.at(item.span), param_env) {
765765
return;
766766
}
767-
if can_type_implement_copy(cx.tcx, param_env, ty).is_ok() {
767+
if can_type_implement_copy(
768+
cx.tcx,
769+
param_env,
770+
ty,
771+
traits::ObligationCause::misc(item.span, item.hir_id()),
772+
)
773+
.is_ok()
774+
{
768775
cx.struct_span_lint(MISSING_COPY_IMPLEMENTATIONS, item.span, |lint| {
769776
lint.build(
770777
"type could implement `Copy`; consider adding `impl \

compiler/rustc_trait_selection/src/traits/misc.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub fn can_type_implement_copy<'tcx>(
2020
tcx: TyCtxt<'tcx>,
2121
param_env: ty::ParamEnv<'tcx>,
2222
self_type: Ty<'tcx>,
23+
cause: ObligationCause<'tcx>,
2324
) -> Result<(), CopyImplementationError<'tcx>> {
2425
// FIXME: (@jroesch) float this code up
2526
tcx.infer_ctxt().enter(|infcx| {
@@ -49,9 +50,8 @@ pub fn can_type_implement_copy<'tcx>(
4950
continue;
5051
}
5152
let span = tcx.def_span(field.did);
52-
let cause = ObligationCause::dummy_with_span(span);
5353
let ctx = traits::FulfillmentContext::new();
54-
match traits::fully_normalize(&infcx, ctx, cause, param_env, ty) {
54+
match traits::fully_normalize(&infcx, ctx, cause.clone(), param_env, ty) {
5555
Ok(ty) => {
5656
if !infcx.type_is_copy_modulo_regions(param_env, ty, span) {
5757
infringing.push(field);

compiler/rustc_typeck/src/coherence/builtin.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
7474

7575
debug!("visit_implementation_of_copy: self_type={:?} (free)", self_type);
7676

77-
match can_type_implement_copy(tcx, param_env, self_type) {
77+
let cause = traits::ObligationCause::misc(span, impl_hir_id);
78+
match can_type_implement_copy(tcx, param_env, self_type, cause) {
7879
Ok(()) => {}
7980
Err(CopyImplementationError::InfrigingFields(fields)) => {
8081
let item = tcx.hir().expect_item(impl_did);

src/test/ui/issues/issue-50480.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
#[derive(Clone, Copy)]
22
//~^ ERROR the trait `Copy` may not be implemented for this type
3+
//~| ERROR `i32` is not an iterator
34
struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
45
//~^ ERROR cannot find type `NotDefined` in this scope
56
//~| ERROR cannot find type `NotDefined` in this scope
67
//~| ERROR cannot find type `N` in this scope
78
//~| ERROR cannot find type `N` in this scope
8-
//~| ERROR `i32` is not an iterator
99

1010
#[derive(Clone, Copy)]
1111
//~^ ERROR the trait `Copy` may not be implemented for this type
12+
//~| ERROR `i32` is not an iterator
1213
struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
1314
//~^ ERROR cannot find type `NotDefined` in this scope
1415
//~| ERROR cannot find type `N` in this scope
15-
//~| ERROR `i32` is not an iterator
1616

1717
fn main() {}

src/test/ui/issues/issue-50480.stderr

+16-14
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
11
error[E0412]: cannot find type `N` in this scope
2-
--> $DIR/issue-50480.rs:3:12
2+
--> $DIR/issue-50480.rs:4:12
33
|
44
LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
55
| -^ not found in this scope
66
| |
77
| help: you might be missing a type parameter: `<N>`
88

99
error[E0412]: cannot find type `NotDefined` in this scope
10-
--> $DIR/issue-50480.rs:3:15
10+
--> $DIR/issue-50480.rs:4:15
1111
|
1212
LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
1313
| ^^^^^^^^^^ not found in this scope
1414

1515
error[E0412]: cannot find type `N` in this scope
16-
--> $DIR/issue-50480.rs:3:12
16+
--> $DIR/issue-50480.rs:4:12
1717
|
1818
LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
1919
| -^ not found in this scope
2020
| |
2121
| help: you might be missing a type parameter: `<N>`
2222

2323
error[E0412]: cannot find type `NotDefined` in this scope
24-
--> $DIR/issue-50480.rs:3:15
24+
--> $DIR/issue-50480.rs:4:15
2525
|
2626
LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
2727
| - ^^^^^^^^^^ not found in this scope
2828
| |
2929
| help: you might be missing a type parameter: `<NotDefined>`
3030

3131
error[E0412]: cannot find type `N` in this scope
32-
--> $DIR/issue-50480.rs:12:18
32+
--> $DIR/issue-50480.rs:13:18
3333
|
3434
LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
3535
| - ^
@@ -46,26 +46,27 @@ LL | struct Bar<T, N>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, Strin
4646
| +++
4747

4848
error[E0412]: cannot find type `NotDefined` in this scope
49-
--> $DIR/issue-50480.rs:12:21
49+
--> $DIR/issue-50480.rs:13:21
5050
|
5151
LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
5252
| ^^^^^^^^^^ not found in this scope
5353

5454
error[E0277]: `i32` is not an iterator
55-
--> $DIR/issue-50480.rs:3:27
55+
--> $DIR/issue-50480.rs:1:17
5656
|
57-
LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
58-
| ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator
57+
LL | #[derive(Clone, Copy)]
58+
| ^^^^ `i32` is not an iterator
5959
|
6060
= help: the trait `Iterator` is not implemented for `i32`
6161
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
62+
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
6263

6364
error[E0204]: the trait `Copy` may not be implemented for this type
6465
--> $DIR/issue-50480.rs:1:17
6566
|
6667
LL | #[derive(Clone, Copy)]
6768
| ^^^^
68-
LL |
69+
...
6970
LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
7071
| -------- ------ this field does not implement `Copy`
7172
| |
@@ -74,20 +75,21 @@ LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
7475
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
7576

7677
error[E0277]: `i32` is not an iterator
77-
--> $DIR/issue-50480.rs:12:33
78+
--> $DIR/issue-50480.rs:10:17
7879
|
79-
LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
80-
| ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator
80+
LL | #[derive(Clone, Copy)]
81+
| ^^^^ `i32` is not an iterator
8182
|
8283
= help: the trait `Iterator` is not implemented for `i32`
8384
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
85+
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
8486

8587
error[E0204]: the trait `Copy` may not be implemented for this type
8688
--> $DIR/issue-50480.rs:10:17
8789
|
8890
LL | #[derive(Clone, Copy)]
8991
| ^^^^
90-
LL |
92+
...
9193
LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
9294
| -------- ------ this field does not implement `Copy`
9395
| |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
trait TraitFoo {
2+
type Bar;
3+
}
4+
5+
struct Foo<T>
6+
where
7+
T: TraitFoo,
8+
{
9+
inner: T::Bar,
10+
}
11+
12+
impl<T> Clone for Foo<T>
13+
where
14+
T: TraitFoo,
15+
T::Bar: Clone,
16+
{
17+
fn clone(&self) -> Self {
18+
Self { inner: self.inner.clone() }
19+
}
20+
}
21+
22+
impl<T> Copy for Foo<T> {}
23+
//~^ ERROR the trait bound `T: TraitFoo` is not satisfied
24+
25+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0277]: the trait bound `T: TraitFoo` is not satisfied
2+
--> $DIR/copy-impl-cannot-normalize.rs:22:1
3+
|
4+
LL | impl<T> Copy for Foo<T> {}
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitFoo` is not implemented for `T`
6+
|
7+
help: consider restricting type parameter `T`
8+
|
9+
LL | impl<T: TraitFoo> Copy for Foo<T> {}
10+
| ++++++++++
11+
12+
error: aborting due to previous error
13+
14+
For more information about this error, try `rustc --explain E0277`.

src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
199199
let sugg = |diag: &mut DiagnosticBuilder<'_>| {
200200
if let ty::Adt(def, ..) = ty.kind() {
201201
if let Some(span) = cx.tcx.hir().span_if_local(def.did) {
202-
if can_type_implement_copy(cx.tcx, cx.param_env, ty).is_ok() {
202+
if can_type_implement_copy(cx.tcx, cx.param_env, ty, traits::ObligationCause::dummy_with_span(span)).is_ok() {
203203
diag.span_help(span, "consider marking this type as `Copy`");
204204
}
205205
}

0 commit comments

Comments
 (0)