Skip to content

Commit 354eb0d

Browse files
committed
Fix write_cvalue type assert for late bound regions in trait objects
1 parent e09ae25 commit 354eb0d

File tree

1 file changed

+59
-40
lines changed

1 file changed

+59
-40
lines changed

src/common.rs

Lines changed: 59 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -320,51 +320,70 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> {
320320
}
321321

322322
pub fn write_cvalue(self, fx: &mut FunctionCx<'a, 'tcx, impl Backend>, from: CValue<'tcx>) {
323+
use rustc::hir::Mutability::*;
324+
323325
let from_ty = from.layout().ty;
324326
let to_ty = self.layout().ty;
325-
match (&from_ty.sty, &to_ty.sty) {
326-
(ty::Ref(_, t, src_mut), ty::Ref(_, u, dest_mut))
327-
if (if *dest_mut != crate::rustc::hir::Mutability::MutImmutable
328-
&& src_mut != dest_mut
329-
{
330-
false
331-
} else if t != u {
332-
false
333-
} else {
334-
true
335-
}) =>
336-
{
337-
// &mut T -> &T is allowed
338-
// &'a T -> &'b T is allowed
339-
}
340-
(ty::FnPtr(_), ty::FnPtr(_)) => {
341-
let from_sig = fx.tcx.normalize_erasing_late_bound_regions(
342-
ParamEnv::reveal_all(),
343-
&from_ty.fn_sig(fx.tcx),
344-
);
345-
let to_sig = fx.tcx.normalize_erasing_late_bound_regions(
346-
ParamEnv::reveal_all(),
347-
&to_ty.fn_sig(fx.tcx),
348-
);
349-
assert_eq!(
350-
from_sig, to_sig,
351-
"Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n\n{:#?}",
352-
from_sig, to_sig, fx,
353-
);
354-
// fn(&T) -> for<'l> fn(&'l T) is allowed
355-
}
356-
_ => {
357-
assert_eq!(
358-
from_ty,
359-
to_ty,
360-
"Can't write value with incompatible type {:?} to place with type {:?}\n\n{:#?}",
361-
from_ty.sty,
362-
to_ty.sty,
363-
fx,
364-
);
327+
328+
fn assert_assignable<'a, 'tcx: 'a>(fx: &FunctionCx<'a, 'tcx, impl Backend>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) {
329+
match (&from_ty.sty, &to_ty.sty) {
330+
(ty::Ref(_, t, MutImmutable), ty::Ref(_, u, MutImmutable))
331+
| (ty::Ref(_, t, MutMutable), ty::Ref(_, u, MutImmutable))
332+
| (ty::Ref(_, t, MutMutable), ty::Ref(_, u, MutMutable)) => {
333+
assert_assignable(fx, t, u);
334+
// &mut T -> &T is allowed
335+
// &'a T -> &'b T is allowed
336+
}
337+
(ty::Ref(_, _, MutImmutable), ty::Ref(_, _, MutMutable)) => {
338+
panic!("Cant assign value of type {} to place of type {}", from_ty.sty, to_ty.sty)
339+
}
340+
(ty::FnPtr(_), ty::FnPtr(_)) => {
341+
let from_sig = fx.tcx.normalize_erasing_late_bound_regions(
342+
ParamEnv::reveal_all(),
343+
&from_ty.fn_sig(fx.tcx),
344+
);
345+
let to_sig = fx.tcx.normalize_erasing_late_bound_regions(
346+
ParamEnv::reveal_all(),
347+
&to_ty.fn_sig(fx.tcx),
348+
);
349+
assert_eq!(
350+
from_sig, to_sig,
351+
"Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n\n{:#?}",
352+
from_sig, to_sig, fx,
353+
);
354+
// fn(&T) -> for<'l> fn(&'l T) is allowed
355+
}
356+
(ty::Dynamic(from_traits, _), ty::Dynamic(to_traits, _)) => {
357+
let from_traits = fx.tcx.normalize_erasing_late_bound_regions(
358+
ParamEnv::reveal_all(),
359+
from_traits,
360+
);
361+
let to_traits = fx.tcx.normalize_erasing_late_bound_regions(
362+
ParamEnv::reveal_all(),
363+
to_traits,
364+
);
365+
assert_eq!(
366+
from_traits, to_traits,
367+
"Can't write trait object of incompatible traits {:?} to place with traits {:?}\n\n{:#?}",
368+
from_traits, to_traits, fx,
369+
);
370+
// dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed
371+
}
372+
_ => {
373+
assert_eq!(
374+
from_ty,
375+
to_ty,
376+
"Can't write value with incompatible type {:?} to place with type {:?}\n\n{:#?}",
377+
from_ty.sty,
378+
to_ty.sty,
379+
fx,
380+
);
381+
}
365382
}
366383
}
367384

385+
assert_assignable(fx, from_ty, to_ty);
386+
368387
let (addr, dst_layout) = match self {
369388
CPlace::Var(var, _) => {
370389
let data = from.load_scalar(fx);

0 commit comments

Comments
 (0)