未验证 提交 7f995369 编写于 作者: D Dylan DPC 提交者: GitHub

Rollup merge of #93714 - compiler-errors:can-type-impl-copy-error-span, r=jackh726

better ObligationCause for normalization errors in `can_type_implement_copy`

Some logic is needed so we can point to the field when given totally nonsense types like `struct Foo(<u32 as Iterator>::Item);`

Fixes #93687
......@@ -51,7 +51,7 @@
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{BytePos, InnerSpan, MultiSpan, Span};
use rustc_target::abi::VariantIdx;
use rustc_trait_selection::traits::misc::can_type_implement_copy;
use rustc_trait_selection::traits::{self, misc::can_type_implement_copy};
use crate::nonstandard_style::{method_context, MethodLateContext};
......@@ -764,7 +764,14 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
if ty.is_copy_modulo_regions(cx.tcx.at(item.span), param_env) {
return;
}
if can_type_implement_copy(cx.tcx, param_env, ty).is_ok() {
if can_type_implement_copy(
cx.tcx,
param_env,
ty,
traits::ObligationCause::misc(item.span, item.hir_id()),
)
.is_ok()
{
cx.struct_span_lint(MISSING_COPY_IMPLEMENTATIONS, item.span, |lint| {
lint.build(
"type could implement `Copy`; consider adding `impl \
......
......@@ -20,6 +20,7 @@ pub fn can_type_implement_copy<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
self_type: Ty<'tcx>,
cause: ObligationCause<'tcx>,
) -> Result<(), CopyImplementationError<'tcx>> {
// FIXME: (@jroesch) float this code up
tcx.infer_ctxt().enter(|infcx| {
......@@ -49,7 +50,19 @@ pub fn can_type_implement_copy<'tcx>(
continue;
}
let span = tcx.def_span(field.did);
let cause = ObligationCause::dummy_with_span(span);
// FIXME(compiler-errors): This gives us better spans for bad
// projection types like in issue-50480.
// If the ADT has substs, point to the cause we are given.
// If it does not, then this field probably doesn't normalize
// to begin with, and point to the bad field's span instead.
let cause = if field
.ty(tcx, traits::InternalSubsts::identity_for_item(tcx, adt.did))
.has_param_types_or_consts()
{
cause.clone()
} else {
ObligationCause::dummy_with_span(span)
};
let ctx = traits::FulfillmentContext::new();
match traits::fully_normalize(&infcx, ctx, cause, param_env, ty) {
Ok(ty) => {
......
......@@ -74,7 +74,8 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
debug!("visit_implementation_of_copy: self_type={:?} (free)", self_type);
match can_type_implement_copy(tcx, param_env, self_type) {
let cause = traits::ObligationCause::misc(span, impl_hir_id);
match can_type_implement_copy(tcx, param_env, self_type, cause) {
Ok(()) => {}
Err(CopyImplementationError::InfrigingFields(fields)) => {
let item = tcx.hir().expect_item(impl_did);
......
trait TraitFoo {
type Bar;
}
struct Foo<T>
where
T: TraitFoo,
{
inner: T::Bar,
}
impl<T> Clone for Foo<T>
where
T: TraitFoo,
T::Bar: Clone,
{
fn clone(&self) -> Self {
Self { inner: self.inner.clone() }
}
}
impl<T> Copy for Foo<T> {}
//~^ ERROR the trait bound `T: TraitFoo` is not satisfied
fn main() {}
error[E0277]: the trait bound `T: TraitFoo` is not satisfied
--> $DIR/copy-impl-cannot-normalize.rs:22:1
|
LL | impl<T> Copy for Foo<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitFoo` is not implemented for `T`
|
help: consider restricting type parameter `T`
|
LL | impl<T: TraitFoo> Copy for Foo<T> {}
| ++++++++++
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
......@@ -199,7 +199,7 @@ fn check_fn(
let sugg = |diag: &mut DiagnosticBuilder<'_>| {
if let ty::Adt(def, ..) = ty.kind() {
if let Some(span) = cx.tcx.hir().span_if_local(def.did) {
if can_type_implement_copy(cx.tcx, cx.param_env, ty).is_ok() {
if can_type_implement_copy(cx.tcx, cx.param_env, ty, traits::ObligationCause::dummy_with_span(span)).is_ok() {
diag.span_help(span, "consider marking this type as `Copy`");
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册