+
+fn error_min_const_fn_violation(tcx: TyCtxt<'_>, span: Span, msg: Cow<'_, str>) {
+ struct_span_err!(tcx.sess, span, E0723, "{}", msg)
+ .note("for more information, see issue https://github.com/rust-lang/rust/issues/57563")
+ .help("add `#![feature(const_fn)]` to the crate attributes to enable")
+ .emit();
+}
+
+fn check_short_circuiting_in_const_local(item: &Item<'_, 'tcx>) {
+ let body = item.body;
+
+ if body.control_flow_destroyed.is_empty() {
+ return;
+ }
+
+ let mut locals = body.vars_iter();
+ if let Some(local) = locals.next() {
+ let span = body.local_decls[local].source_info.span;
+ let mut error = item.tcx.sess.struct_span_err(
+ span,
+ &format!(
+ "new features like let bindings are not permitted in {}s \
+ which also use short circuiting operators",
+ item.const_kind(),
+ ),
+ );
+ for (span, kind) in body.control_flow_destroyed.iter() {
+ error.span_note(
+ *span,
+ &format!("use of {} here does not actually short circuit due to \
+ the const evaluator presently not being able to do control flow. \
+ See https://github.com/rust-lang/rust/issues/49146 for more \
+ information.", kind),
+ );
+ }
+ for local in locals {
+ let span = body.local_decls[local].source_info.span;
+ error.span_note(span, "more locals defined here");
+ }
+ error.emit();
+ }
+}
+
+fn check_return_ty_is_sync(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, hir_id: HirId) {
+ let ty = body.return_ty();
+ tcx.infer_ctxt().enter(|infcx| {
+ let cause = traits::ObligationCause::new(body.span, hir_id, traits::SharedStatic);
+ let mut fulfillment_cx = traits::FulfillmentContext::new();
+ let sync_def_id = tcx.require_lang_item(lang_items::SyncTraitLangItem, Some(body.span));
+ fulfillment_cx.register_bound(&infcx, ty::ParamEnv::empty(), ty, sync_def_id, cause);
+ if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
+ infcx.report_fulfillment_errors(&err, None, false);
+ }
+ });
+}