Auto merge of #114514 - matthiaskrgr:rollup-1rv4f3h, r=matthiaskrgr
Rollup of 3 pull requests Successful merges: - #114029 (Explain more clearly why `fn() -> T` can't be `#[derive(Clone)]`) - #114248 (Make lint missing-copy-implementations honor negative `Copy` impls) - #114498 (Print tidy command with bless tidy check failure) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
fbc11e9690
@ -58,6 +58,7 @@ use rustc_middle::lint::in_external_macro;
|
|||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||||
use rustc_middle::ty::GenericArgKind;
|
use rustc_middle::ty::GenericArgKind;
|
||||||
|
use rustc_middle::ty::ToPredicate;
|
||||||
use rustc_middle::ty::TypeVisitableExt;
|
use rustc_middle::ty::TypeVisitableExt;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef};
|
use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef};
|
||||||
use rustc_session::config::ExpectedValues;
|
use rustc_session::config::ExpectedValues;
|
||||||
@ -68,6 +69,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
|||||||
use rustc_span::{BytePos, InnerSpan, Span};
|
use rustc_span::{BytePos, InnerSpan, Span};
|
||||||
use rustc_target::abi::Abi;
|
use rustc_target::abi::Abi;
|
||||||
use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt};
|
use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt};
|
||||||
|
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::{self, misc::type_allowed_to_implement_copy};
|
use rustc_trait_selection::traits::{self, misc::type_allowed_to_implement_copy};
|
||||||
|
|
||||||
use crate::nonstandard_style::{method_context, MethodLateContext};
|
use crate::nonstandard_style::{method_context, MethodLateContext};
|
||||||
@ -673,6 +675,9 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
|
|||||||
if ty.is_copy_modulo_regions(cx.tcx, param_env) {
|
if ty.is_copy_modulo_regions(cx.tcx, param_env) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if type_implements_negative_copy_modulo_regions(cx.tcx, ty, param_env) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// We shouldn't recommend implementing `Copy` on stateful things,
|
// We shouldn't recommend implementing `Copy` on stateful things,
|
||||||
// such as iterators.
|
// such as iterators.
|
||||||
@ -708,6 +713,24 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check whether a `ty` has a negative `Copy` implementation, ignoring outlives constraints.
|
||||||
|
fn type_implements_negative_copy_modulo_regions<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
ty: Ty<'tcx>,
|
||||||
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
) -> bool {
|
||||||
|
let trait_ref = ty::TraitRef::new(tcx, tcx.require_lang_item(hir::LangItem::Copy, None), [ty]);
|
||||||
|
let pred = ty::TraitPredicate { trait_ref, polarity: ty::ImplPolarity::Negative };
|
||||||
|
let obligation = traits::Obligation {
|
||||||
|
cause: traits::ObligationCause::dummy(),
|
||||||
|
param_env,
|
||||||
|
recursion_depth: 0,
|
||||||
|
predicate: ty::Binder::dummy(pred).to_predicate(tcx),
|
||||||
|
};
|
||||||
|
|
||||||
|
tcx.infer_ctxt().build().predicate_must_hold_modulo_regions(&obligation)
|
||||||
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// The `missing_debug_implementations` lint detects missing
|
/// The `missing_debug_implementations` lint detects missing
|
||||||
/// implementations of [`fmt::Debug`] for public types.
|
/// implementations of [`fmt::Debug`] for public types.
|
||||||
|
@ -86,6 +86,46 @@
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// If we `derive`:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #[derive(Copy, Clone)]
|
||||||
|
/// struct Generate<T>(fn() -> T);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// the auto-derived implementations will have unnecessary `T: Copy` and `T: Clone` bounds:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # struct Generate<T>(fn() -> T);
|
||||||
|
///
|
||||||
|
/// // Automatically derived
|
||||||
|
/// impl<T: Copy> Copy for Generate<T> { }
|
||||||
|
///
|
||||||
|
/// // Automatically derived
|
||||||
|
/// impl<T: Clone> Clone for Generate<T> {
|
||||||
|
/// fn clone(&self) -> Generate<T> {
|
||||||
|
/// Generate(Clone::clone(&self.0))
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// The bounds are unnecessary because clearly the function itself should be
|
||||||
|
/// copy- and cloneable even if its return type is not:
|
||||||
|
///
|
||||||
|
/// ```compile_fail,E0599
|
||||||
|
/// #[derive(Copy, Clone)]
|
||||||
|
/// struct Generate<T>(fn() -> T);
|
||||||
|
///
|
||||||
|
/// struct NotCloneable;
|
||||||
|
///
|
||||||
|
/// fn generate_not_cloneable() -> NotCloneable {
|
||||||
|
/// NotCloneable
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// Generate(generate_not_cloneable).clone(); // error: trait bounds were not satisfied
|
||||||
|
/// // Note: With the manual implementations the above line will compile.
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// ## Additional implementors
|
/// ## Additional implementors
|
||||||
///
|
///
|
||||||
/// In addition to the [implementors listed below][impls],
|
/// In addition to the [implementors listed below][impls],
|
||||||
|
@ -23,7 +23,7 @@ fn check_alphabetic(filename: &str, fluent: &str, bad: &mut bool) {
|
|||||||
tidy_error!(
|
tidy_error!(
|
||||||
bad,
|
bad,
|
||||||
"{filename}: message `{}` appears before `{}`, but is alphabetically later than it
|
"{filename}: message `{}` appears before `{}`, but is alphabetically later than it
|
||||||
run tidy with `--bless` to sort the file correctly",
|
run `./x.py test tidy --bless` to sort the file correctly",
|
||||||
name.as_str(),
|
name.as_str(),
|
||||||
next.as_str()
|
next.as_str()
|
||||||
);
|
);
|
||||||
|
15
tests/ui/lint/missing-copy-implementations-negative-copy.rs
Normal file
15
tests/ui/lint/missing-copy-implementations-negative-copy.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Regression test for issue #101980.
|
||||||
|
// Ensure that we don't suggest impl'ing `Copy` for a type if it already impl's `!Copy`.
|
||||||
|
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(negative_impls)]
|
||||||
|
#![deny(missing_copy_implementations)]
|
||||||
|
|
||||||
|
pub struct Struct {
|
||||||
|
pub field: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl !Copy for Struct {}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
x
Reference in New Issue
Block a user