Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make blame spans better for impl wfcheck #106785

Merged
merged 3 commits into from
Jan 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1254,7 +1254,11 @@ fn check_impl<'tcx>(
// therefore don't need to be WF (the trait's `Self: Trait` predicate
// won't hold).
let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap();
let trait_ref = wfcx.normalize(ast_trait_ref.path.span, None, trait_ref);
let trait_ref = wfcx.normalize(
ast_trait_ref.path.span,
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
trait_ref,
);
let trait_pred = ty::TraitPredicate {
trait_ref,
constness: match constness {
Expand All @@ -1263,14 +1267,21 @@ fn check_impl<'tcx>(
},
polarity: ty::ImplPolarity::Positive,
};
let obligations = traits::wf::trait_obligations(
let mut obligations = traits::wf::trait_obligations(
wfcx.infcx,
wfcx.param_env,
wfcx.body_id,
&trait_pred,
ast_trait_ref.path.span,
item,
);
for obligation in &mut obligations {
if let Some(pred) = obligation.predicate.to_opt_poly_trait_pred()
&& pred.self_ty().skip_binder() == trait_ref.self_ty()
{
obligation.cause.span = ast_self_ty.span;
}
}
debug!(?obligations);
wfcx.register_obligations(obligations);
}
Expand Down
46 changes: 29 additions & 17 deletions compiler/rustc_hir_analysis/src/hir_wf_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,51 +114,63 @@ fn diagnostic_hir_wf_check<'tcx>(
// Get the starting `hir::Ty` using our `WellFormedLoc`.
// We will walk 'into' this type to try to find
// a more precise span for our predicate.
let ty = match loc {
let tys = match loc {
WellFormedLoc::Ty(_) => match hir.get(hir_id) {
hir::Node::ImplItem(item) => match item.kind {
hir::ImplItemKind::Type(ty) => Some(ty),
hir::ImplItemKind::Const(ty, _) => Some(ty),
hir::ImplItemKind::Type(ty) => vec![ty],
hir::ImplItemKind::Const(ty, _) => vec![ty],
ref item => bug!("Unexpected ImplItem {:?}", item),
},
hir::Node::TraitItem(item) => match item.kind {
hir::TraitItemKind::Type(_, ty) => ty,
hir::TraitItemKind::Const(ty, _) => Some(ty),
hir::TraitItemKind::Type(_, ty) => ty.into_iter().collect(),
hir::TraitItemKind::Const(ty, _) => vec![ty],
ref item => bug!("Unexpected TraitItem {:?}", item),
},
hir::Node::Item(item) => match item.kind {
hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => Some(ty),
hir::ItemKind::Impl(ref impl_) => {
assert!(impl_.of_trait.is_none(), "Unexpected trait impl: {:?}", impl_);
Some(impl_.self_ty)
}
hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => vec![ty],
hir::ItemKind::Impl(ref impl_) => match &impl_.of_trait {
Some(t) => t
.path
.segments
.last()
.iter()
.flat_map(|seg| seg.args().args)
.filter_map(|arg| {
if let hir::GenericArg::Type(ty) = arg { Some(*ty) } else { None }
})
.chain([impl_.self_ty])
.collect(),
None => {
vec![impl_.self_ty]
}
},
ref item => bug!("Unexpected item {:?}", item),
},
hir::Node::Field(field) => Some(field.ty),
hir::Node::Field(field) => vec![field.ty],
hir::Node::ForeignItem(ForeignItem {
kind: ForeignItemKind::Static(ty, _), ..
}) => Some(*ty),
}) => vec![*ty],
hir::Node::GenericParam(hir::GenericParam {
kind: hir::GenericParamKind::Type { default: Some(ty), .. },
..
}) => Some(*ty),
}) => vec![*ty],
ref node => bug!("Unexpected node {:?}", node),
},
WellFormedLoc::Param { function: _, param_idx } => {
let fn_decl = hir.fn_decl_by_hir_id(hir_id).unwrap();
// Get return type
if param_idx as usize == fn_decl.inputs.len() {
match fn_decl.output {
hir::FnRetTy::Return(ty) => Some(ty),
hir::FnRetTy::Return(ty) => vec![ty],
// The unit type `()` is always well-formed
hir::FnRetTy::DefaultReturn(_span) => None,
hir::FnRetTy::DefaultReturn(_span) => vec![],
}
} else {
Some(&fn_decl.inputs[param_idx as usize])
vec![&fn_decl.inputs[param_idx as usize]]
}
}
};
if let Some(ty) = ty {
for ty in tys {
visitor.visit_ty(ty);
}
visitor.cause
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: `T` cannot be sent between threads safely
--> $DIR/builtin-superkinds-double-superkind.rs:6:24
--> $DIR/builtin-superkinds-double-superkind.rs:6:32
|
LL | impl <T: Sync+'static> Foo for (T,) { }
| ^^^ `T` cannot be sent between threads safely
| ^^^^ `T` cannot be sent between threads safely
|
= note: required because it appears within the type `(T,)`
note: required by a bound in `Foo`
Expand All @@ -16,10 +16,10 @@ LL | impl <T: Sync+'static + std::marker::Send> Foo for (T,) { }
| +++++++++++++++++++

error[E0277]: `T` cannot be shared between threads safely
--> $DIR/builtin-superkinds-double-superkind.rs:9:16
--> $DIR/builtin-superkinds-double-superkind.rs:9:24
|
LL | impl <T: Send> Foo for (T,T) { }
| ^^^ `T` cannot be shared between threads safely
| ^^^^^ `T` cannot be shared between threads safely
|
= note: required because it appears within the type `(T, T)`
note: required by a bound in `Foo`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: `T` cannot be sent between threads safely
--> $DIR/builtin-superkinds-in-metadata.rs:13:23
--> $DIR/builtin-superkinds-in-metadata.rs:13:56
|
LL | impl <T:Sync+'static> RequiresRequiresShareAndSend for X<T> { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `T` cannot be sent between threads safely
| ^^^^ `T` cannot be sent between threads safely
|
note: required because it appears within the type `X<T>`
--> $DIR/builtin-superkinds-in-metadata.rs:9:8
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/builtin-superkinds/builtin-superkinds-simple.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: `Rc<i8>` cannot be sent between threads safely
--> $DIR/builtin-superkinds-simple.rs:6:6
--> $DIR/builtin-superkinds-simple.rs:6:14
|
LL | impl Foo for std::rc::Rc<i8> { }
| ^^^ `Rc<i8>` cannot be sent between threads safely
| ^^^^^^^^^^^^^^^ `Rc<i8>` cannot be sent between threads safely
|
= help: the trait `Send` is not implemented for `Rc<i8>`
note: required by a bound in `Foo`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: `T` cannot be sent between threads safely
--> $DIR/builtin-superkinds-typaram-not-send.rs:5:24
--> $DIR/builtin-superkinds-typaram-not-send.rs:5:32
|
LL | impl <T: Sync+'static> Foo for T { }
| ^^^ `T` cannot be sent between threads safely
| ^ `T` cannot be sent between threads safely
|
note: required by a bound in `Foo`
--> $DIR/builtin-superkinds-typaram-not-send.rs:3:13
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/chalkify/impl_wf.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/impl_wf.rs:11:6
--> $DIR/impl_wf.rs:11:14
|
LL | impl Foo for str { }
| ^^^ doesn't have a size known at compile-time
| ^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
note: required by a bound in `Foo`
Expand All @@ -12,10 +12,10 @@ LL | trait Foo: Sized { }
| ^^^^^ required by this bound in `Foo`

error[E0277]: the trait bound `f32: Foo` is not satisfied
--> $DIR/impl_wf.rs:22:6
--> $DIR/impl_wf.rs:22:19
|
LL | impl Baz<f32> for f32 { }
| ^^^^^^^^ the trait `Foo` is not implemented for `f32`
| ^^^ the trait `Foo` is not implemented for `f32`
|
= help: the trait `Foo` is implemented for `i32`
note: required by a bound in `Baz`
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/coherence/coherence-overlap-trait-alias.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0283]: type annotations needed: cannot satisfy `u32: C`
--> $DIR/coherence-overlap-trait-alias.rs:15:6
--> $DIR/coherence-overlap-trait-alias.rs:15:12
|
LL | impl C for u32 {}
| ^
| ^^^
|
note: multiple `impl`s satisfying `u32: C` found
--> $DIR/coherence-overlap-trait-alias.rs:14:1
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/dst/dst-sized-trait-param.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ LL | trait Foo<T: ?Sized> : Sized { fn take(self, x: &T) { } } // Note: T is siz
| ++++++++

