mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 07:22:42 +00:00
Auto merge of #98238 - cjgillot:lint-mod, r=oli-obk
Make some lints incremental. Those lints do not track a state, so don't need to be performed for the full crate at once.
This commit is contained in:
commit
67404f7200
@ -1610,13 +1610,11 @@ impl<'tcx> LateLintPass<'tcx> for UnusedBrokenConst {
|
||||
hir::ItemKind::Const(_, body_id) => {
|
||||
let def_id = cx.tcx.hir().body_owner_def_id(body_id).to_def_id();
|
||||
// trigger the query once for all constants since that will already report the errors
|
||||
// FIXME: Use ensure here
|
||||
let _ = cx.tcx.const_eval_poly(def_id);
|
||||
cx.tcx.ensure().const_eval_poly(def_id);
|
||||
}
|
||||
hir::ItemKind::Static(_, _, body_id) => {
|
||||
let def_id = cx.tcx.hir().body_owner_def_id(body_id).to_def_id();
|
||||
// FIXME: Use ensure here
|
||||
let _ = cx.tcx.eval_static_initializer(def_id);
|
||||
cx.tcx.ensure().eval_static_initializer(def_id);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -159,28 +159,16 @@ macro_rules! late_lint_passes {
|
||||
$macro!(
|
||||
$args,
|
||||
[
|
||||
// FIXME: Look into regression when this is used as a module lint
|
||||
// May Depend on constants elsewhere
|
||||
UnusedBrokenConst: UnusedBrokenConst,
|
||||
// Needs to run after UnusedAttributes as it marks all `feature` attributes as used.
|
||||
UnstableFeatures: UnstableFeatures,
|
||||
// Tracks state across modules
|
||||
UnnameableTestItems: UnnameableTestItems::new(),
|
||||
// Tracks attributes of parents
|
||||
MissingDoc: MissingDoc::new(),
|
||||
// Depends on access levels
|
||||
// Builds a global list of all impls of `Debug`.
|
||||
// FIXME: Turn the computation of types which implement Debug into a query
|
||||
// and change this to a module lint pass
|
||||
MissingDebugImplementations: MissingDebugImplementations::default(),
|
||||
ArrayIntoIter: ArrayIntoIter::default(),
|
||||
// Keeps a global list of foreign declarations.
|
||||
ClashingExternDeclarations: ClashingExternDeclarations::new(),
|
||||
DropTraitConstraints: DropTraitConstraints,
|
||||
TemporaryCStringAsPtr: TemporaryCStringAsPtr,
|
||||
NonPanicFmt: NonPanicFmt,
|
||||
NoopMethodCall: NoopMethodCall,
|
||||
EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums,
|
||||
InvalidAtomicOrdering: InvalidAtomicOrdering,
|
||||
NamedAsmLabels: NamedAsmLabels,
|
||||
]
|
||||
);
|
||||
};
|
||||
@ -216,6 +204,17 @@ macro_rules! late_lint_mod_passes {
|
||||
ExplicitOutlivesRequirements: ExplicitOutlivesRequirements,
|
||||
InvalidValue: InvalidValue,
|
||||
DerefNullPtr: DerefNullPtr,
|
||||
// May Depend on constants elsewhere
|
||||
UnusedBrokenConst: UnusedBrokenConst,
|
||||
UnstableFeatures: UnstableFeatures,
|
||||
ArrayIntoIter: ArrayIntoIter::default(),
|
||||
DropTraitConstraints: DropTraitConstraints,
|
||||
TemporaryCStringAsPtr: TemporaryCStringAsPtr,
|
||||
NonPanicFmt: NonPanicFmt,
|
||||
NoopMethodCall: NoopMethodCall,
|
||||
EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums,
|
||||
InvalidAtomicOrdering: InvalidAtomicOrdering,
|
||||
NamedAsmLabels: NamedAsmLabels,
|
||||
]
|
||||
);
|
||||
};
|
||||
|
@ -3,7 +3,7 @@ use super::{ErrorHandled, EvalToConstValueResult, EvalToValTreeResult, GlobalId}
|
||||
use crate::mir;
|
||||
use crate::ty::fold::TypeFoldable;
|
||||
use crate::ty::subst::InternalSubsts;
|
||||
use crate::ty::{self, query::TyCtxtAt, TyCtxt};
|
||||
use crate::ty::{self, query::TyCtxtAt, query::TyCtxtEnsure, TyCtxt};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
@ -171,6 +171,39 @@ impl<'tcx> TyCtxtAt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TyCtxtEnsure<'tcx> {
|
||||
/// Evaluates a constant without providing any substitutions. This is useful to evaluate consts
|
||||
/// that can't take any generic arguments like statics, const items or enum discriminants. If a
|
||||
/// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub fn const_eval_poly(self, def_id: DefId) {
|
||||
// In some situations def_id will have substitutions within scope, but they aren't allowed
|
||||
// to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions
|
||||
// into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are
|
||||
// encountered.
|
||||
let substs = InternalSubsts::identity_for_item(self.tcx, def_id);
|
||||
let instance = ty::Instance::new(def_id, substs);
|
||||
let cid = GlobalId { instance, promoted: None };
|
||||
let param_env =
|
||||
self.tcx.param_env(def_id).with_reveal_all_normalized(self.tcx).with_const();
|
||||
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
|
||||
// improve caching of queries.
|
||||
let inputs = self.tcx.erase_regions(param_env.and(cid));
|
||||
self.eval_to_const_value_raw(inputs)
|
||||
}
|
||||
|
||||
/// Evaluate a static's initializer, returning the allocation of the initializer's memory.
|
||||
pub fn eval_static_initializer(self, def_id: DefId) {
|
||||
trace!("eval_static_initializer: Need to compute {:?}", def_id);
|
||||
assert!(self.tcx.is_static(def_id));
|
||||
let instance = ty::Instance::mono(self.tcx, def_id);
|
||||
let gid = GlobalId { instance, promoted: None };
|
||||
let param_env = ty::ParamEnv::reveal_all().with_const();
|
||||
trace!("eval_to_allocation: Need to compute {:?}", gid);
|
||||
self.eval_to_allocation_raw(param_env.and(gid))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
/// Destructure a type-level constant ADT or array into its variant index and its field values.
|
||||
/// Panics if the destructuring fails, use `try_destructure_const` for fallible version.
|
||||
|
@ -1,3 +1,15 @@
|
||||
warning: the type `!` does not permit zero-initialization
|
||||
--> $DIR/validate_uninhabited_zsts.rs:4:14
|
||||
|
|
||||
LL | unsafe { std::mem::transmute(()) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| this code causes undefined behavior when executed
|
||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
||||
|
|
||||
= note: `#[warn(invalid_value)]` on by default
|
||||
= note: the `!` type has no valid value
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/validate_uninhabited_zsts.rs:4:14
|
||||
|
|
||||
@ -19,18 +31,6 @@ LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
|
||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||
= note: the raw bytes of the constant (size: 0, align: 1) {}
|
||||
|
||||
warning: the type `!` does not permit zero-initialization
|
||||
--> $DIR/validate_uninhabited_zsts.rs:4:14
|
||||
|
|
||||
LL | unsafe { std::mem::transmute(()) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| this code causes undefined behavior when executed
|
||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
||||
|
|
||||
= note: `#[warn(invalid_value)]` on by default
|
||||
= note: the `!` type has no valid value
|
||||
|
||||
warning: the type `empty::Empty` does not permit zero-initialization
|
||||
--> $DIR/validate_uninhabited_zsts.rs:23:42
|
||||
|
|
||||
|
@ -1,3 +1,15 @@
|
||||
warning: the type `!` does not permit zero-initialization
|
||||
--> $DIR/validate_uninhabited_zsts.rs:4:14
|
||||
|
|
||||
LL | unsafe { std::mem::transmute(()) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| this code causes undefined behavior when executed
|
||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
||||
|
|
||||
= note: `#[warn(invalid_value)]` on by default
|
||||
= note: the `!` type has no valid value
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/validate_uninhabited_zsts.rs:4:14
|
||||
|
|
||||
@ -19,18 +31,6 @@ LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
|
||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||
= note: the raw bytes of the constant (size: 0, align: 1) {}
|
||||
|
||||
warning: the type `!` does not permit zero-initialization
|
||||
--> $DIR/validate_uninhabited_zsts.rs:4:14
|
||||
|
|
||||
LL | unsafe { std::mem::transmute(()) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| this code causes undefined behavior when executed
|
||||
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
||||
|
|
||||
= note: `#[warn(invalid_value)]` on by default
|
||||
= note: the `!` type has no valid value
|
||||
|
||||
warning: the type `empty::Empty` does not permit zero-initialization
|
||||
--> $DIR/validate_uninhabited_zsts.rs:23:42
|
||||
|
|
||||
|
@ -10,7 +10,15 @@ note: ...which requires const-evaluating + checking `FOO`...
|
||||
LL | static FOO: () = FOO;
|
||||
| ^^^
|
||||
= note: ...which again requires const-evaluating + checking `FOO`, completing the cycle
|
||||
= note: cycle used when running analysis passes on this crate
|
||||
note: cycle used when linting top-level module
|
||||
--> $DIR/recursive-zst-static.rs:10:1
|
||||
|
|
||||
LL | / static FOO: () = FOO;
|
||||
LL | |
|
||||
LL | | fn main() {
|
||||
LL | | FOO
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -10,7 +10,15 @@ note: ...which requires const-evaluating + checking `FOO`...
|
||||
LL | static FOO: () = FOO;
|
||||
| ^^^
|
||||
= note: ...which again requires const-evaluating + checking `FOO`, completing the cycle
|
||||
= note: cycle used when running analysis passes on this crate
|
||||
note: cycle used when linting top-level module
|
||||
--> $DIR/recursive-zst-static.rs:10:1
|
||||
|
|
||||
LL | / static FOO: () = FOO;
|
||||
LL | |
|
||||
LL | | fn main() {
|
||||
LL | | FOO
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -16,7 +16,17 @@ note: ...which requires const-evaluating + checking `C`...
|
||||
LL | pub static mut C: u32 = unsafe { C = 1; 0 };
|
||||
| ^^^^^
|
||||
= note: ...which again requires const-evaluating + checking `C`, completing the cycle
|
||||
= note: cycle used when running analysis passes on this crate
|
||||
note: cycle used when linting top-level module
|
||||
--> $DIR/write-to-static-mut-in-static.rs:1:1
|
||||
|
|
||||
LL | / pub static mut A: u32 = 0;
|
||||
LL | | pub static mut B: () = unsafe { A = 1; };
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | |
|
||||
LL | | fn main() {}
|
||||
| |____________^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -10,7 +10,14 @@ note: ...which requires const-evaluating + checking `FOO`...
|
||||
LL | pub static FOO: u32 = FOO;
|
||||
| ^^^
|
||||
= note: ...which again requires const-evaluating + checking `FOO`, completing the cycle
|
||||
= note: cycle used when running analysis passes on this crate
|
||||
note: cycle used when linting top-level module
|
||||
--> $DIR/recursive-static-definition.rs:1:1
|
||||
|
|
||||
LL | / pub static FOO: u32 = FOO;
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | fn main() {}
|
||||
| |____________^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -49,12 +49,6 @@ error[E0080]: could not evaluate static initializer
|
||||
LL | static VOID2: Void = unsafe { std::mem::transmute(()) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
|
||||
|
||||
error[E0080]: could not evaluate static initializer
|
||||
--> $DIR/uninhabited-static.rs:16:32
|
||||
|
|
||||
LL | static NEVER2: Void = unsafe { std::mem::transmute(()) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
|
||||
|
||||
warning: the type `Void` does not permit zero-initialization
|
||||
--> $DIR/uninhabited-static.rs:12:31
|
||||
|
|
||||
@ -67,6 +61,12 @@ LL | static VOID2: Void = unsafe { std::mem::transmute(()) };
|
||||
= note: `#[warn(invalid_value)]` on by default
|
||||
= note: enums with no variants have no valid value
|
||||
|
||||
error[E0080]: could not evaluate static initializer
|
||||
--> $DIR/uninhabited-static.rs:16:32
|
||||
|
|
||||
LL | static NEVER2: Void = unsafe { std::mem::transmute(()) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
|
||||
|
||||
warning: the type `Void` does not permit zero-initialization
|
||||
--> $DIR/uninhabited-static.rs:16:32
|
||||
|
|
||||
|
Loading…
Reference in New Issue
Block a user