Skip to content

Commit f862da5

Browse files
committed
Use a single match arm for all TyRef variants when deducing function argument attributes
This makes it a lot easier to later add attributes for fat pointers.
1 parent 4b42cbd commit f862da5

File tree

1 file changed

+20
-26
lines changed

1 file changed

+20
-26
lines changed

src/librustc_trans/trans/attributes.rs

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -262,41 +262,35 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
262262
.arg(idx, llvm::DereferenceableAttribute(llsz));
263263
}
264264

265-
// `&mut` pointer parameters never alias other parameters, or mutable global data
266-
//
267-
// `&T` where `T` contains no `UnsafeCell<U>` is immutable, and can be marked as both
268-
// `readonly` and `noalias`, as LLVM's definition of `noalias` is based solely on
269-
// memory dependencies rather than pointer equality
270-
ty::TyRef(b, mt) if mt.mutbl == ast::MutMutable ||
271-
!ty::type_contents(ccx.tcx(), mt.ty).interior_unsafe() => {
272-
273-
let llsz = machine::llsize_of_real(ccx, type_of::type_of(ccx, mt.ty));
274-
attrs.arg(idx, llvm::Attribute::NoAlias)
275-
.arg(idx, llvm::DereferenceableAttribute(llsz));
265+
ty::TyRef(b, mt) => {
266+
// `&mut` pointer parameters never alias other parameters, or mutable global data
267+
//
268+
// `&T` where `T` contains no `UnsafeCell<U>` is immutable, and can be marked as
269+
// both `readonly` and `noalias`, as LLVM's definition of `noalias` is based solely
270+
// on memory dependencies rather than pointer equality
271+
let interior_unsafe = ty::type_contents(ccx.tcx(), mt.ty).interior_unsafe();
272+
273+
if mt.mutbl == ast::MutMutable || !interior_unsafe {
274+
attrs.arg(idx, llvm::Attribute::NoAlias);
275+
}
276276

277-
if mt.mutbl == ast::MutImmutable {
277+
if mt.mutbl == ast::MutImmutable && !interior_unsafe {
278278
attrs.arg(idx, llvm::Attribute::ReadOnly);
279279
}
280280

281+
// & pointer parameters are also never null and we know exactly
282+
// how many bytes we can dereference
283+
let llsz = machine::llsize_of_real(ccx, type_of::type_of(ccx, mt.ty));
284+
attrs.arg(idx, llvm::DereferenceableAttribute(llsz));
285+
286+
// When a reference in an argument has no named lifetime, it's
287+
// impossible for that reference to escape this function
288+
// (returned or stored beyond the call by a closure).
281289
if let ReLateBound(_, BrAnon(_)) = *b {
282290
attrs.arg(idx, llvm::Attribute::NoCapture);
283291
}
284292
}
285293

286-
// When a reference in an argument has no named lifetime, it's impossible for that
287-
// reference to escape this function (returned or stored beyond the call by a closure).
288-
ty::TyRef(&ReLateBound(_, BrAnon(_)), mt) => {
289-
let llsz = machine::llsize_of_real(ccx, type_of::type_of(ccx, mt.ty));
290-
attrs.arg(idx, llvm::Attribute::NoCapture)
291-
.arg(idx, llvm::DereferenceableAttribute(llsz));
292-
}
293-
294-
// & pointer parameters are also never null and we know exactly how
295-
// many bytes we can dereference
296-
ty::TyRef(_, mt) => {
297-
let llsz = machine::llsize_of_real(ccx, type_of::type_of(ccx, mt.ty));
298-
attrs.arg(idx, llvm::DereferenceableAttribute(llsz));
299-
}
300294
_ => ()
301295
}
302296
}

0 commit comments

Comments
 (0)