Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 460bf3d

Browse files
committed
Auto merge of rust-lang#120687 - oli-obk:early_const_prop, r=<try>
Run const_prop_lint in check builds, too implements rust-lang#108730 (comment) Turns the const_prop_lint pass into a query that is run alongside borrowck.
2 parents 870a01a + f271893 commit 460bf3d

File tree

137 files changed

+1343
-616
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

137 files changed

+1343
-616
lines changed

compiler/rustc_abi/src/layout.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -426,10 +426,11 @@ where
426426
}
427427
}
428428
}
429-
_ => assert!(
430-
start == Bound::Unbounded && end == Bound::Unbounded,
431-
"nonscalar layout for layout_scalar_valid_range type: {st:#?}",
432-
),
429+
_ => {
430+
if start != Bound::Unbounded || end != Bound::Unbounded {
431+
return None;
432+
}
433+
}
433434
}
434435

435436
Some(st)

compiler/rustc_interface/src/passes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
738738
// Run unsafety check because it's responsible for stealing and
739739
// deallocating THIR.
740740
tcx.ensure().check_unsafety(def_id);
741+
tcx.ensure().const_prop_lint(def_id);
741742
tcx.ensure().mir_borrowck(def_id)
742743
});
743744
});

compiler/rustc_middle/src/query/erase.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ trivial! {
241241
Option<rustc_target::spec::PanicStrategy>,
242242
Option<usize>,
243243
Result<(), rustc_errors::ErrorGuaranteed>,
244+
Result<(), traits::util::HasImpossiblePredicates>,
244245
Result<(), rustc_middle::traits::query::NoSolution>,
245246
Result<rustc_middle::traits::EvaluationResult, rustc_middle::traits::OverflowError>,
246247
rustc_ast::expand::allocator::AllocatorKind,

compiler/rustc_middle/src/query/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use crate::traits::query::{
3939
OutlivesBound,
4040
};
4141
use crate::traits::specialization_graph;
42+
use crate::traits::util::HasImpossiblePredicates;
4243
use crate::traits::{
4344
CodegenObligationError, EvaluationResult, ImplSource, ObjectSafetyViolation, ObligationCause,
4445
OverflowError, WellFormedLoc,
@@ -1018,6 +1019,12 @@ rustc_queries! {
10181019
cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) }
10191020
}
10201021

1022+
/// Run the const prop lints on the `mir_promoted` of an item.
1023+
query const_prop_lint(key: LocalDefId) -> Result<(), HasImpossiblePredicates> {
1024+
desc { |tcx| "checking const prop lints for `{}`", tcx.def_path_str(key) }
1025+
cache_on_disk_if { true }
1026+
}
1027+
10211028
/// Gets a complete map from all types to their inherent impls.
10221029
/// Not meant to be used directly outside of coherence.
10231030
query crate_inherent_impls(k: ()) -> Result<&'tcx CrateInherentImpls, ErrorGuaranteed> {

compiler/rustc_middle/src/traits/util.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,9 @@ impl<'tcx> Iterator for Elaborator<'tcx> {
4646
}
4747
}
4848
}
49+
50+
/// Used as an error type to signal that an item may have an invalid body, because its
51+
/// where bounds are trivially not satisfyable.
52+
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
53+
#[derive(HashStable, Encodable, Decodable)]
54+
pub struct HasImpossiblePredicates;

compiler/rustc_mir_transform/src/lib.rs

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use rustc_middle::mir::{
4040
SourceInfo, Statement, StatementKind, TerminatorKind, START_BLOCK,
4141
};
4242
use rustc_middle::query::Providers;
43+
use rustc_middle::traits::util::HasImpossiblePredicates;
4344
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
4445
use rustc_span::{source_map::Spanned, sym, DUMMY_SP};
4546
use rustc_trait_selection::traits;
@@ -142,6 +143,7 @@ pub fn provide(providers: &mut Providers) {
142143
is_ctfe_mir_available: |tcx, did| is_mir_available(tcx, did),
143144
mir_callgraph_reachable: inline::cycle::mir_callgraph_reachable,
144145
mir_inliner_callees: inline::cycle::mir_inliner_callees,
146+
const_prop_lint,
145147
promoted_mir,
146148
deduced_param_attrs: deduce_param_attrs::deduced_param_attrs,
147149
..*providers
@@ -398,28 +400,11 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
398400
body
399401
}
400402

