Skip to content

Commit 67404f7

Browse files
committed
Auto merge of rust-lang#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.
2 parents 15fc228 + 1e7ec94 commit 67404f7

10 files changed

+116
-53
lines changed

compiler/rustc_lint/src/builtin.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1610,13 +1610,11 @@ impl<'tcx> LateLintPass<'tcx> for UnusedBrokenConst {
16101610
hir::ItemKind::Const(_, body_id) => {
16111611
let def_id = cx.tcx.hir().body_owner_def_id(body_id).to_def_id();
16121612
// trigger the query once for all constants since that will already report the errors
1613-
// FIXME: Use ensure here
1614-
let _ = cx.tcx.const_eval_poly(def_id);
1613+
cx.tcx.ensure().const_eval_poly(def_id);
16151614
}
16161615
hir::ItemKind::Static(_, _, body_id) => {
16171616
let def_id = cx.tcx.hir().body_owner_def_id(body_id).to_def_id();
1618-
// FIXME: Use ensure here
1619-
let _ = cx.tcx.eval_static_initializer(def_id);
1617+
cx.tcx.ensure().eval_static_initializer(def_id);
16201618
}
16211619
_ => {}
16221620
}

compiler/rustc_lint/src/lib.rs

+13-14
Original file line numberDiff line numberDiff line change
@@ -159,28 +159,16 @@ macro_rules! late_lint_passes {
159159
$macro!(
160160
$args,
161161
[
162-
// FIXME: Look into regression when this is used as a module lint
163-
// May Depend on constants elsewhere
164-
UnusedBrokenConst: UnusedBrokenConst,
165-
// Needs to run after UnusedAttributes as it marks all `feature` attributes as used.
166-
UnstableFeatures: UnstableFeatures,
167162
// Tracks state across modules
168163
UnnameableTestItems: UnnameableTestItems::new(),
169164
// Tracks attributes of parents
170165
MissingDoc: MissingDoc::new(),
171-
// Depends on access levels
166+
// Builds a global list of all impls of `Debug`.
172167
// FIXME: Turn the computation of types which implement Debug into a query
173168
// and change this to a module lint pass
174169
MissingDebugImplementations: MissingDebugImplementations::default(),
175-
ArrayIntoIter: ArrayIntoIter::default(),
170+
// Keeps a global list of foreign declarations.
176171
ClashingExternDeclarations: ClashingExternDeclarations::new(),
177-
DropTraitConstraints: DropTraitConstraints,
178-
TemporaryCStringAsPtr: TemporaryCStringAsPtr,
179-
NonPanicFmt: NonPanicFmt,
180-
NoopMethodCall: NoopMethodCall,
181-
EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums,
182-
InvalidAtomicOrdering: InvalidAtomicOrdering,
183-
NamedAsmLabels: NamedAsmLabels,
184172
]
185173
);
186174
};
@@ -216,6 +204,17 @@ macro_rules! late_lint_mod_passes {
216204
ExplicitOutlivesRequirements: ExplicitOutlivesRequirements,
217205
InvalidValue: InvalidValue,
218206
DerefNullPtr: DerefNullPtr,
207+
// May Depend on constants elsewhere
208+
UnusedBrokenConst: UnusedBrokenConst,
209+
UnstableFeatures: UnstableFeatures,
210+
ArrayIntoIter: ArrayIntoIter::default(),
211+
DropTraitConstraints: DropTraitConstraints,
212+
TemporaryCStringAsPtr: TemporaryCStringAsPtr,
213+
NonPanicFmt: NonPanicFmt,
214+
NoopMethodCall: NoopMethodCall,
215+
EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums,
216+
InvalidAtomicOrdering: InvalidAtomicOrdering,
217+
NamedAsmLabels: NamedAsmLabels,
219218
]
220219
);
221220
};

compiler/rustc_middle/src/mir/interpret/queries.rs

+34-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use super::{ErrorHandled, EvalToConstValueResult, EvalToValTreeResult, GlobalId}
33
use crate::mir;
44
use crate::ty::fold::TypeFoldable;
55
use crate::ty::subst::InternalSubsts;
6-
use crate::ty::{self, query::TyCtxtAt, TyCtxt};
6+
use crate::ty::{self, query::TyCtxtAt, query::TyCtxtEnsure, TyCtxt};
77
use rustc_hir::def_id::DefId;
88
use rustc_span::{Span, DUMMY_SP};
99

