Skip to content

Commit 81a583c

Browse files
committed
Try normalizing types without RevealAll in ParamEnv in mir validation
Before, the MIR validator used RevealAll in its ParamEnv for type checking. This could cause false negatives in some cases due to RevealAll ParamEnvs not always use all predicates as expected here. Since some MIR passes like inlining use RevealAll as well, keep using it in the MIR validator too, but when it fails usign RevealAll, also try the check without it, to stop false negatives.
1 parent b96fa1a commit 81a583c

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed

compiler/rustc_const_eval/src/transform/validate.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,28 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
181181
if (src, dest).has_opaque_types() {
182182
return true;
183183
}
184+
185+
let try_equal_with_param_env = |param_env| {
186+
let src = self.tcx.normalize_erasing_regions(param_env, src);
187+
let dest = self.tcx.normalize_erasing_regions(param_env, dest);
188+
// Type-changing assignments can happen when subtyping is used. While
189+
// all normal lifetimes are erased, higher-ranked types with their
190+
// late-bound lifetimes are still around and can lead to type
191+
// differences. So we compare ignoring lifetimes.
192+
equal_up_to_regions(self.tcx, param_env, src, dest)
193+
};
194+
184195
// Normalize projections and things like that.
196+
// First, try with reveal_all. This might not work in some cases, as the predicates
197+
// can be cleared in reveal_all mode. We try the reveal first anyways as it is used
198+
// by some other passes like inlining as well.
185199
let param_env = self.param_env.with_reveal_all_normalized(self.tcx);
186-
let src = self.tcx.normalize_erasing_regions(param_env, src);
187-
let dest = self.tcx.normalize_erasing_regions(param_env, dest);
188-
189-
// Type-changing assignments can happen when subtyping is used. While
190-
// all normal lifetimes are erased, higher-ranked types with their
191-
// late-bound lifetimes are still around and can lead to type
192-
// differences. So we compare ignoring lifetimes.
193-
equal_up_to_regions(self.tcx, param_env, src, dest)
200+
if try_equal_with_param_env(param_env) {
201+
true
202+
} else {
203+
// If this fails, we can try it without the reveal.
204+
try_equal_with_param_env(self.param_env)
205+
}
194206
}
195207
}
196208

src/test/ui/mir/issue-99866.rs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// check-pass
2+
pub trait Backend {
3+
type DescriptorSetLayout;
4+
}
5+
6+
pub struct Back;
7+
8+
impl Backend for Back {
9+
type DescriptorSetLayout = u32;
10+
}
11+
12+
pub struct HalSetLayouts {
13+
vertex_layout: <Back as Backend>::DescriptorSetLayout,
14+
}
15+
16+
impl HalSetLayouts {
17+
pub fn iter<DSL>(self) -> DSL
18+
where
19+
Back: Backend<DescriptorSetLayout = DSL>,
20+
{
21+
self.vertex_layout
22+
}
23+
}
24+
25+
fn main() {}

0 commit comments

Comments
 (0)