401-
/// Obtain just the main MIR (no promoteds) and run some cleanups on it. This also runs
402-
/// mir borrowck *before* doing so in order to ensure that borrowck can be run and doesn't
403-
/// end up missing the source MIR due to stealing happening.
404-
fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
405-
if tcx.is_coroutine(def.to_def_id()) {
406-
tcx.ensure_with_value().mir_coroutine_witnesses(def);
407-
}
408-
let mir_borrowck = tcx.mir_borrowck(def);
409-
410-
let is_fn_like = tcx.def_kind(def).is_fn_like();
411-
if is_fn_like {
412-
// Do not compute the mir call graph without said call graph actually being used.
413-
if pm::should_run_pass(tcx, &inline::Inline) {
414-
tcx.ensure_with_value().mir_inliner_callees(ty::InstanceDef::Item(def.to_def_id()));
415-
}
416-
}
417-
403+
fn const_prop_lint(tcx: TyCtxt<'_>, def: LocalDefId) -> Result<(), HasImpossiblePredicates> {
418404
let (body, _) = tcx.mir_promoted(def);
419-
let mut body = body.steal();
420-
if let Some(error_reported) = mir_borrowck.tainted_by_errors {
421-
body.tainted_by_errors = Some(error_reported);
422-
}
405+
let body = body.borrow();
406+
407+
let mir_borrowck = tcx.mir_borrowck(def);
423408

424409
// Check if it's even possible to satisfy the 'where' clauses
425410
// for this item.
@@ -455,6 +440,40 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
455440
.iter()
456441
.filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None });
457442
if traits::impossible_predicates(tcx, traits::elaborate(tcx, predicates).collect()) {
443+
Err(HasImpossiblePredicates)
444+
} else {
445+
if mir_borrowck.tainted_by_errors.is_none() && body.tainted_by_errors.is_none() {
446+
const_prop_lint::ConstPropLint.run_lint(tcx, &body);
447+
}
448+
Ok(())
449+
}
450+
}
451+
452+
/// Obtain just the main MIR (no promoteds) and run some cleanups on it. This also runs
453+
/// mir borrowck *before* doing so in order to ensure that borrowck can be run and doesn't
454+
/// end up missing the source MIR due to stealing happening.
455+
fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
456+
if tcx.is_coroutine(def.to_def_id()) {
457+
tcx.ensure_with_value().mir_coroutine_witnesses(def);
458+
}
459+
let mir_borrowck = tcx.mir_borrowck(def);
460+
let has_impossible_predicates = tcx.const_prop_lint(def);
461+
462+
let is_fn_like = tcx.def_kind(def).is_fn_like();
463+
if is_fn_like {
464+
// Do not compute the mir call graph without said call graph actually being used.
465+
if pm::should_run_pass(tcx, &inline::Inline) {
466+
tcx.ensure_with_value().mir_inliner_callees(ty::InstanceDef::Item(def.to_def_id()));
467+
}
468+
}
469+
470+
let (body, _) = tcx.mir_promoted(def);
471+
let mut body = body.steal();
472+
if let Some(error_reported) = mir_borrowck.tainted_by_errors {
473+
body.tainted_by_errors = Some(error_reported);
474+
}
475+
476+
if let Err(HasImpossiblePredicates) = has_impossible_predicates {
458477
trace!("found unsatisfiable predicates for {:?}", body.source);
459478
// Clear the body to only contain a single `unreachable` statement.
460479
let bbs = body.basic_blocks.as_mut();
@@ -538,7 +557,6 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
538557
&elaborate_box_derefs::ElaborateBoxDerefs,
539558
&coroutine::StateTransform,
540559
&add_retag::AddRetag,
541-
&Lint(const_prop_lint::ConstPropLint),
542560
];
543561
pm::run_passes_no_validate(tcx, body, passes, Some(MirPhase::Runtime(RuntimePhase::Initial)));
544562
}

