Skip to content

Make some lints incremental. #98238

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

Merged
merged 3 commits into from
Jun 19, 2022
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
6 changes: 2 additions & 4 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
_ => {}
}
Expand Down
27 changes: 13 additions & 14 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
]
);
};
Expand Down Expand Up @@ -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,
]
);
};
Expand Down
35 changes: 34 additions & 1 deletion compiler/rustc_middle/src/mir/interpret/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These comments (also the one below) are wrong now -- they talk about the return value of a function that doesn't return anything! I have no idea what is going on here so if someone could make a PR to update the comments, that would be much appreciated. :)

#[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.
Expand Down
Original file line number Diff line number Diff line change
@@ -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
|
Expand All @@ -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
|
Expand Down
Original file line number Diff line number Diff line change
@@ -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
|
Expand All @@ -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
|
Expand Down
10 changes: 9 additions & 1 deletion src/test/ui/consts/recursive-zst-static.default.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
10 changes: 9 additions & 1 deletion src/test/ui/consts/recursive-zst-static.unleash.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 11 additions & 1 deletion src/test/ui/consts/write-to-static-mut-in-static.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
9 changes: 8 additions & 1 deletion src/test/ui/recursion/recursive-static-definition.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 6 additions & 6 deletions src/test/ui/statics/uninhabited-static.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
|
Expand All @@ -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
|
Expand Down