@@ -171,6 +171,39 @@ impl<'tcx> TyCtxtAt<'tcx> {
171171
}
172172
}
173173

174+
impl<'tcx> TyCtxtEnsure<'tcx> {
175+
/// Evaluates a constant without providing any substitutions. This is useful to evaluate consts
176+
/// that can't take any generic arguments like statics, const items or enum discriminants. If a
177+
/// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned.
178+
#[instrument(skip(self), level = "debug")]
179+
pub fn const_eval_poly(self, def_id: DefId) {
180+
// In some situations def_id will have substitutions within scope, but they aren't allowed
181+
// to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions
182+
// into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are
183+
// encountered.
184+
let substs = InternalSubsts::identity_for_item(self.tcx, def_id);
185+
let instance = ty::Instance::new(def_id, substs);
186+
let cid = GlobalId { instance, promoted: None };
187+
let param_env =
188+
self.tcx.param_env(def_id).with_reveal_all_normalized(self.tcx).with_const();
189+
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
190+
// improve caching of queries.
191+
let inputs = self.tcx.erase_regions(param_env.and(cid));
192+
self.eval_to_const_value_raw(inputs)
193+
}
194+
195+
/// Evaluate a static's initializer, returning the allocation of the initializer's memory.
196+
pub fn eval_static_initializer(self, def_id: DefId) {
197+
trace!("eval_static_initializer: Need to compute {:?}", def_id);
198+
assert!(self.tcx.is_static(def_id));
199+
let instance = ty::Instance::mono(self.tcx, def_id);
200+
let gid = GlobalId { instance, promoted: None };
201+
let param_env = ty::ParamEnv::reveal_all().with_const();
202+
trace!("eval_to_allocation: Need to compute {:?}", gid);
203+
self.eval_to_allocation_raw(param_env.and(gid))
204+
}
205+
}
206+
174207
impl<'tcx> TyCtxt<'tcx> {
175208
/// Destructure a type-level constant ADT or array into its variant index and its field values.
176209
/// Panics if the destructuring fails, use `try_destructure_const` for fallible version.

src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
warning: the type `!` does not permit zero-initialization
2+
--> $DIR/validate_uninhabited_zsts.rs:4:14
3+
|
4+
LL | unsafe { std::mem::transmute(()) }
5+
| ^^^^^^^^^^^^^^^^^^^^^^^
6+
| |
7+
| this code causes undefined behavior when executed
8+
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
9+
|
10+
= note: `#[warn(invalid_value)]` on by default
11+
= note: the `!` type has no valid value
12+
113
error[E0080]: evaluation of constant value failed
214
--> $DIR/validate_uninhabited_zsts.rs:4:14
315
|
@@ -19,18 +31,6 @@ LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
1931
= 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.
2032
= note: the raw bytes of the constant (size: 0, align: 1) {}
2133

22-
warning: the type `!` does not permit zero-initialization
23-
--> $DIR/validate_uninhabited_zsts.rs:4:14
24-
|
25-
LL | unsafe { std::mem::transmute(()) }
26-
| ^^^^^^^^^^^^^^^^^^^^^^^
27-
| |
28-
| this code causes undefined behavior when executed
29-
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
30-
|
31-
= note: `#[warn(invalid_value)]` on by default
32-
= note: the `!` type has no valid value
33-
3434
warning: the type `empty::Empty` does not permit zero-initialization
3535
--> $DIR/validate_uninhabited_zsts.rs:23:42
3636
|

src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
warning: the type `!` does not permit zero-initialization
2+
--> $DIR/validate_uninhabited_zsts.rs:4:14
3+
|
4+
LL | unsafe { std::mem::transmute(()) }
5+
| ^^^^^^^^^^^^^^^^^^^^^^^
6+
| |
7+
| this code causes undefined behavior when executed
8+
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
9+
|
10+
= note: `#[warn(invalid_value)]` on by default
11+
= note: the `!` type has no valid value
12+
113
error[E0080]: evaluation of constant value failed
214
--> $DIR/validate_uninhabited_zsts.rs:4:14
315
|
@@ -19,18 +31,6 @@ LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
1931
= 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.
2032
= note: the raw bytes of the constant (size: 0, align: 1) {}
2133

22-
warning: the type `!` does not permit zero-initialization
23-
--> $DIR/validate_uninhabited_zsts.rs:4:14
24-
|
25-
LL | unsafe { std::mem::transmute(()) }
26-
| ^^^^^^^^^^^^^^^^^^^^^^^
27-
| |
28-
| this code causes undefined behavior when executed
29-
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
30-
|
31-
= note: `#[warn(invalid_value)]` on by default
32-
= note: the `!` type has no valid value
33-
3434
warning: the type `empty::Empty` does not permit zero-initialization
3535
--> $DIR/validate_uninhabited_zsts.rs:23:42
3636
|

src/test/ui/consts/recursive-zst-static.default.stderr

+9-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,15 @@ note: ...which requires const-evaluating + checking `FOO`...
1010
LL | static FOO: () = FOO;
1111
| ^^^
1212
= note: ...which again requires const-evaluating + checking `FOO`, completing the cycle
13-
= note: cycle used when running analysis passes on this crate
13+
note: cycle used when linting top-level module
14+
--> $DIR/recursive-zst-static.rs:10:1
15+
|
16+
LL | / static FOO: () = FOO;
17+
LL | |
18+
LL | | fn main() {
19+
LL | | FOO
20+
LL | | }
21+
| |_^
1422

1523
error: aborting due to previous error
1624

src/test/ui/consts/recursive-zst-static.unleash.stderr

+9-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,15 @@ note: ...which requires const-evaluating + checking `FOO`...
1010
LL | static FOO: () = FOO;
1111
| ^^^
1212
= note: ...which again requires const-evaluating + checking `FOO`, completing the cycle
13-
= note: cycle used when running analysis passes on this crate
13+
note: cycle used when linting top-level module
14+
--> $DIR/recursive-zst-static.rs:10:1
15+
|
16+
LL | / static FOO: () = FOO;
17+
LL | |
18+
LL | | fn main() {
19+
LL | | FOO
20+
LL | | }
21+
| |_^
1422

1523
error: aborting due to previous error
1624

src/test/ui/consts/write-to-static-mut-in-static.stderr

+11-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,17 @@ note: ...which requires const-evaluating + checking `C`...
1616
LL | pub static mut C: u32 = unsafe { C = 1; 0 };
1717
| ^^^^^
1818
= note: ...which again requires const-evaluating + checking `C`, completing the cycle
19-
= note: cycle used when running analysis passes on this crate
19+
note: cycle used when linting top-level module
20+
--> $DIR/write-to-static-mut-in-static.rs:1:1
21+
|
22+
LL | / pub static mut A: u32 = 0;
23+
LL | | pub static mut B: () = unsafe { A = 1; };
24+
LL | |
25+
LL | |
26+
... |
27+
LL | |
28+
LL | | fn main() {}
29+
| |____________^
2030

2131
error: aborting due to 2 previous errors
2232

src/test/ui/recursion/recursive-static-definition.stderr

+8-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ note: ...which requires const-evaluating + checking `FOO`...
1010
LL | pub static FOO: u32 = FOO;
1111
| ^^^
1212
= note: ...which again requires const-evaluating + checking `FOO`, completing the cycle
13-
= note: cycle used when running analysis passes on this crate
13+
note: cycle used when linting top-level module
14+
--> $DIR/recursive-static-definition.rs:1:1
15+
|
16+
LL | / pub static FOO: u32 = FOO;
17+
LL | |
18+
LL | |
19+
LL | | fn main() {}
20+
| |____________^
1421

1522
error: aborting due to previous error
1623

src/test/ui/statics/uninhabited-static.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,6 @@ error[E0080]: could not evaluate static initializer
4949
LL | static VOID2: Void = unsafe { std::mem::transmute(()) };
5050
| ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
5151

52-
error[E0080]: could not evaluate static initializer
53-
--> $DIR/uninhabited-static.rs:16:32
54-
|
55-
LL | static NEVER2: Void = unsafe { std::mem::transmute(()) };
56-
| ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
57-
5852
warning: the type `Void` does not permit zero-initialization
5953
--> $DIR/uninhabited-static.rs:12:31
6054
|
@@ -67,6 +61,12 @@ LL | static VOID2: Void = unsafe { std::mem::transmute(()) };
6761
= note: `#[warn(invalid_value)]` on by default
6862
= note: enums with no variants have no valid value
6963

64+
error[E0080]: could not evaluate static initializer
65+
--> $DIR/uninhabited-static.rs:16:32
66+
|
67+
LL | static NEVER2: Void = unsafe { std::mem::transmute(()) };
68+
| ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
69+
7070
warning: the type `Void` does not permit zero-initialization
7171
--> $DIR/uninhabited-static.rs:16:32
7272
|

0 commit comments

Comments
 (0)