src/doc/rustc/src/lints/levels.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ level is capped via cap-lints.
7171
A 'deny' lint produces an error if you violate it. For example, this code
7272
runs into the `exceeding_bitshifts` lint.
7373

74-
```rust,no_run
74+
```rust,compile_fail
7575
fn main() {
7676
100u8 << 10;
7777
}
@@ -246,7 +246,7 @@ pub fn foo() {}
246246
This is the maximum level for all lints. So for example, if we take our
247247
code sample from the "deny" lint level above:
248248
249-
```rust,no_run
249+
```rust,compile_fail
250250
fn main() {
251251
100u8 << 10;
252252
}

src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,8 @@ fn main() {
3535
x[const { idx() }]; // Ok, should not produce stderr.
3636
x[const { idx4() }]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
3737
const { &ARR[idx()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true.
38-
const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true.
39-
//
40-
//~^^ ERROR: failed
38+
// FIXME errors in rustc and subsequently blocks all lints in this file. Can reenable once solved on the rustc side
39+
//const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true.
4140

4241
let y = &x;
4342
y[0]; // Ok, referencing shouldn't affect this lint. See the issue 6021
Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,3 @@
1-
error[E0080]: evaluation of `main::{constant#3}` failed
2-
--> $DIR/test.rs:38:14
3-
|
4-
LL | const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true.
5-
| ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4
6-
7-
note: erroneous constant encountered
8-
--> $DIR/test.rs:38:5
9-
|
10-
LL | const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true.
11-
| ^^^^^^^^^^^^^^^^^^^^^^
12-
131
error: indexing may panic
142
--> $DIR/test.rs:29:5
153
|
@@ -21,39 +9,39 @@ LL | x[index];
219
= help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`
2210

2311
error: indexing may panic
24-
--> $DIR/test.rs:47:5
12+
--> $DIR/test.rs:46:5
2513
|
2614
LL | v[0];
2715
| ^^^^
2816
|
2917
= help: consider using `.get(n)` or `.get_mut(n)` instead
3018

3119
error: indexing may panic
32-
--> $DIR/test.rs:48:5
20+
--> $DIR/test.rs:47:5
3321
|
3422
LL | v[10];
3523
| ^^^^^
3624
|
3725
= help: consider using `.get(n)` or `.get_mut(n)` instead
3826

3927
error: indexing may panic
40-
--> $DIR/test.rs:49:5
28+
--> $DIR/test.rs:48:5
4129
|
4230
LL | v[1 << 3];
4331
| ^^^^^^^^^
4432
|
4533
= help: consider using `.get(n)` or `.get_mut(n)` instead
4634

4735
error: indexing may panic
48-
--> $DIR/test.rs:55:5
36+
--> $DIR/test.rs:54:5
4937
|
5038
LL | v[N];
5139
| ^^^^
5240
|
5341
= help: consider using `.get(n)` or `.get_mut(n)` instead
5442

5543
error: indexing may panic
56-
--> $DIR/test.rs:56:5
44+
--> $DIR/test.rs:55:5
5745
|
5846
LL | v[M];
5947
| ^^^^
@@ -66,6 +54,6 @@ error[E0080]: evaluation of constant value failed
6654
LL | const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts.
6755
| ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4
6856

69-
error: aborting due to 8 previous errors
57+
error: aborting due to 7 previous errors
7058

7159
For more information about this error, try `rustc --explain E0080`.

src/tools/clippy/tests/ui/indexing_slicing_index.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ fn main() {
4545
const { &ARR[idx()] };
4646
//~^ ERROR: indexing may panic
4747
// This should be linted, since `suppress-restriction-lint-in-const` default is false.
48-
const { &ARR[idx4()] };
49-
//~^ ERROR: indexing may panic
48+
// FIXME can't include here for now, as the error on it causes all lints to get silenced
49+
//const { &ARR[idx4()] };
5050

5151
let y = &x;
5252
// Ok, referencing shouldn't affect this lint. See the issue 6021

0 commit comments

Comments
 (0)