From 8d288d0ef05979c9c8e7de58ca73ad4a1a92a8c2 Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Sun, 10 Jun 2018 16:57:40 +0800 Subject: [PATCH] report const excess time limt as lint --- src/librustc/lint/builtin.rs | 6 ++++++ src/librustc_mir/interpret/step.rs | 25 +++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index de583e81ca831..2bc77cc88cf2e 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -31,6 +31,12 @@ declare_lint! { "constant evaluation detected erroneous expression" } +declare_lint! { + pub CONST_TIME_LIMIT, + Warn, + "constant evaluating a complex constant, this might take some time" +} + declare_lint! { pub UNUSED_IMPORTS, Warn, diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index ab15278219f40..e0a1a8d990c0b 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -3,6 +3,7 @@ //! The main entry point is the `step` method. use rustc::mir; +use rustc::lint; use rustc::mir::interpret::EvalResult; use super::{EvalContext, Machine}; @@ -11,8 +12,28 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { pub fn inc_step_counter_and_check_limit(&mut self, n: usize) { self.terminators_remaining = self.terminators_remaining.saturating_sub(n); if self.terminators_remaining == 0 { - // FIXME(#49980): make this warning a lint - self.tcx.sess.span_warn(self.frame().span, "Constant evaluating a complex constant, this might take some time"); + let msg = "constant evaluating a complex constant, this might take some time"; + let lint = ::rustc::lint::builtin::CONST_TIME_LIMIT; + let node_id = self + .stack() + .iter() + .rev() + .filter_map(|frame| frame.lint_root) + .next() + .or(lint_root) + .expect("some part of a failing const eval must be local"); + let err = self.tcx.struct_span_lint_node( + lint, + node_id, + self.frame().span, + msg, + ); + if self.lint_level_at_node(lint, node_id).0 == lint::Level::Deny || + self.lint_level_at_node(lint, node_id).0 == lint::Level::Forbid { + err.report_as_err(self.tcx, msg, node_id); + } else { + err.report_as_lint(self.tcx, msg); + } self.terminators_remaining = 1_000_000; } }