debuginfo::set_source_location(bcx.fcx, expr.id, expr.span);
- if bcx.tcx().tables.borrow().adjustments.contains_key(&expr.id) {
+ if adjustment_required(bcx, expr) {
// use trans, which may be less efficient but
// which will perform the adjustments:
let datum = unpack_datum!(bcx, trans(bcx, expr));
}
}
+fn adjustment_required<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+ expr: &hir::Expr) -> bool {
+ let adjustment = match bcx.tcx().tables.borrow().adjustments.get(&expr.id).cloned() {
+ None => { return false; }
+ Some(adj) => adj
+ };
+
+ // Don't skip a conversion from Box<T> to &T, etc.
+ if bcx.tcx().is_overloaded_autoderef(expr.id, 0) {
+ return true;
+ }
+
+ match adjustment {
+ AdjustReifyFnPointer => {
+ // FIXME(#19925) once fn item types are
+ // zero-sized, we'll need to return true here
+ false
+ }
+ AdjustUnsafeFnPointer => {
+ // purely a type-level thing
+ false
+ }
+ AdjustDerefRef(ref adj) => {
+ // We are a bit paranoid about adjustments and thus might have a re-
+ // borrow here which merely derefs and then refs again (it might have
+ // a different region or mutability, but we don't care here).
+ !(adj.autoderefs == 1 && adj.autoref.is_some() && adj.unsize.is_none())
+ }
+ }
+}
+
/// Helper for trans that apply adjustments from `expr` to `datum`, which should be the unadjusted
/// translation of `expr`.
fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// CHECK: call void @llvm.memcpy.{{.*}}(i8* [[DST]], i8* [[SRC]],
{ x }
}
+
+// CHECK-LABEL: @no_op_slice_adjustment2
+#[no_mangle]
+pub fn no_op_slice_adjustment2(x: &[u8]) -> &[u8] {
+ // We used to generate an extra alloca and memcpy for the function's return value, so check
+ // that there's no memcpy (the slice is written to sret_slot element-wise)
+// CHECK-NOT: call void @llvm.memcpy.
+ no_op_slice_adjustment(x)
+}