Rollup merge of #87065 - FabianWolff:issue-87046, r=oli-obk
Fix ICE with unsized type in const pattern
Fixes #87046. The `deref_const()` query currently contains the following check:
e9a387d6cf/compiler/rustc_mir/src/const_eval/mod.rs (L191-L204)
i.e. this will cause an ICE for every unsized type except slices. An error is reported with my changes if such a type is used as a const pattern (this should not be a breaking change, since so far, this has caused an ICE).
This commit is contained in:
commit
47a418420e
|
@ -490,17 +490,29 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
// convert the dereferenced constant to a pattern that is the sub-pattern of the
|
// convert the dereferenced constant to a pattern that is the sub-pattern of the
|
||||||
// deref pattern.
|
// deref pattern.
|
||||||
_ => {
|
_ => {
|
||||||
let old = self.behind_reference.replace(true);
|
if !pointee_ty.is_sized(tcx.at(span), param_env) {
|
||||||
// In case there are structural-match violations somewhere in this subpattern,
|
// `tcx.deref_const()` below will ICE with an unsized type
|
||||||
// we fall back to a const pattern. If we do not do this, we may end up with
|
// (except slices, which are handled in a separate arm above).
|
||||||
// a !structural-match constant that is not of reference type, which makes it
|
let msg = format!("cannot use unsized non-slice type `{}` in constant patterns", pointee_ty);
|
||||||
// very hard to invoke `PartialEq::eq` on it as a fallback.
|
if self.include_lint_checks {
|
||||||
let val = match self.recur(tcx.deref_const(self.param_env.and(cv)), false) {
|
tcx.sess.span_err(span, &msg);
|
||||||
Ok(subpattern) => PatKind::Deref { subpattern },
|
} else {
|
||||||
Err(_) => PatKind::Constant { value: cv },
|
tcx.sess.delay_span_bug(span, &msg);
|
||||||
};
|
}
|
||||||
self.behind_reference.set(old);
|
PatKind::Wild
|
||||||
val
|
} else {
|
||||||
|
let old = self.behind_reference.replace(true);
|
||||||
|
// In case there are structural-match violations somewhere in this subpattern,
|
||||||
|
// we fall back to a const pattern. If we do not do this, we may end up with
|
||||||
|
// a !structural-match constant that is not of reference type, which makes it
|
||||||
|
// very hard to invoke `PartialEq::eq` on it as a fallback.
|
||||||
|
let val = match self.recur(tcx.deref_const(self.param_env.and(cv)), false) {
|
||||||
|
Ok(subpattern) => PatKind::Deref { subpattern },
|
||||||
|
Err(_) => PatKind::Constant { value: cv },
|
||||||
|
};
|
||||||
|
self.behind_reference.set(old);
|
||||||
|
val
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::FnDef(..) => {
|
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::FnDef(..) => {
|
||||||
|
|
34
src/test/ui/consts/issue-87046.rs
Normal file
34
src/test/ui/consts/issue-87046.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
// Regression test for the ICE described in #87046.
|
||||||
|
|
||||||
|
#![crate_type="lib"]
|
||||||
|
#![allow(unreachable_patterns)]
|
||||||
|
#![feature(const_fn_union)]
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct Username(str);
|
||||||
|
|
||||||
|
pub const ROOT_USER: &Username = Username::from_str("root");
|
||||||
|
|
||||||
|
impl Username {
|
||||||
|
pub const fn from_str(raw: &str) -> &Self {
|
||||||
|
union Transmute<'a> {
|
||||||
|
raw: &'a str,
|
||||||
|
typed: &'a Username,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe { Transmute { raw }.typed }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn as_str(&self) -> &str {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_root(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
ROOT_USER => true,
|
||||||
|
//~^ ERROR: cannot use unsized non-slice type `Username` in constant patterns
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
src/test/ui/consts/issue-87046.stderr
Normal file
8
src/test/ui/consts/issue-87046.stderr
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
error: cannot use unsized non-slice type `Username` in constant patterns
|
||||||
|
--> $DIR/issue-87046.rs:29:13
|
||||||
|
|
|
||||||
|
LL | ROOT_USER => true,
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
Loading…
Reference in a new issue