]> git.lizzy.rs Git - rust.git/commitdiff
Add an attribute to be able to configure the limit
authorOli Scherer <github35764891676564198441@oli-obk.de>
Fri, 26 Mar 2021 16:28:52 +0000 (16:28 +0000)
committerFelix S. Klock II <pnkfelix@pnkfx.org>
Tue, 20 Apr 2021 13:30:28 +0000 (09:30 -0400)
compiler/rustc_feature/src/active.rs
compiler/rustc_feature/src/builtin_attrs.rs
compiler/rustc_lint_defs/src/builtin.rs
compiler/rustc_middle/src/middle/limits.rs
compiler/rustc_mir/src/monomorphize/collector.rs
compiler/rustc_session/src/session.rs
compiler/rustc_span/src/symbol.rs
src/test/ui/async-await/large_moves.rs
src/test/ui/async-await/large_moves.stderr
src/test/ui/feature-gates/feature-gate-large-assignments.rs [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-large-assignments.stderr [new file with mode: 0644]

index a410826d3fda6fcda8a6089f0e850a19101ec8e4..eb143e5bac22de4b87e646bdf7d574d902a42d04 100644 (file)
@@ -633,6 +633,9 @@ pub fn set(&self, features: &mut Features, span: Span) {
     /// Allows associated types in inherent impls.
     (active, inherent_associated_types, "1.52.0", Some(8995), None),
 
+    // Allows setting the threshold for the `large_assignments` lint.
+    (active, large_assignments, "1.52.0", Some(83518), None),
+
     /// Allows `extern "C-unwind" fn` to enable unwinding across ABI boundaries.
     (active, c_unwind, "1.52.0", Some(74990), None),
 
index 43054f5bf5e708717bbe13e3386946e522a4000b..8dfc4572a848c3de56f53529bab16a75795448c1 100644 (file)
@@ -241,6 +241,10 @@ macro_rules! experimental {
         const_eval_limit, CrateLevel, template!(NameValueStr: "N"), const_eval_limit,
         experimental!(const_eval_limit)
     ),
+    gated!(
+        move_size_limit, CrateLevel, template!(NameValueStr: "N"), large_assignments,
+        experimental!(move_size_limit)
+    ),
 
     // Entry point:
     ungated!(main, Normal, template!(Word)),
index e29005c0c897d5e4cf52966e6f225ec3a0f66dd7..2edb8b717fd57f28c9f037234fdf789e6e84d464 100644 (file)
     /// This lint will trigger on all sites of large moves and thus allow the
     /// user to resolve them in code.
     pub LARGE_ASSIGNMENTS,
-    Allow,
+    Warn,
     "detects large moves or copies",
 }
 
index 61f850c2fc166fa86da21a1b1462158ea5372bbf..601198fd0de0443090df30821db510102dee1d82 100644 (file)
@@ -1,4 +1,8 @@
-//! Registering limits, recursion_limit, type_length_limit and const_eval_limit
+//! Registering limits:
+//! * recursion_limit,
+//! * move_size_limit,
+//! * type_length_limit, and
+//! * const_eval_limit
 //!
 //! There are various parts of the compiler that must impose arbitrary limits
 //! on how deeply they recurse to prevent stack overflow. Users can override
 use crate::bug;
 use rustc_ast as ast;
 use rustc_data_structures::sync::OnceCell;
-use rustc_session::{Limit, Session};
+use rustc_session::Session;
 use rustc_span::symbol::{sym, Symbol};
 
 use std::num::IntErrorKind;
 
 pub fn update_limits(sess: &Session, krate: &ast::Crate) {
     update_limit(sess, krate, &sess.recursion_limit, sym::recursion_limit, 128);
+    update_limit(sess, krate, &sess.move_size_limit, sym::move_size_limit, 0);
     update_limit(sess, krate, &sess.type_length_limit, sym::type_length_limit, 1048576);
     update_limit(sess, krate, &sess.const_eval_limit, sym::const_eval_limit, 1_000_000);
 }
@@ -22,7 +27,7 @@ pub fn update_limits(sess: &Session, krate: &ast::Crate) {
 fn update_limit(
     sess: &Session,
     krate: &ast::Crate,
-    limit: &OnceCell<Limit>,
+    limit: &OnceCell<impl From<usize> + std::fmt::Debug>,
     name: Symbol,
     default: usize,
 ) {
@@ -34,7 +39,7 @@ fn update_limit(
         if let Some(s) = attr.value_str() {
             match s.as_str().parse() {
                 Ok(n) => {
-                    limit.set(Limit::new(n)).unwrap();
+                    limit.set(From::from(n)).unwrap();
                     return;
                 }
                 Err(e) => {
@@ -63,5 +68,5 @@ fn update_limit(
             }
         }
     }
-    limit.set(Limit::new(default)).unwrap();
+    limit.set(From::from(default)).unwrap();
 }
index 8ff3edac65fbe05c884bfa09f4865af4d722888c..e621bc9167d801dc3c4f2587e0ac714e8684a741 100644 (file)
@@ -757,11 +757,16 @@ fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Loc
 
     fn visit_operand(&mut self, operand: &mir::Operand<'tcx>, location: Location) {
         self.super_operand(operand, location);
+        let limit = self.tcx.sess.move_size_limit();
+        if limit == 0 {
+            return;
+        }
+        let limit = Size::from_bytes(limit);
         let ty = operand.ty(self.body, self.tcx);
         let ty = self.monomorphize(ty);
         let layout = self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty));
         if let Ok(layout) = layout {
-            if layout.size > Size::from_bytes(1000) {
+            if layout.size > limit {
                 debug!(?layout);
                 let source_info = self.body.source_info(location);
                 debug!(?source_info);
index cc2583be94474ea208f77f4c1a9fe446e45f4549..7bff634fb2dd09baef261966758669e942e8fec9 100644 (file)
@@ -83,6 +83,12 @@ pub fn value_within_limit(&self, value: usize) -> bool {
     }
 }
 
+impl From<usize> for Limit {
+    fn from(value: usize) -> Self {
+        Self::new(value)
+    }
+}
+
 impl fmt::Display for Limit {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "{}", self.0)
@@ -143,6 +149,10 @@ pub struct Session {
     /// operations such as auto-dereference and monomorphization.
     pub recursion_limit: OnceCell<Limit>,
 
+    /// The size at which the `large_assignments` lint starts
+    /// being emitted.
+    pub move_size_limit: OnceCell<usize>,
+
     /// The maximum length of types during monomorphization.
     pub type_length_limit: OnceCell<Limit>,
 
@@ -352,6 +362,11 @@ pub fn recursion_limit(&self) -> Limit {
         self.recursion_limit.get().copied().unwrap()
     }
 
+    #[inline]
+    pub fn move_size_limit(&self) -> usize {
+        self.move_size_limit.get().copied().unwrap()
+    }
+
     #[inline]
     pub fn type_length_limit(&self) -> Limit {
         self.type_length_limit.get().copied().unwrap()
@@ -1414,6 +1429,7 @@ pub fn build_session(
         features: OnceCell::new(),
         lint_store: OnceCell::new(),
         recursion_limit: OnceCell::new(),
+        move_size_limit: OnceCell::new(),
         type_length_limit: OnceCell::new(),
         const_eval_limit: OnceCell::new(),
         incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)),
index 52270f0e6277b0412cc96c3a1fc8f1262adfc701..5c46e7d9af90dce53cf29d65f4fe0c6c1d971ff0 100644 (file)
         label_break_value,
         lang,
         lang_items,
+        large_assignments,
         lateout,
         lazy_normalization_consts,
         le,
         more_struct_aliases,
         movbe_target_feature,
         move_ref_pattern,
+        move_size_limit,
         mul,
         mul_assign,
         mul_with_overflow,
index 7e6819d6d139092dc08216f9b2b401966cca3ec0..fff23db3351e8d26a02a63a2edf2f6c834fdf84a 100644 (file)
@@ -1,4 +1,6 @@
 #![deny(large_assignments)]
+#![feature(large_assignments)]
+#![move_size_limit = "1000"]
 // build-fail
 
 // edition:2018
index d395d2ae8696d123a223b5b00ab76861d664f4fb..476f5875beb3b047db5465a5afbab858dbe7e4b9 100644 (file)
@@ -1,5 +1,5 @@
 error: moving 10024 bytes
-  --> $DIR/large_moves.rs:7:13
+  --> $DIR/large_moves.rs:9:13
    |
 LL |       let x = async {
    |  _____________^
@@ -17,19 +17,19 @@ LL | #![deny(large_assignments)]
    |         ^^^^^^^^^^^^^^^^^
 
 error: moving 10024 bytes
-  --> $DIR/large_moves.rs:13:14
+  --> $DIR/large_moves.rs:15:14
    |
 LL |     let z = (x, 42);
    |              ^ value moved from here
 
 error: moving 10024 bytes
-  --> $DIR/large_moves.rs:13:13
+  --> $DIR/large_moves.rs:15:13
    |
 LL |     let z = (x, 42);
    |             ^^^^^^^ value moved from here
 
 error: moving 10024 bytes
-  --> $DIR/large_moves.rs:15:13
+  --> $DIR/large_moves.rs:17:13
    |
 LL |     let a = z.0;
    |             ^^^ value moved from here
diff --git a/src/test/ui/feature-gates/feature-gate-large-assignments.rs b/src/test/ui/feature-gates/feature-gate-large-assignments.rs
new file mode 100644 (file)
index 0000000..7e9e574
--- /dev/null
@@ -0,0 +1,5 @@
+// check that `move_size_limit is feature-gated
+
+#![move_size_limit = "42"] //~ ERROR the `#[move_size_limit]` attribute is an experimental feature
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-large-assignments.stderr b/src/test/ui/feature-gates/feature-gate-large-assignments.stderr
new file mode 100644 (file)
index 0000000..8ddc304
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0658]: the `#[move_size_limit]` attribute is an experimental feature
+  --> $DIR/feature-gate-large-assignments.rs:3:1
+   |
+LL | #![move_size_limit = "42"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #83518 <https://github.com/rust-lang/rust/issues/83518> for more information
+   = help: add `#![feature(large_assignments)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.