Fix write_cvalue type assert for late bound regions in trait objects
This commit is contained in:
parent
e09ae25299
commit
354eb0da9f
1 changed files with 59 additions and 40 deletions
|
@ -320,51 +320,70 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> {
|
|||
}
|
||||
|
||||
pub fn write_cvalue(self, fx: &mut FunctionCx<'a, 'tcx, impl Backend>, from: CValue<'tcx>) {
|
||||
use rustc::hir::Mutability::*;
|
||||
|
||||
let from_ty = from.layout().ty;
|
||||
let to_ty = self.layout().ty;
|
||||
match (&from_ty.sty, &to_ty.sty) {
|
||||
(ty::Ref(_, t, src_mut), ty::Ref(_, u, dest_mut))
|
||||
if (if *dest_mut != crate::rustc::hir::Mutability::MutImmutable
|
||||
&& src_mut != dest_mut
|
||||
{
|
||||
false
|
||||
} else if t != u {
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}) =>
|
||||
{
|
||||
// &mut T -> &T is allowed
|
||||
// &'a T -> &'b T is allowed
|
||||
}
|
||||
(ty::FnPtr(_), ty::FnPtr(_)) => {
|
||||
let from_sig = fx.tcx.normalize_erasing_late_bound_regions(
|
||||
ParamEnv::reveal_all(),
|
||||
&from_ty.fn_sig(fx.tcx),
|
||||
);
|
||||
let to_sig = fx.tcx.normalize_erasing_late_bound_regions(
|
||||
ParamEnv::reveal_all(),
|
||||
&to_ty.fn_sig(fx.tcx),
|
||||
);
|
||||
assert_eq!(
|
||||
from_sig, to_sig,
|
||||
"Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n\n{:#?}",
|
||||
from_sig, to_sig, fx,
|
||||
);
|
||||
// fn(&T) -> for<'l> fn(&'l T) is allowed
|
||||
}
|
||||
_ => {
|
||||
assert_eq!(
|
||||
from_ty,
|
||||
to_ty,
|
||||
"Can't write value with incompatible type {:?} to place with type {:?}\n\n{:#?}",
|
||||
from_ty.sty,
|
||||
to_ty.sty,
|
||||
fx,
|
||||
);
|
||||
|
||||
fn assert_assignable<'a, 'tcx: 'a>(fx: &FunctionCx<'a, 'tcx, impl Backend>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) {
|
||||
match (&from_ty.sty, &to_ty.sty) {
|
||||
(ty::Ref(_, t, MutImmutable), ty::Ref(_, u, MutImmutable))
|
||||
| (ty::Ref(_, t, MutMutable), ty::Ref(_, u, MutImmutable))
|
||||
| (ty::Ref(_, t, MutMutable), ty::Ref(_, u, MutMutable)) => {
|
||||
assert_assignable(fx, t, u);
|
||||
// &mut T -> &T is allowed
|
||||
// &'a T -> &'b T is allowed
|
||||
}
|
||||
(ty::Ref(_, _, MutImmutable), ty::Ref(_, _, MutMutable)) => {
|
||||
panic!("Cant assign value of type {} to place of type {}", from_ty.sty, to_ty.sty)
|
||||
}
|
||||
(ty::FnPtr(_), ty::FnPtr(_)) => {
|
||||
let from_sig = fx.tcx.normalize_erasing_late_bound_regions(
|
||||
ParamEnv::reveal_all(),
|
||||
&from_ty.fn_sig(fx.tcx),
|
||||
);
|
||||
let to_sig = fx.tcx.normalize_erasing_late_bound_regions(
|
||||
ParamEnv::reveal_all(),
|
||||
&to_ty.fn_sig(fx.tcx),
|
||||
);
|
||||
assert_eq!(
|
||||
from_sig, to_sig,
|
||||
"Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n\n{:#?}",
|
||||
from_sig, to_sig, fx,
|
||||
);
|
||||
// fn(&T) -> for<'l> fn(&'l T) is allowed
|
||||
}
|
||||
(ty::Dynamic(from_traits, _), ty::Dynamic(to_traits, _)) => {
|
||||
let from_traits = fx.tcx.normalize_erasing_late_bound_regions(
|
||||
ParamEnv::reveal_all(),
|
||||
from_traits,
|
||||
);
|
||||
let to_traits = fx.tcx.normalize_erasing_late_bound_regions(
|
||||
ParamEnv::reveal_all(),
|
||||
to_traits,
|
||||
);
|
||||
assert_eq!(
|
||||
from_traits, to_traits,
|
||||
"Can't write trait object of incompatible traits {:?} to place with traits {:?}\n\n{:#?}",
|
||||
from_traits, to_traits, fx,
|
||||
);
|
||||
// dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed
|
||||
}
|
||||
_ => {
|
||||
assert_eq!(
|
||||
from_ty,
|
||||
to_ty,
|
||||
"Can't write value with incompatible type {:?} to place with type {:?}\n\n{:#?}",
|
||||
from_ty.sty,
|
||||
to_ty.sty,
|
||||
fx,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert_assignable(fx, from_ty, to_ty);
|
||||
|
||||
let (addr, dst_layout) = match self {
|
||||
CPlace::Var(var, _) => {
|
||||
let data = from.load_scalar(fx);
|
||||
|
|
Loading…
Reference in a new issue