Skip to content

Commit 89308bb

Browse files
committed
Don't run const propagation on items with inconsistent bounds
Using `#![feature(trivial_bounds)]`, it's possible to write functions with unsatisfiable 'where' clauses, making them uncallable. However, the user can act as if these 'where' clauses are true inside the body of the function, leading to code that would normally be impossible to write. Since const propgation can run even without any user-written calls to a function, we need to explcitly check for these uncallable functions.
1 parent 0731573 commit 89308bb

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

src/librustc_mir/transform/const_prop.rs

+25
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,31 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
7575
return;
7676
}
7777

78+
// Check if it's even possible to satisy the 'where' clauses
79+
// for this item.
80+
// This branch will never be taken for any normal function.
81+
// However, it's possible to `#!feature(trivial_bounds)]` to write
82+
// a function with impossible to satisfy clauses, e.g.:
83+
// `fn foo() where String: Copy {}`
84+
//
85+
// We don't usually need to worry about this kind of case,
86+
// since we would get a compilation error if the user tried
87+
// to call it. However, since we can do const propagation
88+
// even without any calls to the function, we need to make
89+
// sure that it even makes sense to try to evaluate the body.
90+
// If there are unsatisfiable where clauses, then all bets are
91+
// off, and we just give up.
92+
if !tcx.substitute_normalize_and_test_predicates((
93+
source.def_id(),
94+
InternalSubsts::identity_for_item(tcx, source.def_id()),
95+
)) {
96+
trace!(
97+
"ConstProp skipped for item with unsatisfiable predicates: {:?}",
98+
source.def_id()
99+
);
100+
return;
101+
}
102+
78103
trace!("ConstProp starting for {:?}", source.def_id());
79104

80105
let dummy_body = &Body::new(

src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
// run-pass
2+
// Force mir to be emitted, to ensure that const
3+
// propagation doesn't ICE on a function
4+
// with an 'impossible' body. See issue #67696
5+
// compile-flags: --emit=mir,link
26
// Inconsistent bounds with trait implementations
37

48
#![feature(trivial_bounds)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
warning: due to multiple output types requested, the explicitly specified output file name will be adapted for each output type
2+

0 commit comments

Comments
 (0)