Code change:
} } } <ins> fn expr_as_call_operand( &mut self, mut block: BasicBlock, scope: Option<region::Scope>, expr: Expr<'tcx>, ) -> BlockAnd<Operand<'tcx>> { debug!("expr_as_call_operand(block={:?}, expr={:?})", block, expr); let this = self; if let ExprKind::Scope { region_scope, lint_level, value } = expr.kind { let source_info = this.source_info(expr.span); let region_scope = (region_scope, source_info); return this.in_scope(region_scope, lint_level, |this| { this.as_call_operand(block, scope, value) }); } let tcx = this.hir.tcx(); if tcx.features().unsized_locals { let ty = expr.ty; let span = expr.span; let param_env = this.hir.param_env; if !ty.is_sized(tcx.at(span), param_env) { // !sized means !copy, so this is an unsized move assert!(!ty.is_copy_modulo_regions(tcx, param_env, span)); // As described above, detect the case where we are passing a value of unsized // type, and that value is coming from the deref of a box. if let ExprKind::Deref { ref arg } = expr.kind { let arg = this.hir.mirror(arg.clone()); // Generate let tmp0 = arg0 let operand = unpack!(block = this.as_temp(block, scope, arg, Mutability::Mut)); // Return the operand *tmp0 to be used as the call argument let place = Place { local: operand, projection: tcx.intern_place_elems(&[PlaceElem::Deref]), }; return block.and(Operand::Move(place)); } } } this.expr_as_operand(block, scope, expr) } </ins> }

Related discussion:
text: if we keep setting as the default alignment we can skip the overallocating and offset dance for types with an alignment below that.
My idea was that rustc would prohibit coercing overaligned types to a dyn trait that takes by value. So:
The alignment is dynamically determined though, not sure if saving 15 bytes of stack space is worth the conditional branch?
Oh right. Yea that's probably not helpful.
Since , this would be backwards incompatible (at latest) once trait object upcasting is finally implemented: and trait objects would have to have the same alignment restriction (because you can upcast to ), but today you can freely create such objects with any alignment.
I was under the impression that calling didn't require dynamic , is that related to missing MIR optimizations, meaning we have unnecessary moves which end up duplicating the data on the stack using a dynamic ?
Correctness shouldn't rely on optimizations to fire...
Sure, I was just hoping we weren't relying on "unsized locals", only unsized parameters (i.e. ), for what we're exposing as stable. And I was hoping an optimization wouldn't need to be involved to get there. I wonder if it would even be possible to restrict "unsized locals" to the subset where we can handle it entirely through ABI, and not actually have dynamic s anywhere, since that would make me far more comfortable with 's implementation or even stabilization. Ironically, if that works, it's also the subset we could've implemented years earlier than we did, since most of the complexity, unknowns (and apparently bugs) are around dynamic s, not calling trait object methods on a dereference of .
That should be possible. I think everything that is necessary is performing the deref of the box as argument () instead of moving the box contents to a local first () That would also make it possible to call in cg_clif. Cranelift doesn't have alloca support, so the current MIR is untranslatable.
Hmm, but that's not trivially sound because it could lead to MIR calls where argument and return places overlap, which is UB. We'd potentially have to special-case it to derefs, but even then what's to stop someone from doing ? Maybe we could introduce a temporary for the return value instead, for these kinds of virtual calls? That should remove any potential overlap while allowing the call.