error[E0277]: the size for values of type `[usize]` cannot be known at compilation time
--> $DIR/dst-sized-trait-param.rs:10:6
--> $DIR/dst-sized-trait-param.rs:10:21
|
LL | impl Foo<isize> for [usize] { }
| ^^^^^^^^^^ doesn't have a size known at compile-time
| ^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[usize]`
note: required by a bound in `Foo`
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/error-codes/E0308-2.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0308]: mismatched types
--> $DIR/E0308-2.rs:9:6
--> $DIR/E0308-2.rs:9:13
|
LL | impl Eq for &dyn DynEq {}
| ^^ lifetime mismatch
| ^^^^^^^^^^ lifetime mismatch
|
= note: expected trait `<&dyn DynEq as PartialEq>`
found trait `<&(dyn DynEq + 'static) as PartialEq>`
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/issues/issue-65230.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0308]: mismatched types
--> $DIR/issue-65230.rs:8:6
--> $DIR/issue-65230.rs:8:13
|
LL | impl T1 for &dyn T2 {}
| ^^ lifetime mismatch
| ^^^^^^^ lifetime mismatch
|
= note: expected trait `<&dyn T2 as T0>`
found trait `<&(dyn T2 + 'static) as T0>`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0283]: type annotations needed: cannot satisfy `&(): Marker`
--> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:6:6
--> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:6:17
|
LL | impl Marker for &'_ () {}
| ^^^^^^
| ^^^^^^
|
note: multiple `impl`s satisfying `&(): Marker` found
--> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:6:1
Expand All @@ -13,10 +13,10 @@ LL | impl Marker for &'_ () {}
| ^^^^^^^^^^^^^^^^^^^^^^

