Skip to content

Commit 0100a94

Browse files
rustc_layout_scalar_valid_range makes ctors unsafe
1 parent 59a8294 commit 0100a94

File tree

3 files changed

+36
-8
lines changed

3 files changed

+36
-8
lines changed

compiler/rustc_hir_analysis/src/collect.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use rustc_trait_selection::infer::InferCtxtExt;
3838
use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
3939
use rustc_trait_selection::traits::ObligationCtxt;
4040
use std::iter;
41+
use std::ops::Bound;
4142

4243
mod generics_of;
4344
mod item_bounds;
@@ -1144,15 +1145,15 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
11441145
}
11451146

11461147
Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => {
1147-
let ty = tcx.type_of(tcx.hir().get_parent_item(hir_id)).instantiate_identity();
1148+
let adt_def_id = tcx.hir().get_parent_item(hir_id).def_id.to_def_id();
1149+
let ty = tcx.type_of(adt_def_id).instantiate_identity();
11481150
let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id).instantiate_identity());
1149-
ty::Binder::dummy(tcx.mk_fn_sig(
1150-
inputs,
1151-
ty,
1152-
false,
1153-
hir::Unsafety::Normal,
1154-
abi::Abi::Rust,
1155-
))
1151+
// constructors for structs with `layout_scalar_valid_range` are unsafe to call
1152+
let safety = match tcx.layout_scalar_valid_range(adt_def_id) {
1153+
(Bound::Unbounded, Bound::Unbounded) => hir::Unsafety::Normal,
1154+
_ => hir::Unsafety::Unsafe,
1155+
};
1156+
ty::Binder::dummy(tcx.mk_fn_sig(inputs, ty, false, safety, abi::Abi::Rust))
11561157
}
11571158

11581159
Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![feature(rustc_attrs)]
2+
#![allow(internal_features)]
3+
4+
#[derive(Debug)]
5+
#[rustc_layout_scalar_valid_range_start(2)]
6+
struct NonZeroAndOneU8(u8);
7+
8+
fn main() {
9+
println!("{:?}", Some(1).map(NonZeroAndOneU8).unwrap());
10+
//~^ ERROR found `unsafe fn(u8) -> NonZeroAndOneU8 {NonZeroAndOneU8}`
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0277]: expected a `FnOnce<({integer},)>` closure, found `unsafe fn(u8) -> NonZeroAndOneU8 {NonZeroAndOneU8}`
2+
--> $DIR/initializing-ranged-via-ctor.rs:9:34
3+
|
4+
LL | println!("{:?}", Some(1).map(NonZeroAndOneU8).unwrap());
5+
| --- ^^^^^^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
= help: the trait `FnOnce<({integer},)>` is not implemented for fn item `unsafe fn(u8) -> NonZeroAndOneU8 {NonZeroAndOneU8}`
10+
= note: unsafe function cannot be called generically without an unsafe block
11+
note: required by a bound in `Option::<T>::map`
12+
--> $SRC_DIR/core/src/option.rs:LL:COL
13+
14+
error: aborting due to previous error
15+
16+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)