diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 77ef8a83bce18..80ccdc45d8081 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -99,6 +99,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => { /* cannot have a non-rust abi */ } } + if self.is_scalable_vector_ctor(autoderef.final_ty()) { + let mut err = self.dcx().create_err(errors::ScalableVectorCtor { + span: callee_expr.span, + ty: autoderef.final_ty(), + }); + err.span_label(callee_expr.span, "you can create scalable vectors using intrinsics"); + Ty::new_error(self.tcx, err.emit()); + } + self.register_predicates(autoderef.into_obligations()); let output = match result { @@ -421,6 +430,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None } + fn is_scalable_vector_ctor(&self, callee_ty: Ty<'_>) -> bool { + if let ty::FnDef(def_id, _) = callee_ty.kind() + && let def::DefKind::Ctor(def::CtorOf::Struct, _) = self.tcx.def_kind(def_id) + { + self.tcx + .opt_parent(*def_id) + .and_then(|id| self.tcx.adt_def(id).repr().scalable) + .is_some() + } else { + false + } + } + /// Give appropriate suggestion when encountering `||{/* not callable */}()`, where the /// likely intention is to call the closure, suggest `(||{})()`. (#55851) fn identify_bad_closure_def_and_call( diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index e0467f4dc6ed2..6524961f28c86 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -569,6 +569,14 @@ pub(crate) struct InvalidCallee<'tcx> { pub found: String, } +#[derive(Diagnostic)] +#[diag("scalable vector types cannot be initialised using their constructor")] +pub(crate) struct ScalableVectorCtor<'tcx> { + #[primary_span] + pub span: Span, + pub ty: Ty<'tcx>, +} + #[derive(Diagnostic)] #[diag("cannot cast `{$expr_ty}` to a pointer that {$known_wide -> [true] is diff --git a/tests/ui/scalable-vectors/illegal_init.rs b/tests/ui/scalable-vectors/illegal_init.rs new file mode 100644 index 0000000000000..e8c0447fea422 --- /dev/null +++ b/tests/ui/scalable-vectors/illegal_init.rs @@ -0,0 +1,10 @@ +#![allow(incomplete_features, internal_features)] +#![feature(rustc_attrs)] + +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +struct svint32_t(i32); +fn main() { + let foo = svint32_t(1); + //~^ ERROR: scalable vector types cannot be initialised using their constructor +} diff --git a/tests/ui/scalable-vectors/illegal_init.stderr b/tests/ui/scalable-vectors/illegal_init.stderr new file mode 100644 index 0000000000000..db0fffcf3b772 --- /dev/null +++ b/tests/ui/scalable-vectors/illegal_init.stderr @@ -0,0 +1,8 @@ +error: scalable vector types cannot be initialised using their constructor + --> $DIR/illegal_init.rs:8:15 + | +LL | let foo = svint32_t(1); + | ^^^^^^^^^ you can create scalable vectors using intrinsics + +error: aborting due to 1 previous error +