error[E0283]: type annotations needed: cannot satisfy `&(): Marker`
--> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:7:6
--> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:7:17
|
LL | impl Marker for &'_ () {}
| ^^^^^^
| ^^^^^^
|
note: multiple `impl`s satisfying `&(): Marker` found
--> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:6:1
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/marker_trait_attr/region-overlap.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0283]: type annotations needed: cannot satisfy `(&'static (), &'a ()): A`
--> $DIR/region-overlap.rs:5:10
--> $DIR/region-overlap.rs:5:16
|
LL | impl<'a> A for (&'static (), &'a ()) {}
| ^
| ^^^^^^^^^^^^^^^^^^^^^
|
note: multiple `impl`s satisfying `(&'static (), &'a ()): A` found
--> $DIR/region-overlap.rs:5:1
Expand All @@ -13,10 +13,10 @@ LL | impl<'a> A for (&'a (), &'static ()) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0283]: type annotations needed: cannot satisfy `(&'a (), &'static ()): A`
--> $DIR/region-overlap.rs:6:10
--> $DIR/region-overlap.rs:6:16
|
LL | impl<'a> A for (&'a (), &'static ()) {}
| ^
| ^^^^^^^^^^^^^^^^^^^^^
|
note: multiple `impl`s satisfying `(&'a (), &'static ()): A` found
--> $DIR/region-overlap.rs:5:1
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/rfc-2632-const-trait-impl/super-traits-fail.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
error[E0277]: the trait bound `S: ~const Foo` is not satisfied
--> $DIR/super-traits-fail.rs:15:12
--> $DIR/super-traits-fail.rs:15:20
|
LL | impl const Bar for S {}
| ^^^ the trait `~const Foo` is not implemented for `S`
| ^ the trait `~const Foo` is not implemented for `S`
|
note: the trait `Foo` is implemented for `S`, but that implementation is not `const`
--> $DIR/super-traits-fail.rs:15:12
--> $DIR/super-traits-fail.rs:15:20
|
LL | impl const Bar for S {}
| ^^^
| ^
note: required by a bound in `Bar`
--> $DIR/super-traits-fail.rs:8:12
|
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/span/issue-71363.stderr
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
error[E0277]: `MyError` doesn't implement `std::fmt::Display`
--> $DIR/issue-71363.rs:4:6
--> $DIR/issue-71363.rs:4:28
|
4 | impl std::error::Error for MyError {}
| ^^^^^^^^^^^^^^^^^ `MyError` cannot be formatted with the default formatter
| ^^^^^^^ `MyError` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `MyError`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `std::error::Error`
--> $SRC_DIR/core/src/error.rs:LL:COL

error[E0277]: `MyError` doesn't implement `Debug`
--> $DIR/issue-71363.rs:4:6
--> $DIR/issue-71363.rs:4:28
|
4 | impl std::error::Error for MyError {}
| ^^^^^^^^^^^^^^^^^ `MyError` cannot be formatted using `{:?}`
| ^^^^^^^ `MyError` cannot be formatted using `{:?}`
|
= help: the trait `Debug` is not implemented for `MyError`
= note: add `#[derive(Debug)]` to `MyError` or manually `impl Debug for MyError`
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/specialization/min_specialization/issue-79224.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `B: Clone` is not satisfied
--> $DIR/issue-79224.rs:18:17
--> $DIR/issue-79224.rs:18:29
|
LL | impl<B: ?Sized> Display for Cow<'_, B> {
| ^^^^^^^ the trait `Clone` is not implemented for `B`
| ^^^^^^^^^^ the trait `Clone` is not implemented for `B`
|
= note: required for `B` to implement `ToOwned`
help: consider further restricting this bound
Expand Down
Loading