From 240907bbdef95fa5900daccdc3bb2d0a1e4ab82f Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Wed, 30 Dec 2020 19:37:39 +0100 Subject: [PATCH 01/24] #[doc(inline)] sym_generated --- compiler/rustc_span/src/symbol.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index bc57a00e31b..928a405a9de 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1583,6 +1583,7 @@ pub mod sym { use super::Symbol; use std::convert::TryInto; + #[doc(inline)] pub use super::sym_generated::*; // Used from a macro in `librustc_feature/accepted.rs` From a26fa74d3cba37a6e1df2dffae00c522546350a3 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Mon, 8 Feb 2021 13:48:10 -0500 Subject: [PATCH 02/24] Make `header` a vec of modifiers, make FunctionPointer consistent with Function and Method. --- src/etc/check_missing_items.py | 2 +- src/librustdoc/json/conversions.rs | 31 +++++++++++++++------- src/librustdoc/json/mod.rs | 2 +- src/rustdoc-json-types/lib.rs | 17 +++++++++--- src/test/rustdoc-json/fn_pointer/header.rs | 5 ++++ src/test/rustdoc-json/fns/header.rs | 20 ++++++++++++++ src/test/rustdoc-json/methods/header.rs | 24 +++++++++++++++++ 7 files changed, 85 insertions(+), 16 deletions(-) create mode 100644 src/test/rustdoc-json/fn_pointer/header.rs create mode 100644 src/test/rustdoc-json/fns/header.rs create mode 100644 src/test/rustdoc-json/methods/header.rs diff --git a/src/etc/check_missing_items.py b/src/etc/check_missing_items.py index c7ca0134f9c..7572b8c6f4a 100644 --- a/src/etc/check_missing_items.py +++ b/src/etc/check_missing_items.py @@ -108,7 +108,7 @@ def check_type(ty): elif ty["kind"] == "function_pointer": for param in ty["inner"]["generic_params"]: check_generic_param(param) - check_decl(ty["inner"]["inner"]) + check_decl(ty["inner"]["decl"]) elif ty["kind"] == "qualified_path": check_type(ty["inner"]["self_type"]) check_type(ty["inner"]["trait"]) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index e021faa5041..af44ab9868e 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -225,15 +225,22 @@ fn from(struct_: clean::Union) -> Self { } } -fn stringify_header(header: &rustc_hir::FnHeader) -> String { - let mut s = String::from(header.unsafety.prefix_str()); - if header.asyncness == rustc_hir::IsAsync::Async { - s.push_str("async ") +crate fn from_fn_header(header: &rustc_hir::FnHeader) -> Vec { + let mut v = Vec::new(); + + if let rustc_hir::Unsafety::Unsafe = header.unsafety { + v.push(Modifiers::Unsafe); } - if header.constness == rustc_hir::Constness::Const { - s.push_str("const ") + + if let rustc_hir::IsAsync::Async = header.asyncness { + v.push(Modifiers::Async); } - s + + if let rustc_hir::Constness::Const = header.constness { + v.push(Modifiers::Const); + } + + v } impl From for Function { @@ -242,7 +249,7 @@ fn from(function: clean::Function) -> Self { Function { decl: decl.into(), generics: generics.into(), - header: stringify_header(&header), + header: from_fn_header(&header), abi: header.abi.to_string(), } } @@ -364,7 +371,11 @@ impl From for FunctionPointer { fn from(bare_decl: clean::BareFunctionDecl) -> Self { let clean::BareFunctionDecl { unsafety, generic_params, decl, abi } = bare_decl; FunctionPointer { - is_unsafe: unsafety == rustc_hir::Unsafety::Unsafe, + header: if let rustc_hir::Unsafety::Unsafe = unsafety { + vec![Modifiers::Unsafe] + } else { + vec![] + }, generic_params: generic_params.into_iter().map(Into::into).collect(), decl: decl.into(), abi: abi.to_string(), @@ -439,7 +450,7 @@ fn from(impl_: clean::Impl) -> Self { Method { decl: decl.into(), generics: generics.into(), - header: stringify_header(&header), + header: from_fn_header(&header), abi: header.abi.to_string(), has_body, } diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 876b1b56dee..b31276c9dcb 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -243,7 +243,7 @@ fn after_krate( ) }) .collect(), - format_version: 3, + format_version: 4, }; let mut p = self.out_path.clone(); p.push(output.index.get(&output.root).unwrap().name.clone().unwrap()); diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index f4b8dc9a3ad..790f9d62d8a 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -281,11 +281,20 @@ pub enum StructType { Unit, } +#[non_exhaustive] +#[serde(rename_all = "snake_case")] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +pub enum Modifiers { + Const, + Unsafe, + Async, +} + #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] pub struct Function { pub decl: FnDecl, pub generics: Generics, - pub header: String, + pub header: Vec, pub abi: String, } @@ -293,7 +302,7 @@ pub struct Function { pub struct Method { pub decl: FnDecl, pub generics: Generics, - pub header: String, + pub header: Vec, pub abi: String, pub has_body: bool, } @@ -404,9 +413,9 @@ pub enum Type { #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] pub struct FunctionPointer { - pub is_unsafe: bool, - pub generic_params: Vec, pub decl: FnDecl, + pub generic_params: Vec, + pub header: Vec, pub abi: String, } diff --git a/src/test/rustdoc-json/fn_pointer/header.rs b/src/test/rustdoc-json/fn_pointer/header.rs new file mode 100644 index 00000000000..a5038e0cd2a --- /dev/null +++ b/src/test/rustdoc-json/fn_pointer/header.rs @@ -0,0 +1,5 @@ +// @has header.json "$.index[*][?(@.name=='FnPointer')].inner.type.inner.header" "[]" +pub type FnPointer = fn(); + +// @has - "$.index[*][?(@.name=='UnsafePointer')].inner.type.inner.header" '["unsafe"]' +pub type UnsafePointer = unsafe fn(); diff --git a/src/test/rustdoc-json/fns/header.rs b/src/test/rustdoc-json/fns/header.rs new file mode 100644 index 00000000000..fb4f89db267 --- /dev/null +++ b/src/test/rustdoc-json/fns/header.rs @@ -0,0 +1,20 @@ +// edition:2018 + +// @has header.json "$.index[*][?(@.name=='nothing_fn')].inner.header" "[]" +pub fn nothing_fn() {} + +// @has - "$.index[*][?(@.name=='const_fn')].inner.header" '["const"]' +pub const fn const_fn() {} + +// @has - "$.index[*][?(@.name=='async_fn')].inner.header" '["async"]' +pub async fn async_fn() {} + +// @count - "$.index[*][?(@.name=='async_unsafe_fn')].inner.header[*]" 2 +// @has - "$.index[*][?(@.name=='async_unsafe_fn')].inner.header[*]" '"async"' +// @has - "$.index[*][?(@.name=='async_unsafe_fn')].inner.header[*]" '"unsafe"' +pub async unsafe fn async_unsafe_fn() {} + +// @count - "$.index[*][?(@.name=='const_unsafe_fn')].inner.header[*]" 2 +// @has - "$.index[*][?(@.name=='const_unsafe_fn')].inner.header[*]" '"const"' +// @has - "$.index[*][?(@.name=='const_unsafe_fn')].inner.header[*]" '"unsafe"' +pub const unsafe fn const_unsafe_fn() {} diff --git a/src/test/rustdoc-json/methods/header.rs b/src/test/rustdoc-json/methods/header.rs new file mode 100644 index 00000000000..27a6ec04730 --- /dev/null +++ b/src/test/rustdoc-json/methods/header.rs @@ -0,0 +1,24 @@ +// edition:2018 + +pub struct Foo; + +impl Foo { + // @has header.json "$.index[*][?(@.name=='nothing_meth')].inner.header" "[]" + pub fn nothing_meth() {} + + // @has - "$.index[*][?(@.name=='const_meth')].inner.header" '["const"]' + pub const fn const_meth() {} + + // @has - "$.index[*][?(@.name=='async_meth')].inner.header" '["async"]' + pub async fn async_meth() {} + + // @count - "$.index[*][?(@.name=='async_unsafe_meth')].inner.header[*]" 2 + // @has - "$.index[*][?(@.name=='async_unsafe_meth')].inner.header[*]" '"async"' + // @has - "$.index[*][?(@.name=='async_unsafe_meth')].inner.header[*]" '"unsafe"' + pub async unsafe fn async_unsafe_meth() {} + + // @count - "$.index[*][?(@.name=='const_unsafe_meth')].inner.header[*]" 2 + // @has - "$.index[*][?(@.name=='const_unsafe_meth')].inner.header[*]" '"const"' + // @has - "$.index[*][?(@.name=='const_unsafe_meth')].inner.header[*]" '"unsafe"' + pub const unsafe fn const_unsafe_meth() {} +} From ce02b7f7a6f554dbf80b7cabc09c3d84d92d0c3a Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Mon, 8 Feb 2021 15:45:50 -0500 Subject: [PATCH 03/24] Add comment + move derive helper --- src/rustdoc-json-types/lib.rs | 2 +- src/test/rustdoc-json/fns/header.rs | 2 ++ src/test/rustdoc-json/methods/header.rs | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 790f9d62d8a..20bae0f14a2 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -282,8 +282,8 @@ pub enum StructType { } #[non_exhaustive] -#[serde(rename_all = "snake_case")] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "snake_case")] pub enum Modifiers { Const, Unsafe, diff --git a/src/test/rustdoc-json/fns/header.rs b/src/test/rustdoc-json/fns/header.rs index fb4f89db267..29741dd50da 100644 --- a/src/test/rustdoc-json/fns/header.rs +++ b/src/test/rustdoc-json/fns/header.rs @@ -18,3 +18,5 @@ pub async fn async_fn() {} // @has - "$.index[*][?(@.name=='const_unsafe_fn')].inner.header[*]" '"const"' // @has - "$.index[*][?(@.name=='const_unsafe_fn')].inner.header[*]" '"unsafe"' pub const unsafe fn const_unsafe_fn() {} + +// It's impossible for a function to be both const and async, so no test for that diff --git a/src/test/rustdoc-json/methods/header.rs b/src/test/rustdoc-json/methods/header.rs index 27a6ec04730..50a3db75ef3 100644 --- a/src/test/rustdoc-json/methods/header.rs +++ b/src/test/rustdoc-json/methods/header.rs @@ -21,4 +21,6 @@ pub async fn async_meth() {} // @has - "$.index[*][?(@.name=='const_unsafe_meth')].inner.header[*]" '"const"' // @has - "$.index[*][?(@.name=='const_unsafe_meth')].inner.header[*]" '"unsafe"' pub const unsafe fn const_unsafe_meth() {} + + // It's impossible for a method to be both const and async, so no test for that } From 0a91daeaa33e4ae71e0be405cdddba741b72aa7f Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Mon, 8 Feb 2021 16:04:14 -0500 Subject: [PATCH 04/24] Vec -> HashSet --- src/librustdoc/json/conversions.rs | 17 ++++++++++------- src/rustdoc-json-types/lib.rs | 10 +++++----- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index af44ab9868e..de0240f28f7 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -14,6 +14,7 @@ use crate::clean; use crate::formats::item_type::ItemType; use crate::json::JsonRenderer; +use std::collections::HashSet; impl JsonRenderer<'_> { pub(super) fn convert_item(&self, item: clean::Item) -> Option { @@ -225,19 +226,19 @@ fn from(struct_: clean::Union) -> Self { } } -crate fn from_fn_header(header: &rustc_hir::FnHeader) -> Vec { - let mut v = Vec::new(); +crate fn from_fn_header(header: &rustc_hir::FnHeader) -> HashSet { + let mut v = HashSet::new(); if let rustc_hir::Unsafety::Unsafe = header.unsafety { - v.push(Modifiers::Unsafe); + v.insert(Modifiers::Unsafe); } if let rustc_hir::IsAsync::Async = header.asyncness { - v.push(Modifiers::Async); + v.insert(Modifiers::Async); } if let rustc_hir::Constness::Const = header.constness { - v.push(Modifiers::Const); + v.insert(Modifiers::Const); } v @@ -372,9 +373,11 @@ fn from(bare_decl: clean::BareFunctionDecl) -> Self { let clean::BareFunctionDecl { unsafety, generic_params, decl, abi } = bare_decl; FunctionPointer { header: if let rustc_hir::Unsafety::Unsafe = unsafety { - vec![Modifiers::Unsafe] + let mut hs = HashSet::new(); + hs.insert(Modifiers::Unsafe); + hs } else { - vec![] + HashSet::new() }, generic_params: generic_params.into_iter().map(Into::into).collect(), decl: decl.into(), diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 20bae0f14a2..a2f323699c1 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -3,7 +3,7 @@ //! These types are the public API exposed through the `--output-format json` flag. The [`Crate`] //! struct is the root of the JSON blob and all other items are contained within. -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::path::PathBuf; use serde::{Deserialize, Serialize}; @@ -282,7 +282,7 @@ pub enum StructType { } #[non_exhaustive] -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] #[serde(rename_all = "snake_case")] pub enum Modifiers { Const, @@ -294,7 +294,7 @@ pub enum Modifiers { pub struct Function { pub decl: FnDecl, pub generics: Generics, - pub header: Vec, + pub header: HashSet, pub abi: String, } @@ -302,7 +302,7 @@ pub struct Function { pub struct Method { pub decl: FnDecl, pub generics: Generics, - pub header: Vec, + pub header: HashSet, pub abi: String, pub has_body: bool, } @@ -415,7 +415,7 @@ pub enum Type { pub struct FunctionPointer { pub decl: FnDecl, pub generic_params: Vec, - pub header: Vec, + pub header: HashSet, pub abi: String, } From ffa5280b0ed19400e2095ce6cc2eb6e888d6bd01 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Mon, 8 Feb 2021 16:17:00 -0500 Subject: [PATCH 05/24] Allow default hash types in conversion --- src/librustdoc/json/conversions.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index de0240f28f7..60197a0dc1c 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -2,6 +2,8 @@ //! the `clean` types but with some fields removed or stringified to simplify the output and not //! expose unstable compiler internals. +#![allow(rustc::default_hash_types)] + use std::convert::From; use rustc_ast::ast; From c01036af1d8da0e5e16f8c126fa0017049d52636 Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Sun, 27 Dec 2020 01:13:51 -0500 Subject: [PATCH 06/24] Implement the precise analysis pass for lint `disjoint_capture_drop_reorder` --- compiler/rustc_typeck/src/check/upvar.rs | 322 ++++++++++++++++++++++- 1 file changed, 317 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 04a9e65e664..4d21629cd69 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -40,13 +40,16 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_infer::infer::UpvarRegion; -use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, ProjectionKind}; +use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection, ProjectionKind}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{self, Ty, TyCtxt, TypeckResults, UpvarSubsts}; use rustc_session::lint; use rustc_span::sym; use rustc_span::{MultiSpan, Span, Symbol}; +use rustc_index::vec::Idx; +use rustc_target::abi::VariantIdx; + /// Describe the relationship between the paths of two places /// eg: /// - `foo` is ancestor of `foo.bar.baz` @@ -537,7 +540,7 @@ fn perform_2229_migration_anaysis( span: Span, body: &'tcx hir::Body<'tcx>, ) { - let need_migrations = self.compute_2229_migrations_first_pass( + let need_migrations_first_pass = self.compute_2229_migrations_first_pass( closure_def_id, span, capture_clause, @@ -545,10 +548,15 @@ fn perform_2229_migration_anaysis( self.typeck_results.borrow().closure_min_captures.get(&closure_def_id), ); - if !need_migrations.is_empty() { - let need_migrations_hir_id = need_migrations.iter().map(|m| m.0).collect::>(); + let need_migrations = self.compute_2229_migrations_precise_pass( + closure_def_id, + span, + self.typeck_results.borrow().closure_min_captures.get(&closure_def_id), + &need_migrations_first_pass, + ); - let migrations_text = migration_suggestion_for_2229(self.tcx, &need_migrations_hir_id); + if !need_migrations.is_empty() { + let migrations_text = migration_suggestion_for_2229(self.tcx, &need_migrations); let local_def_id = closure_def_id.expect_local(); let closure_hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id); @@ -642,6 +650,310 @@ fn resolve_ty>( need_migrations } + fn compute_2229_migrations_precise_pass( + &self, + closure_def_id: DefId, + closure_span: Span, + min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>, + need_migrations: &[(hir::HirId, Ty<'tcx>)], + ) -> Vec { + // Need migrations -- second pass + let mut need_migrations_2 = Vec::new(); + + for (hir_id, ty) in need_migrations { + let projections_list = min_captures + .and_then(|m| m.get(hir_id)) + .into_iter() + .flatten() + .filter_map(|captured_place| match captured_place.info.capture_kind { + // Only care about captures that are moved into the closure + ty::UpvarCapture::ByValue(..) => { + Some(captured_place.place.projections.as_slice()) + } + ty::UpvarCapture::ByRef(..) => None, + }) + .collect(); + + if self.has_significant_drop_outside_of_captures( + closure_def_id, + closure_span, + ty, + projections_list, + ) { + need_migrations_2.push(*hir_id); + } + } + + need_migrations_2 + } + + /// This is a helper function to `compute_2229_migrations_precise_pass`. Provided the type + /// of a root variable and a list of captured paths starting at this root variable (expressed + /// using list of `Projection` slices), it returns true if there is a path that is not + /// captured starting at this root variable that implements Drop. + /// + /// FIXME(project-rfc-2229#35): This should return true only for significant drops. + /// A drop is significant if it's implemented by the user or does + /// anything that will have any observable behavior (other than + /// freeing up memory). + /// + /// The way this function works is at a given call it looks at type `base_path_ty` of some base + /// path say P and then vector of projection slices which represent the different captures + /// starting off of P. + /// + /// This will make more sense with an example: + /// + /// ```rust + /// #![feature(capture_disjoint_fields)] + /// + /// struct FancyInteger(i32); // This implements Drop + /// + /// struct Point { x: FancyInteger, y: FancyInteger } + /// struct Color; + /// + /// struct Wrapper { p: Point, c: Color } + /// + /// fn f(w: Wrapper) { + /// let c = || { + /// // Closure captures w.p.x and w.c by move. + /// }; + /// + /// c(); + /// } + /// ``` + /// + /// If `capture_disjoint_fields` wasn't enabled the closure would've moved `w` instead of the + /// precise paths. If we look closely `w.p.y` isn't captured which implements Drop and + /// therefore Drop ordering would change and we want this function to return true. + /// + /// Call stack to figure out if we need to migrate for `w` would look as follows: + /// + /// Our initial base path is just `w`, and the paths captured from it are `w[p, x]` and + /// `w[c]`. + /// Notation: + /// - Ty(place): Type of place + /// - `(a, b)`: Represents the function parameters `base_path_ty` and `captured_projs` + /// respectively. + /// ``` + /// (Ty(w), [ &[p, x], &[c] ]) + /// | + /// ---------------------------- + /// | | + /// v v + /// (Ty(w.p), [ &[x] ]) (Ty(w.c), [ &[] ]) // I(1) + /// | | + /// v v + /// (Ty(w.p), [ &[x] ]) false + /// | + /// | + /// ------------------------------- + /// | | + /// v v + /// (Ty((w.p).x), [ &[] ]) (Ty((w.p).y), []) // IMP 2 + /// | | + /// v v + /// false NeedsDrop(Ty(w.p.y)) + /// | + /// v + /// true + /// ``` + /// + /// IMP 1 `(Ty(w.c), [ &[] ])`: Notice the single empty slice inside `captured_projs`. + /// This implies that the `w.c` is completely captured by the closure. + /// Since drop for this path will be called when the closure is + /// dropped we don't need to migrate for it. + /// + /// IMP 2 `(Ty((w.p).y), [])`: Notice that `captured_projs` is empty. This implies that this + /// path wasn't captured by the closure. Also note that even + /// though we didn't capture this path, the function visits it, + /// which is kind of the point of this function. We then return + /// if the type of `w.p.y` implements Drop, which in this case is + /// true. + /// + /// Consider another example: + /// + /// ```rust + /// struct X; + /// impl Drop for X {} + /// + /// struct Y(X); + /// impl Drop for Y {} + /// + /// fn foo() { + /// let y = Y(X); + /// let c = || move(y.0); + /// } + /// ``` + /// + /// Note that `y.0` is captured by the closure. When this function is called for `y`, it will + /// return true, because even though all paths starting at `y` are captured, `y` itself + /// implements Drop which will be affected since `y` isn't completely captured. + fn has_significant_drop_outside_of_captures( + &self, + closure_def_id: DefId, + closure_span: Span, + base_path_ty: Ty<'tcx>, + captured_projs: Vec<&[Projection<'tcx>]>, + ) -> bool { + let needs_drop = |ty: Ty<'tcx>| { + ty.needs_drop(self.tcx, self.tcx.param_env(closure_def_id.expect_local())) + }; + + let is_drop_defined_for_ty = |ty: Ty<'tcx>| { + let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span)); + let ty_params = self.tcx.mk_substs_trait(base_path_ty, &[]); + self.tcx.type_implements_trait(( + drop_trait, + ty, + ty_params, + self.tcx.param_env(closure_def_id.expect_local()), + )) + }; + + let is_drop_defined_for_ty = is_drop_defined_for_ty(base_path_ty); + + // If there is a case where no projection is applied on top of current place + // then there must be exactly one capture corresponding to such a case. Note that this + // represents the case of the path being completely captured by the variable. + // + // eg. If `a.b` is captured and we are processing `a.b`, then we can't have the closure also + // capture `a.b.c`, because that voilates min capture. + let is_completely_captured = captured_projs.iter().any(|projs| projs.is_empty()); + + assert!(!is_completely_captured || (captured_projs.len() == 1)); + + if is_drop_defined_for_ty { + // If drop is implemented for this type then we need it to be fully captured, or + // it will require migration. + return !is_completely_captured; + } + + if is_completely_captured { + // The place is captured entirely, so doesn't matter if needs dtor, it will be drop + // when the closure is dropped. + return false; + } + + match base_path_ty.kind() { + _ if captured_projs.is_empty() => needs_drop(base_path_ty), + + // Observations: + // - `captured_projs` is not empty. Therefore we can call + // `captured_projs.first().unwrap()` safely. + // - All entries in `captured_projs` have atleast one projection. + // Therefore we can call `captured_projs.first().unwrap().first().unwrap()` safely. + ty::Adt(def, _) if def.is_box() => { + // We must deref to access paths on top of a Box. + assert!( + captured_projs + .iter() + .all(|projs| matches!(projs.first().unwrap().kind, ProjectionKind::Deref)) + ); + + let next_ty = captured_projs.first().unwrap().first().unwrap().ty; + let captured_projs = captured_projs.iter().map(|projs| &projs[1..]).collect(); + self.has_significant_drop_outside_of_captures( + closure_def_id, + closure_span, + next_ty, + captured_projs, + ) + } + + ty::Adt(def, substs) => { + // Multi-varaint enums are captured in entirety, + // which would've been handled in the case of single empty slice in `captured_projs`. + assert_eq!(def.variants.len(), 1); + + // Only Field projections can be applied to a non-box Adt. + assert!( + captured_projs.iter().all(|projs| matches!( + projs.first().unwrap().kind, + ProjectionKind::Field(..) + )) + ); + def.variants.get(VariantIdx::new(0)).unwrap().fields.iter().enumerate().any( + |(i, field)| { + let paths_using_field = captured_projs + .iter() + .filter_map(|projs| { + if let ProjectionKind::Field(field_idx, _) = + projs.first().unwrap().kind + { + if (field_idx as usize) == i { Some(&projs[1..]) } else { None } + } else { + unreachable!(); + } + }) + .collect(); + + let after_field_ty = field.ty(self.tcx, substs); + self.has_significant_drop_outside_of_captures( + closure_def_id, + closure_span, + after_field_ty, + paths_using_field, + ) + }, + ) + } + + ty::Tuple(..) => { + // Only Field projections can be applied to a tuple. + assert!( + captured_projs.iter().all(|projs| matches!( + projs.first().unwrap().kind, + ProjectionKind::Field(..) + )) + ); + + base_path_ty.tuple_fields().enumerate().any(|(i, element_ty)| { + let paths_using_field = captured_projs + .iter() + .filter_map(|projs| { + if let ProjectionKind::Field(field_idx, _) = projs.first().unwrap().kind + { + if (field_idx as usize) == i { Some(&projs[1..]) } else { None } + } else { + unreachable!(); + } + }) + .collect(); + + self.has_significant_drop_outside_of_captures( + closure_def_id, + closure_span, + element_ty, + paths_using_field, + ) + }) + } + + ty::Ref(_, deref_ty, _) => { + // Only Derefs can be applied to a Ref + assert!( + captured_projs + .iter() + .all(|projs| matches!(projs.first().unwrap().kind, ProjectionKind::Deref)) + ); + + let captured_projs = captured_projs.iter().map(|projs| &projs[1..]).collect(); + self.has_significant_drop_outside_of_captures( + closure_def_id, + closure_span, + deref_ty, + captured_projs, + ) + } + + // Unsafe Ptrs are captured in their entirety, which would've have been handled in + // the case of single empty slice in `captured_projs`. + ty::RawPtr(..) => unreachable!(), + + _ => unreachable!(), + } + } + fn init_capture_kind( &self, capture_clause: hir::CaptureBy, From 319f1aba6281adb6ca22522003b49578c406745f Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Thu, 4 Feb 2021 18:50:32 -0500 Subject: [PATCH 07/24] Tests for precise lint analysis --- .../migrations/precise.rs | 78 +++++++++++++ .../migrations/precise.stderr | 49 ++++++++ .../migrations/precise_no_migrations.rs | 105 ++++++++++++++++++ 3 files changed, 232 insertions(+) create mode 100644 src/test/ui/closures/2229_closure_analysis/migrations/precise.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs b/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs new file mode 100644 index 00000000000..79702cc6b56 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs @@ -0,0 +1,78 @@ +#![deny(disjoint_capture_drop_reorder)] +//~^ NOTE: the lint level is defined here + +#[derive(Debug)] +struct Foo(i32); +impl Drop for Foo { + fn drop(&mut self) { + println!("{:?} dropped", self.0); + } +} + +struct ConstainsDropField(Foo, Foo); + +#[derive(Debug)] +struct ContainsAndImplsDrop(Foo); +impl Drop for ContainsAndImplsDrop { + fn drop(&mut self) { + println!("{:?} dropped", self.0); + } +} + +// Test that even if all paths starting at root variable that implement Drop are captured, +// the lint is triggered if the root variable implements drop and isn't captured. +fn test_precise_analysis_parent_root_impl_drop_not_captured() { + let t = ContainsAndImplsDrop(Foo(10)); + + let c = || { + //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| NOTE: drop(&(t)); + let _t = t.0; + }; + + c(); +} + +// Test that lint is triggered if a path that implements Drop is not captured by move +fn test_precise_analysis_drop_paths_not_captured_by_move() { + let t = ConstainsDropField(Foo(10), Foo(20)); + + let c = || { + //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| NOTE: drop(&(t)); + let _t = t.0; + let _t = &t.1; + }; + + c(); +} + +struct S; +impl Drop for S { + fn drop(&mut self) { + } +} + +struct T(S, S); +struct U(T, T); + +// Test precise analysis for the lint works with paths longer than one. +fn test_precise_analysis_long_path_missing() { + let u = U(T(S, S), T(S, S)); + + let c = || { + //~^ERROR: drop order affected for closure because of `capture_disjoint_fields` + //~| NOTE: drop(&(u)); + let _x = u.0.0; + let _x = u.0.1; + let _x = u.1.0; + }; + + c(); +} + +fn main() { + test_precise_analysis_parent_root_impl_drop_not_captured(); + test_precise_analysis_drop_paths_not_captured_by_move(); + test_precise_analysis_long_path_missing(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr new file mode 100644 index 00000000000..968ca395f94 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr @@ -0,0 +1,49 @@ +error: drop order affected for closure because of `capture_disjoint_fields` + --> $DIR/precise.rs:27:13 + | +LL | let c = || { + | _____________^ +LL | | +LL | | +LL | | let _t = t.0; +LL | | }; + | |_____^ + | +note: the lint level is defined here + --> $DIR/precise.rs:1:9 + | +LL | #![deny(disjoint_capture_drop_reorder)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: drop(&(t)); + +error: drop order affected for closure because of `capture_disjoint_fields` + --> $DIR/precise.rs:40:13 + | +LL | let c = || { + | _____________^ +LL | | +LL | | +LL | | let _t = t.0; +LL | | let _t = &t.1; +LL | | }; + | |_____^ + | + = note: drop(&(t)); + +error: drop order affected for closure because of `capture_disjoint_fields` + --> $DIR/precise.rs:63:13 + | +LL | let c = || { + | _____________^ +LL | | +LL | | +LL | | let _x = u.0.0; +LL | | let _x = u.0.1; +LL | | let _x = u.1.0; +LL | | }; + | |_____^ + | + = note: drop(&(u)); + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs b/src/test/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs new file mode 100644 index 00000000000..8af48501ca2 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs @@ -0,0 +1,105 @@ +// run-pass + +#![deny(disjoint_capture_drop_reorder)] + +#[derive(Debug)] +struct Foo(i32); +impl Drop for Foo { + fn drop(&mut self) { + println!("{:?} dropped", self.0); + } +} + +struct ConstainsDropField(Foo, Foo); + +// Test that if all paths starting at root variable that implement Drop are captured +// then it doesn't trigger the lint. +fn test_precise_analysis_simple_1() { + let t = (Foo(10), Foo(20), Foo(30)); + + let c = || { + let _t = t.0; + let _t = t.1; + let _t = t.2; + }; + + c(); +} + +// Test that if all paths starting at root variable that implement Drop are captured +// then it doesn't trigger the lint. +fn test_precise_analysis_simple_2() { + let t = ConstainsDropField(Foo(10), Foo(20)); + + let c = || { + let _t = t.0; + let _t = t.1; + }; + + c(); +} + +#[derive(Debug)] +struct ContainsAndImplsDrop(Foo); +impl Drop for ContainsAndImplsDrop { + fn drop(&mut self) { + println!("{:?} dropped", self.0); + } +} + +// If a path isn't directly captured but requires Drop, then this tests that migrations aren't +// needed if the a parent to that path is captured. +fn test_precise_analysis_parent_captured_1() { + let t = ConstainsDropField(Foo(10), Foo(20)); + + let c = || { + let _t = t; + }; + + c(); +} + +// If a path isn't directly captured but requires Drop, then this tests that migrations aren't +// needed if the a parent to that path is captured. +fn test_precise_analysis_parent_captured_2() { + let t = ContainsAndImplsDrop(Foo(10)); + + let c = || { + let _t = t; + }; + + c(); +} + +struct S; +impl Drop for S { + fn drop(&mut self) { + } +} + +struct T(S, S); +struct U(T, T); + +// Test that if the path is longer than just one element, precise analysis works correctly. +fn test_precise_analysis_long_path() { + let u = U(T(S, S), T(S, S)); + + let c = || { + let _x = u.0.0; + let _x = u.0.1; + let _x = u.1.0; + let _x = u.1.1; + }; + + c(); +} + +fn main() { + test_precise_analysis_simple_1(); + test_precise_analysis_simple_2(); + + test_precise_analysis_parent_captured_1(); + test_precise_analysis_parent_captured_2(); + + test_precise_analysis_long_path(); +} From 5b54640128766d967d5d7366f5d068cd4a774ead Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Thu, 4 Feb 2021 19:55:16 -0500 Subject: [PATCH 08/24] Mark migration code that relies on Deref unreachable --- compiler/rustc_typeck/src/check/upvar.rs | 47 ++++-------------------- 1 file changed, 8 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 4d21629cd69..1ffa8c37a80 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -698,8 +698,8 @@ fn compute_2229_migrations_precise_pass( /// freeing up memory). /// /// The way this function works is at a given call it looks at type `base_path_ty` of some base - /// path say P and then vector of projection slices which represent the different captures - /// starting off of P. + /// path say P and then list of projection slices which represent the different captures moved + /// into the closure starting off of P. /// /// This will make more sense with an example: /// @@ -842,23 +842,12 @@ fn has_significant_drop_outside_of_captures( // `captured_projs.first().unwrap()` safely. // - All entries in `captured_projs` have atleast one projection. // Therefore we can call `captured_projs.first().unwrap().first().unwrap()` safely. - ty::Adt(def, _) if def.is_box() => { - // We must deref to access paths on top of a Box. - assert!( - captured_projs - .iter() - .all(|projs| matches!(projs.first().unwrap().kind, ProjectionKind::Deref)) - ); - let next_ty = captured_projs.first().unwrap().first().unwrap().ty; - let captured_projs = captured_projs.iter().map(|projs| &projs[1..]).collect(); - self.has_significant_drop_outside_of_captures( - closure_def_id, - closure_span, - next_ty, - captured_projs, - ) - } + // We don't capture derefs in case of move captures, which would have be applied to + // access any further paths. + ty::Adt(def, _) if def.is_box() => unreachable!(), + ty::Ref(..) => unreachable!(), + ty::RawPtr(..) => unreachable!(), ty::Adt(def, substs) => { // Multi-varaint enums are captured in entirety, @@ -929,27 +918,7 @@ fn has_significant_drop_outside_of_captures( }) } - ty::Ref(_, deref_ty, _) => { - // Only Derefs can be applied to a Ref - assert!( - captured_projs - .iter() - .all(|projs| matches!(projs.first().unwrap().kind, ProjectionKind::Deref)) - ); - - let captured_projs = captured_projs.iter().map(|projs| &projs[1..]).collect(); - self.has_significant_drop_outside_of_captures( - closure_def_id, - closure_span, - deref_ty, - captured_projs, - ) - } - - // Unsafe Ptrs are captured in their entirety, which would've have been handled in - // the case of single empty slice in `captured_projs`. - ty::RawPtr(..) => unreachable!(), - + // Anything else would be completely captured and therefore handled already. _ => unreachable!(), } } From 09d5d0766eaaf0dbf1c1773af79d26f73aa65073 Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Tue, 9 Feb 2021 08:35:58 +0000 Subject: [PATCH 09/24] Fixing bad suggestion for `_` in `const` type when a function #81885 --- compiler/rustc_typeck/src/astconv/mod.rs | 1 + compiler/rustc_typeck/src/collect.rs | 22 +++- src/test/ui/did_you_mean/bad-assoc-ty.stderr | 20 --- src/test/ui/issues/issue-74086.stderr | 5 +- src/test/ui/issues/issue-81885.rs | 10 ++ src/test/ui/issues/issue-81885.stderr | 15 +++ src/test/ui/self/self-infer.stderr | 10 -- .../typeck_type_placeholder_item.stderr | 116 ++---------------- .../typeck_type_placeholder_item_help.stderr | 5 +- 9 files changed, 54 insertions(+), 150 deletions(-) create mode 100644 src/test/ui/issues/issue-81885.rs create mode 100644 src/test/ui/issues/issue-81885.stderr diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 5659345f0ff..877c7631c9b 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2327,6 +2327,7 @@ pub fn ty_of_fn( &generics.params[..], visitor.0, true, + true ); } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index b1d98d75196..3d0220bfd67 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -141,6 +141,7 @@ struct CollectItemTypesVisitor<'tcx> { generics: &[hir::GenericParam<'_>], placeholder_types: Vec, suggest: bool, + is_fn: bool, ) { if placeholder_types.is_empty() { return; @@ -171,7 +172,9 @@ struct CollectItemTypesVisitor<'tcx> { } let mut err = bad_placeholder_type(tcx, placeholder_types); - if suggest { + + // Suggest, but only if it is not a function + if suggest && !is_fn { err.multipart_suggestion( "use type parameters instead", sugg, @@ -198,7 +201,14 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_item(item); - placeholder_type_error(tcx, Some(generics.span), &generics.params[..], visitor.0, suggest); + placeholder_type_error( + tcx, + Some(generics.span), + &generics.params[..], + visitor.0, + suggest, + false + ); } impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { @@ -743,7 +753,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) { // Account for `const C: _;`. let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_trait_item(trait_item); - placeholder_type_error(tcx, None, &[], visitor.0, false); + placeholder_type_error(tcx, None, &[], visitor.0, false, false); } hir::TraitItemKind::Type(_, Some(_)) => { @@ -752,7 +762,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) { // Account for `type T = _;`. let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_trait_item(trait_item); - placeholder_type_error(tcx, None, &[], visitor.0, false); + placeholder_type_error(tcx, None, &[], visitor.0, false, false); } hir::TraitItemKind::Type(_, None) => { @@ -761,7 +771,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) { // even if there is no concrete type. let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_trait_item(trait_item); - placeholder_type_error(tcx, None, &[], visitor.0, false); + placeholder_type_error(tcx, None, &[], visitor.0, false, false); } }; @@ -782,7 +792,7 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::HirId) { // Account for `type T = _;` let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_impl_item(impl_item); - placeholder_type_error(tcx, None, &[], visitor.0, false); + placeholder_type_error(tcx, None, &[], visitor.0, false, false); } hir::ImplItemKind::Const(..) => {} } diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.stderr b/src/test/ui/did_you_mean/bad-assoc-ty.stderr index ebc0883370b..fe67e099527 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr @@ -129,33 +129,18 @@ LL | fn foo>(x: X) {} | ^ ^ not allowed in type signatures | | | not allowed in type signatures - | -help: use type parameters instead - | -LL | fn foo, T>(x: X) {} - | ^ ^ ^^^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/bad-assoc-ty.rs:52:34 | LL | fn bar(_: F) where F: Fn() -> _ {} | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn bar(_: F) where F: Fn() -> T {} - | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/bad-assoc-ty.rs:55:19 | LL | fn baz _>(_: F) {} | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn baz T, T>(_: F) {} - | ^^^^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/bad-assoc-ty.rs:58:33 @@ -217,11 +202,6 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn foo(_: F) where F: Fn() -> _ {} | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn foo(_: F) where F: Fn() -> T {} - | ^^^ ^ error: aborting due to 28 previous errors diff --git a/src/test/ui/issues/issue-74086.stderr b/src/test/ui/issues/issue-74086.stderr index 4127f48a093..e602425059e 100644 --- a/src/test/ui/issues/issue-74086.stderr +++ b/src/test/ui/issues/issue-74086.stderr @@ -2,10 +2,7 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa --> $DIR/issue-74086.rs:2:20 | LL | static BUG: fn(_) -> u8 = |_| 8; - | ^ - | | - | not allowed in type signatures - | help: use type parameters instead: `T` + | ^ not allowed in type signatures error: aborting due to previous error diff --git a/src/test/ui/issues/issue-81885.rs b/src/test/ui/issues/issue-81885.rs new file mode 100644 index 00000000000..86c39d4a48c --- /dev/null +++ b/src/test/ui/issues/issue-81885.rs @@ -0,0 +1,10 @@ +const TEST4: fn() -> _ = 42; + //~^ ERROR the type placeholder `_` is not allowed within types on item + //signatures + +fn main() { + const TEST5: fn() -> _ = 42; + //~^ ERROR the type placeholder `_` is not allowed within types on item + //signatures + +} diff --git a/src/test/ui/issues/issue-81885.stderr b/src/test/ui/issues/issue-81885.stderr new file mode 100644 index 00000000000..955b4283874 --- /dev/null +++ b/src/test/ui/issues/issue-81885.stderr @@ -0,0 +1,15 @@ +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/issue-81885.rs:1:22 + | +LL | const TEST4: fn() -> _ = 42; + | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/issue-81885.rs:6:26 + | +LL | const TEST5: fn() -> _ = 42; + | ^ not allowed in type signatures + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/self/self-infer.stderr b/src/test/ui/self/self-infer.stderr index 1475b212b56..f91cfe5eb62 100644 --- a/src/test/ui/self/self-infer.stderr +++ b/src/test/ui/self/self-infer.stderr @@ -3,22 +3,12 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn f(self: _) {} | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn f(self: T) {} - | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/self-infer.rs:5:17 | LL | fn g(self: &_) {} | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn g(self: &T) {} - | ^^^ ^ error: aborting due to 2 previous errors diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index 684f451b7c3..18e06bc2b35 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -92,64 +92,36 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn test6(_: _) { } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn test6(_: T) { } - | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:24:18 | LL | fn test6_b(_: _, _: T) { } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn test6_b(_: U, _: T) { } - | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:27:30 | LL | fn test6_c(_: _, _: (T, K, L, A, B)) { } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn test6_c(_: U, _: (T, K, L, A, B)) { } - | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:30:13 | LL | fn test7(x: _) { let _x: usize = x; } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn test7(x: T) { let _x: usize = x; } - | ^^^ ^ - -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:33:22 - | -LL | fn test8(_f: fn() -> _) { } - | ^ - | | - | not allowed in type signatures - | help: use type parameters instead: `T` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:33:22 | LL | fn test8(_f: fn() -> _) { } | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:33:22 | -help: use type parameters instead - | -LL | fn test8(_f: fn() -> T) { } - | ^^^ ^ +LL | fn test8(_f: fn() -> _) { } + | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:47:26 @@ -257,42 +229,24 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn fn_test6(_: _) { } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn fn_test6(_: T) { } - | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:97:20 | LL | fn fn_test7(x: _) { let _x: usize = x; } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn fn_test7(x: T) { let _x: usize = x; } - | ^^^ ^ - -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:100:29 - | -LL | fn fn_test8(_f: fn() -> _) { } - | ^ - | | - | not allowed in type signatures - | help: use type parameters instead: `T` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:100:29 | LL | fn fn_test8(_f: fn() -> _) { } | ^ not allowed in type signatures + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:100:29 | -help: use type parameters instead - | -LL | fn fn_test8(_f: fn() -> T) { } - | ^^^ ^ +LL | fn fn_test8(_f: fn() -> _) { } + | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:123:12 @@ -415,11 +369,6 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn method_test1(&self, x: _); | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn method_test1(&self, x: T); - | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:142:31 @@ -428,33 +377,18 @@ LL | fn method_test2(&self, x: _) -> _; | ^ ^ not allowed in type signatures | | | not allowed in type signatures - | -help: use type parameters instead - | -LL | fn method_test2(&self, x: T) -> T; - | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:144:31 | LL | fn method_test3(&self) -> _; | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn method_test3(&self) -> T; - | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:146:26 | LL | fn assoc_fn_test1(x: _); | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn assoc_fn_test1(x: T); - | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:148:26 @@ -463,22 +397,12 @@ LL | fn assoc_fn_test2(x: _) -> _; | ^ ^ not allowed in type signatures | | | not allowed in type signatures - | -help: use type parameters instead - | -LL | fn assoc_fn_test2(x: T) -> T; - | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:150:28 | LL | fn assoc_fn_test3() -> _; | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn assoc_fn_test3() -> T; - | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:190:14 @@ -521,11 +445,6 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn test10(&self, _x : _) { } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn test10(&self, _x : T) { } - | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:58:24 @@ -541,11 +460,6 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn clone_from(&mut self, other: _) { *self = Test9; } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn clone_from(&mut self, other: T) { *self = Test9; } - | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:107:31 @@ -561,11 +475,6 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn fn_test10(&self, _x : _) { } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn fn_test10(&self, _x : T) { } - | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:115:28 @@ -581,11 +490,6 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn clone_from(&mut self, other: _) { *self = FnTest9; } | ^ not allowed in type signatures - | -help: use type parameters instead - | -LL | fn clone_from(&mut self, other: T) { *self = FnTest9; } - | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:201:14 diff --git a/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr b/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr index 0121e186316..f868c8d4834 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr @@ -29,10 +29,7 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa --> $DIR/typeck_type_placeholder_item_help.rs:13:22 | LL | const TEST4: fn() -> _ = 42; - | ^ - | | - | not allowed in type signatures - | help: use type parameters instead: `T` + | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item_help.rs:17:18 From 95be69dabb9ddd5fe32a33942b1cfe4914c79c38 Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Tue, 9 Feb 2021 08:42:08 +0000 Subject: [PATCH 10/24] Fixing codestyle --- compiler/rustc_typeck/src/collect.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 3d0220bfd67..d26f3242048 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -172,7 +172,7 @@ struct CollectItemTypesVisitor<'tcx> { } let mut err = bad_placeholder_type(tcx, placeholder_types); - + // Suggest, but only if it is not a function if suggest && !is_fn { err.multipart_suggestion( @@ -202,11 +202,11 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir visitor.visit_item(item); placeholder_type_error( - tcx, - Some(generics.span), - &generics.params[..], - visitor.0, - suggest, + tcx, + Some(generics.span), + &generics.params[..], + visitor.0, + suggest, false ); } From 49fc41f047dbb961427e1f2421e36a1cacc799dd Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Tue, 9 Feb 2021 10:28:49 +0000 Subject: [PATCH 11/24] Running ./x.py fmt --- compiler/rustc_typeck/src/astconv/mod.rs | 2 +- compiler/rustc_typeck/src/collect.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 877c7631c9b..66bded85f3f 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2327,7 +2327,7 @@ pub fn ty_of_fn( &generics.params[..], visitor.0, true, - true + true, ); } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index d26f3242048..58e083f2c24 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -207,7 +207,7 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir &generics.params[..], visitor.0, suggest, - false + false, ); } From f7edf5ce051e64c2d392e19819542e177867e714 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Mon, 25 Jan 2021 10:04:09 +0100 Subject: [PATCH 12/24] BTreeMap: fix internal comments --- library/alloc/src/collections/btree/navigate.rs | 7 ++++--- library/alloc/src/collections/btree/node.rs | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/collections/btree/navigate.rs b/library/alloc/src/collections/btree/navigate.rs index 1ef2a572ddd..259b22e5c66 100644 --- a/library/alloc/src/collections/btree/navigate.rs +++ b/library/alloc/src/collections/btree/navigate.rs @@ -103,7 +103,8 @@ fn range_search( } } -/// Equivalent to `range_search(k, v, ..)` but without the `Ord` bound. +/// Equivalent to `range_search(root1, root2, ..)` but without the `Ord` bound. +/// Equivalent to `(root1.first_leaf_edge(), root2.last_leaf_edge())` but more efficient. fn full_range( root1: NodeRef, root2: NodeRef, @@ -130,7 +131,7 @@ fn full_range( } impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> { - /// Creates a pair of leaf edges delimiting a specified range in or underneath a node. + /// Finds the pair of leaf edges delimiting a specific range in a tree. /// /// The result is meaningful only if the tree is ordered by key, like the tree /// in a `BTreeMap` is. @@ -149,7 +150,7 @@ pub fn range_search( range_search(self, self, range) } - /// Returns (self.first_leaf_edge(), self.last_leaf_edge()), but more efficiently. + /// Finds the pair of leaf edges delimiting an entire tree. pub fn full_range( self, ) -> ( diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs index 1d632512c78..6f67aadc161 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -169,7 +169,7 @@ pub fn borrow_valmut(&mut self) -> NodeRef, K, V, Type> { NodeRef { height: self.height, node: self.node, _marker: PhantomData } } - /// Irreversibly transistions to a reference that offers traversal, + /// Irreversibly transitions to a reference that permits traversal and offers /// destructive methods and little else. pub fn into_dying(self) -> NodeRef { NodeRef { height: self.height, node: self.node, _marker: PhantomData } From b29d7166f2dd2e975e5d2eff5674b7bd10bac5c3 Mon Sep 17 00:00:00 2001 From: Bram van den Heuvel Date: Tue, 9 Feb 2021 14:42:04 +0100 Subject: [PATCH 13/24] Add a regression test for #32498 --- src/test/ui/generics/issue-32498.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/test/ui/generics/issue-32498.rs diff --git a/src/test/ui/generics/issue-32498.rs b/src/test/ui/generics/issue-32498.rs new file mode 100644 index 00000000000..1b54401097e --- /dev/null +++ b/src/test/ui/generics/issue-32498.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] + +// Making sure that no overflow occurs. + +struct L { + n: Option, +} +type L8 = L>>>>>>>; +type L64 = L8>>>; + +fn main() { + use std::mem::size_of; + assert_eq!(size_of::>>(), 1); + assert_eq!(size_of::>>>(), 1); +} From 396022b90b315ab35be3317836528d83bdd0c042 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Fri, 8 Jan 2021 10:00:39 +0100 Subject: [PATCH 14/24] Visit more targets when checking attrs --- compiler/rustc_hir/src/target.rs | 2 ++ compiler/rustc_passes/src/check_attr.rs | 28 +++++++++++-------- .../ui/proc-macro/ambiguous-builtin-attrs.rs | 2 +- .../proc-macro/ambiguous-builtin-attrs.stderr | 10 +++---- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index 6dbcfb963ee..473477bf22d 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -54,6 +54,7 @@ pub enum Target { ForeignTy, GenericParam(GenericParamKind), MacroDef, + Param, } impl Display for Target { @@ -96,6 +97,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { GenericParamKind::Const => "const parameter", }, Target::MacroDef => "macro def", + Target::Param => "function param", } ) } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 0e3a722e082..2c79eeeb0e6 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1101,17 +1101,6 @@ fn visit_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) { intravisit::walk_arm(self, arm); } - fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef<'tcx>) { - self.check_attributes( - macro_def.hir_id, - ¯o_def.attrs, - ¯o_def.span, - Target::MacroDef, - None, - ); - intravisit::walk_macro_def(self, macro_def); - } - fn visit_foreign_item(&mut self, f_item: &'tcx ForeignItem<'tcx>) { let target = Target::from_foreign_item(f_item); self.check_attributes( @@ -1157,6 +1146,23 @@ fn visit_variant( self.check_attributes(variant.id, variant.attrs, &variant.span, Target::Variant, None); intravisit::walk_variant(self, variant, generics, item_id) } + + fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef<'tcx>) { + self.check_attributes( + macro_def.hir_id, + macro_def.attrs, + ¯o_def.span, + Target::MacroDef, + None, + ); + intravisit::walk_macro_def(self, macro_def); + } + + fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) { + self.check_attributes(param.hir_id, param.attrs, ¶m.span, Target::Param, None); + + intravisit::walk_param(self, param); + } } fn is_c_like_enum(item: &Item<'_>) -> bool { diff --git a/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs b/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs index a6e9ed14ff1..65d8bcd9972 100644 --- a/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs +++ b/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs @@ -3,8 +3,8 @@ #![feature(decl_macro)] //~ ERROR `feature` is ambiguous extern crate builtin_attrs; -use builtin_attrs::{test, bench}; use builtin_attrs::*; +use builtin_attrs::{bench, test}; #[repr(C)] //~ ERROR `repr` is ambiguous struct S; diff --git a/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr b/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr index 31959248a68..1ad991db3be 100644 --- a/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr +++ b/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr @@ -12,7 +12,7 @@ LL | #[repr(C)] | = note: `repr` could refer to a built-in attribute note: `repr` could also refer to the attribute macro imported here - --> $DIR/ambiguous-builtin-attrs.rs:7:5 + --> $DIR/ambiguous-builtin-attrs.rs:6:5 | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | #[cfg_attr(all(), repr(C))] | = note: `repr` could refer to a built-in attribute note: `repr` could also refer to the attribute macro imported here - --> $DIR/ambiguous-builtin-attrs.rs:7:5 + --> $DIR/ambiguous-builtin-attrs.rs:6:5 | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | fn non_macro_expanded_location<#[repr(C)] T>() { | = note: `repr` could refer to a built-in attribute note: `repr` could also refer to the attribute macro imported here - --> $DIR/ambiguous-builtin-attrs.rs:7:5 + --> $DIR/ambiguous-builtin-attrs.rs:6:5 | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ @@ -54,7 +54,7 @@ LL | #[repr(C)] | = note: `repr` could refer to a built-in attribute note: `repr` could also refer to the attribute macro imported here - --> $DIR/ambiguous-builtin-attrs.rs:7:5 + --> $DIR/ambiguous-builtin-attrs.rs:6:5 | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ @@ -82,7 +82,7 @@ LL | #![feature(decl_macro)] | = note: `feature` could refer to a built-in attribute note: `feature` could also refer to the attribute macro imported here - --> $DIR/ambiguous-builtin-attrs.rs:7:5 + --> $DIR/ambiguous-builtin-attrs.rs:6:5 | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ From 9f0e1d4921bbb40fea71594d7c599c09ab513232 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Tue, 9 Feb 2021 22:17:10 +0100 Subject: [PATCH 15/24] Add attr-on-params test --- src/test/ui/attributes/attrs-on-params.rs | 8 ++++++++ src/test/ui/attributes/attrs-on-params.stderr | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 src/test/ui/attributes/attrs-on-params.rs create mode 100644 src/test/ui/attributes/attrs-on-params.stderr diff --git a/src/test/ui/attributes/attrs-on-params.rs b/src/test/ui/attributes/attrs-on-params.rs new file mode 100644 index 00000000000..0e606eac1e8 --- /dev/null +++ b/src/test/ui/attributes/attrs-on-params.rs @@ -0,0 +1,8 @@ +// This checks that incorrect params on function parameters are caught + +fn function(#[inline] param: u32) { + //~^ ERROR attribute should be applied to function or closure + //~| ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes +} + +fn main() {} diff --git a/src/test/ui/attributes/attrs-on-params.stderr b/src/test/ui/attributes/attrs-on-params.stderr new file mode 100644 index 00000000000..003f43d371a --- /dev/null +++ b/src/test/ui/attributes/attrs-on-params.stderr @@ -0,0 +1,17 @@ +error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters + --> $DIR/attrs-on-params.rs:3:13 + | +LL | fn function(#[inline] param: u32) { + | ^^^^^^^^^ + +error[E0518]: attribute should be applied to function or closure + --> $DIR/attrs-on-params.rs:3:13 + | +LL | fn function(#[inline] param: u32) { + | ^^^^^^^^^----------- + | | + | not a function or closure + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0518`. From 96c12f90cf62442bc5cba1d8c1c8049ee4652237 Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Fri, 12 Feb 2021 04:07:41 -0500 Subject: [PATCH 16/24] fixup! Implement the precise analysis pass for lint `disjoint_capture_drop_reorder` --- compiler/rustc_typeck/src/check/upvar.rs | 92 +++++++++--------------- 1 file changed, 34 insertions(+), 58 deletions(-) diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 1ffa8c37a80..0d045c1b9c4 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -540,7 +540,7 @@ fn perform_2229_migration_anaysis( span: Span, body: &'tcx hir::Body<'tcx>, ) { - let need_migrations_first_pass = self.compute_2229_migrations_first_pass( + let need_migrations = self.compute_2229_migrations( closure_def_id, span, capture_clause, @@ -548,13 +548,6 @@ fn perform_2229_migration_anaysis( self.typeck_results.borrow().closure_min_captures.get(&closure_def_id), ); - let need_migrations = self.compute_2229_migrations_precise_pass( - closure_def_id, - span, - self.typeck_results.borrow().closure_min_captures.get(&closure_def_id), - &need_migrations_first_pass, - ); - if !need_migrations.is_empty() { let migrations_text = migration_suggestion_for_2229(self.tcx, &need_migrations); @@ -583,15 +576,15 @@ fn perform_2229_migration_anaysis( /// - It would have been moved into the closure when `capture_disjoint_fields` wasn't /// enabled, **and** /// - It wasn't completely captured by the closure, **and** - /// - The type of the root variable needs Drop. - fn compute_2229_migrations_first_pass( + /// - One of the paths starting at this root variable, that is not captured needs Drop. + fn compute_2229_migrations( &self, closure_def_id: DefId, closure_span: Span, closure_clause: hir::CaptureBy, body: &'tcx hir::Body<'tcx>, min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>, - ) -> Vec<(hir::HirId, Ty<'tcx>)> { + ) -> Vec { fn resolve_ty>( fcx: &FnCtxt<'_, 'tcx>, span: Span, @@ -627,7 +620,7 @@ fn resolve_ty>( match closure_clause { // Only migrate if closure is a move closure - hir::CaptureBy::Value => need_migrations.push((var_hir_id, ty)), + hir::CaptureBy::Value => need_migrations.push(var_hir_id), hir::CaptureBy::Ref => {} } @@ -635,36 +628,8 @@ fn resolve_ty>( continue; }; - let is_moved = root_var_min_capture_list + let projections_list = root_var_min_capture_list .iter() - .any(|capture| matches!(capture.info.capture_kind, ty::UpvarCapture::ByValue(_))); - - let is_not_completely_captured = - root_var_min_capture_list.iter().any(|capture| capture.place.projections.len() > 0); - - if is_moved && is_not_completely_captured { - need_migrations.push((var_hir_id, ty)); - } - } - - need_migrations - } - - fn compute_2229_migrations_precise_pass( - &self, - closure_def_id: DefId, - closure_span: Span, - min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>, - need_migrations: &[(hir::HirId, Ty<'tcx>)], - ) -> Vec { - // Need migrations -- second pass - let mut need_migrations_2 = Vec::new(); - - for (hir_id, ty) in need_migrations { - let projections_list = min_captures - .and_then(|m| m.get(hir_id)) - .into_iter() - .flatten() .filter_map(|captured_place| match captured_place.info.capture_kind { // Only care about captures that are moved into the closure ty::UpvarCapture::ByValue(..) => { @@ -672,19 +637,27 @@ fn compute_2229_migrations_precise_pass( } ty::UpvarCapture::ByRef(..) => None, }) - .collect(); + .collect::>(); - if self.has_significant_drop_outside_of_captures( - closure_def_id, - closure_span, - ty, - projections_list, - ) { - need_migrations_2.push(*hir_id); + let is_moved = !projections_list.is_empty(); + + let is_not_completely_captured = + root_var_min_capture_list.iter().any(|capture| capture.place.projections.len() > 0); + + if is_moved + && is_not_completely_captured + && self.has_significant_drop_outside_of_captures( + closure_def_id, + closure_span, + ty, + projections_list, + ) + { + need_migrations.push(var_hir_id); } } - need_migrations_2 + need_migrations } /// This is a helper function to `compute_2229_migrations_precise_pass`. Provided the type @@ -822,21 +795,24 @@ fn has_significant_drop_outside_of_captures( assert!(!is_completely_captured || (captured_projs.len() == 1)); - if is_drop_defined_for_ty { - // If drop is implemented for this type then we need it to be fully captured, or - // it will require migration. - return !is_completely_captured; - } - if is_completely_captured { // The place is captured entirely, so doesn't matter if needs dtor, it will be drop // when the closure is dropped. return false; } - match base_path_ty.kind() { - _ if captured_projs.is_empty() => needs_drop(base_path_ty), + if is_drop_defined_for_ty { + // If drop is implemented for this type then we need it to be fully captured, + // which we know it is not because of the previous check. Therefore we need to + // do migrate. + return true; + } + if captured_projs.is_empty() { + return needs_drop(base_path_ty); + } + + match base_path_ty.kind() { // Observations: // - `captured_projs` is not empty. Therefore we can call // `captured_projs.first().unwrap()` safely. From fba2f883f39332f43d9cd8f69ebc720076e64e0d Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Wed, 10 Feb 2021 15:49:23 +0000 Subject: [PATCH 17/24] Implementing more sophisticated filter for fn in const or static --- compiler/rustc_typeck/src/astconv/mod.rs | 6 ++- compiler/rustc_typeck/src/check/mod.rs | 1 + compiler/rustc_typeck/src/collect.rs | 69 ++++++++++++++++++------ 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 66bded85f3f..120a59aa9d2 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2145,12 +2145,14 @@ fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool) -> Ty<'tcx> { } hir::TyKind::BareFn(ref bf) => { require_c_abi_if_c_variadic(tcx, &bf.decl, bf.abi, ast_ty.span); + tcx.mk_fn_ptr(self.ty_of_fn( bf.unsafety, bf.abi, &bf.decl, &hir::Generics::empty(), None, + Some(ast_ty), )) } hir::TyKind::TraitObject(ref bounds, ref lifetime) => { @@ -2290,6 +2292,7 @@ pub fn ty_of_fn( decl: &hir::FnDecl<'_>, generics: &hir::Generics<'_>, ident_span: Option, + hir_ty: Option<&hir::Ty<'_>>, ) -> ty::PolyFnSig<'tcx> { debug!("ty_of_fn"); @@ -2321,13 +2324,14 @@ pub fn ty_of_fn( // only want to emit an error complaining about them if infer types (`_`) are not // allowed. `allow_ty_infer` gates this behavior. We check for the presence of // `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`. + crate::collect::placeholder_type_error( tcx, ident_span.map(|sp| sp.shrink_to_hi()), &generics.params[..], visitor.0, true, - true, + hir_ty, ); } diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index 229127e95d9..fce7ae8119e 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -502,6 +502,7 @@ fn typeck_with_fallback<'tcx>( decl, &hir::Generics::empty(), None, + None, ) } else { tcx.fn_sig(def_id) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 58e083f2c24..754fc6a9c7b 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -141,7 +141,7 @@ struct CollectItemTypesVisitor<'tcx> { generics: &[hir::GenericParam<'_>], placeholder_types: Vec, suggest: bool, - is_fn: bool, + hir_ty: Option<&hir::Ty<'_>>, ) { if placeholder_types.is_empty() { return; @@ -173,13 +173,39 @@ struct CollectItemTypesVisitor<'tcx> { let mut err = bad_placeholder_type(tcx, placeholder_types); - // Suggest, but only if it is not a function - if suggest && !is_fn { - err.multipart_suggestion( - "use type parameters instead", - sugg, - Applicability::HasPlaceholders, - ); + // Suggest, but only if it is not a function in const or static + if suggest { + let mut is_fn = false; + let mut is_const = false; + let mut is_static = false; + + if let Some(hir_ty) = hir_ty { + if let hir::TyKind::BareFn(_) = hir_ty.kind { + is_fn = true; + + // Check if parent is const or static + let parent_id = tcx.hir().get_parent_node(hir_ty.hir_id); + let parent_node = tcx.hir().get(parent_id); + + if let hir::Node::Item(item) = parent_node { + if let hir::ItemKind::Const(_, _) = item.kind { + is_const = true; + } else if let hir::ItemKind::Static(_, _, _) = item.kind { + is_static = true; + } + } + } + } + + // if function is wrapped around a const or static, + // then don't show the suggestion + if !(is_fn && (is_const || is_static)) { + err.multipart_suggestion( + "use type parameters instead", + sugg, + Applicability::HasPlaceholders, + ); + } } err.emit(); } @@ -207,7 +233,7 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir &generics.params[..], visitor.0, suggest, - false, + None, ); } @@ -648,6 +674,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::HirId) { let it = tcx.hir().expect_item(item_id); debug!("convert: item {} with id {}", it.ident, it.hir_id); let def_id = tcx.hir().local_def_id(item_id); + match it.kind { // These don't define types. hir::ItemKind::ExternCrate(_) @@ -753,7 +780,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) { // Account for `const C: _;`. let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_trait_item(trait_item); - placeholder_type_error(tcx, None, &[], visitor.0, false, false); + placeholder_type_error(tcx, None, &[], visitor.0, false, None); } hir::TraitItemKind::Type(_, Some(_)) => { @@ -762,7 +789,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) { // Account for `type T = _;`. let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_trait_item(trait_item); - placeholder_type_error(tcx, None, &[], visitor.0, false, false); + placeholder_type_error(tcx, None, &[], visitor.0, false, None); } hir::TraitItemKind::Type(_, None) => { @@ -771,7 +798,8 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) { // even if there is no concrete type. let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_trait_item(trait_item); - placeholder_type_error(tcx, None, &[], visitor.0, false, false); + + placeholder_type_error(tcx, None, &[], visitor.0, false, None); } }; @@ -792,7 +820,8 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::HirId) { // Account for `type T = _;` let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_impl_item(impl_item); - placeholder_type_error(tcx, None, &[], visitor.0, false, false); + + placeholder_type_error(tcx, None, &[], visitor.0, false, None); } hir::ImplItemKind::Const(..) => {} } @@ -1583,6 +1612,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { &sig.decl, &generics, Some(ident.span), + None, ), } } @@ -1592,9 +1622,15 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { ident, generics, .. - }) => { - AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl, &generics, Some(ident.span)) - } + }) => AstConv::ty_of_fn( + &icx, + header.unsafety, + header.abi, + decl, + &generics, + Some(ident.span), + None, + ), ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(ref fn_decl, _, _), @@ -2264,6 +2300,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>( decl, &hir::Generics::empty(), Some(ident.span), + None, ); // Feature gate SIMD types in FFI, since I am not sure that the From 1adc6be23f93c2a348cbf568fb89dc546319e199 Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Fri, 12 Feb 2021 09:19:54 +0000 Subject: [PATCH 18/24] Update .stderr --- src/test/ui/did_you_mean/bad-assoc-ty.stderr | 20 +++ src/test/ui/self/self-infer.stderr | 10 ++ .../typeck_type_placeholder_item.stderr | 116 ++++++++++++++++-- 3 files changed, 136 insertions(+), 10 deletions(-) diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.stderr b/src/test/ui/did_you_mean/bad-assoc-ty.stderr index fe67e099527..ebc0883370b 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr @@ -129,18 +129,33 @@ LL | fn foo>(x: X) {} | ^ ^ not allowed in type signatures | | | not allowed in type signatures + | +help: use type parameters instead + | +LL | fn foo, T>(x: X) {} + | ^ ^ ^^^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/bad-assoc-ty.rs:52:34 | LL | fn bar(_: F) where F: Fn() -> _ {} | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn bar(_: F) where F: Fn() -> T {} + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/bad-assoc-ty.rs:55:19 | LL | fn baz _>(_: F) {} | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn baz T, T>(_: F) {} + | ^^^^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/bad-assoc-ty.rs:58:33 @@ -202,6 +217,11 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn foo(_: F) where F: Fn() -> _ {} | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn foo(_: F) where F: Fn() -> T {} + | ^^^ ^ error: aborting due to 28 previous errors diff --git a/src/test/ui/self/self-infer.stderr b/src/test/ui/self/self-infer.stderr index f91cfe5eb62..1475b212b56 100644 --- a/src/test/ui/self/self-infer.stderr +++ b/src/test/ui/self/self-infer.stderr @@ -3,12 +3,22 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn f(self: _) {} | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn f(self: T) {} + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/self-infer.rs:5:17 | LL | fn g(self: &_) {} | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn g(self: &T) {} + | ^^^ ^ error: aborting due to 2 previous errors diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index 18e06bc2b35..684f451b7c3 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -92,36 +92,64 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn test6(_: _) { } | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn test6(_: T) { } + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:24:18 | LL | fn test6_b(_: _, _: T) { } | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn test6_b(_: U, _: T) { } + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:27:30 | LL | fn test6_c(_: _, _: (T, K, L, A, B)) { } | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn test6_c(_: U, _: (T, K, L, A, B)) { } + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:30:13 | LL | fn test7(x: _) { let _x: usize = x; } | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn test7(x: T) { let _x: usize = x; } + | ^^^ ^ + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:33:22 + | +LL | fn test8(_f: fn() -> _) { } + | ^ + | | + | not allowed in type signatures + | help: use type parameters instead: `T` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:33:22 | LL | fn test8(_f: fn() -> _) { } | ^ not allowed in type signatures - -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:33:22 | -LL | fn test8(_f: fn() -> _) { } - | ^ not allowed in type signatures +help: use type parameters instead + | +LL | fn test8(_f: fn() -> T) { } + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:47:26 @@ -229,24 +257,42 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn fn_test6(_: _) { } | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn fn_test6(_: T) { } + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:97:20 | LL | fn fn_test7(x: _) { let _x: usize = x; } | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn fn_test7(x: T) { let _x: usize = x; } + | ^^^ ^ + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:100:29 + | +LL | fn fn_test8(_f: fn() -> _) { } + | ^ + | | + | not allowed in type signatures + | help: use type parameters instead: `T` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:100:29 | LL | fn fn_test8(_f: fn() -> _) { } | ^ not allowed in type signatures - -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:100:29 | -LL | fn fn_test8(_f: fn() -> _) { } - | ^ not allowed in type signatures +help: use type parameters instead + | +LL | fn fn_test8(_f: fn() -> T) { } + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:123:12 @@ -369,6 +415,11 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn method_test1(&self, x: _); | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn method_test1(&self, x: T); + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:142:31 @@ -377,18 +428,33 @@ LL | fn method_test2(&self, x: _) -> _; | ^ ^ not allowed in type signatures | | | not allowed in type signatures + | +help: use type parameters instead + | +LL | fn method_test2(&self, x: T) -> T; + | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:144:31 | LL | fn method_test3(&self) -> _; | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn method_test3(&self) -> T; + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:146:26 | LL | fn assoc_fn_test1(x: _); | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn assoc_fn_test1(x: T); + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:148:26 @@ -397,12 +463,22 @@ LL | fn assoc_fn_test2(x: _) -> _; | ^ ^ not allowed in type signatures | | | not allowed in type signatures + | +help: use type parameters instead + | +LL | fn assoc_fn_test2(x: T) -> T; + | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:150:28 | LL | fn assoc_fn_test3() -> _; | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn assoc_fn_test3() -> T; + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:190:14 @@ -445,6 +521,11 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn test10(&self, _x : _) { } | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn test10(&self, _x : T) { } + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:58:24 @@ -460,6 +541,11 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn clone_from(&mut self, other: _) { *self = Test9; } | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn clone_from(&mut self, other: T) { *self = Test9; } + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:107:31 @@ -475,6 +561,11 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn fn_test10(&self, _x : _) { } | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn fn_test10(&self, _x : T) { } + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:115:28 @@ -490,6 +581,11 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa | LL | fn clone_from(&mut self, other: _) { *self = FnTest9; } | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn clone_from(&mut self, other: T) { *self = FnTest9; } + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:201:14 From 361dcd5ca7ecc84209c10d7102051471e82f8160 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sat, 13 Feb 2021 00:00:00 +0000 Subject: [PATCH 19/24] Use debug log level for developer oriented logs The information logged here is of limited general interest, while at the same times makes it impractical to simply enable logging and share the resulting logs due to the amount of the output produced. Reduce log level from info to debug for developer oriented information. For example, when building cargo, this reduces the amount of logs generated by `RUSTC_LOG=info cargo build` from 265 MB to 79 MB. Continuation of changes from 81350. --- compiler/rustc_mir/src/transform/inline.rs | 4 ++-- compiler/rustc_mir/src/transform/inline/cycle.rs | 7 +++++-- compiler/rustc_mir_build/src/thir/pattern/usefulness.rs | 5 ++++- compiler/rustc_span/src/hygiene.rs | 4 ++-- compiler/rustc_trait_selection/src/traits/codegen.rs | 2 +- compiler/rustc_trait_selection/src/traits/fulfill.rs | 2 +- compiler/rustc_traits/src/dropck_outlives.rs | 2 +- 7 files changed, 16 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index 1635a95f46e..f4f69fc8ac6 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -159,7 +159,7 @@ fn process_blocks(&mut self, caller_body: &mut Body<'tcx>, blocks: Range, caller_body: &Body<'tcx>) -> bool { match callee.def { InstanceDef::Item(_) => { @@ -258,7 +258,7 @@ fn get_valid_function_call( None } - #[instrument(skip(self, callee_body))] + #[instrument(level = "debug", skip(self, callee_body))] fn should_inline(&self, callsite: CallSite<'tcx>, callee_body: &Body<'tcx>) -> bool { let tcx = self.tcx; diff --git a/compiler/rustc_mir/src/transform/inline/cycle.rs b/compiler/rustc_mir/src/transform/inline/cycle.rs index e4d403fbf60..4c24bec0ce3 100644 --- a/compiler/rustc_mir/src/transform/inline/cycle.rs +++ b/compiler/rustc_mir/src/transform/inline/cycle.rs @@ -7,7 +7,7 @@ // FIXME: check whether it is cheaper to precompute the entire call graph instead of invoking // this query riddiculously often. -#[instrument(skip(tcx, root, target))] +#[instrument(level = "debug", skip(tcx, root, target))] crate fn mir_callgraph_reachable( tcx: TyCtxt<'tcx>, (root, target): (ty::Instance<'tcx>, LocalDefId), @@ -27,7 +27,10 @@ !tcx.is_constructor(root.def_id()), "you should not call `mir_callgraph_reachable` on enum/struct constructor functions" ); - #[instrument(skip(tcx, param_env, target, stack, seen, recursion_limiter, caller))] + #[instrument( + level = "debug", + skip(tcx, param_env, target, stack, seen, recursion_limiter, caller) + )] fn process( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index f3f21b903ea..010fe4fd524 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -1079,7 +1079,10 @@ fn apply_constructor<'p>( /// `is_under_guard` is used to inform if the pattern has a guard. If it /// has one it must not be inserted into the matrix. This shouldn't be /// relied on for soundness. -#[instrument(skip(cx, matrix, witness_preference, hir_id, is_under_guard, is_top_level))] +#[instrument( + level = "debug", + skip(cx, matrix, witness_preference, hir_id, is_under_guard, is_top_level) +)] fn is_useful<'p, 'tcx>( cx: &MatchCheckCtxt<'p, 'tcx>, matrix: &Matrix<'p, 'tcx>, diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 9f265f37f35..4ccf657335f 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -1405,8 +1405,8 @@ fn span_data_to_lines_and_cols( }); if modified { - info!("Set disambiguator for {:?} (hash {:?})", expn_id, first_hash); - info!("expn_data = {:?}", expn_id.expn_data()); + debug!("Set disambiguator for {:?} (hash {:?})", expn_id, first_hash); + debug!("expn_data = {:?}", expn_id.expn_data()); // Verify that the new disambiguator makes the hash unique #[cfg(debug_assertions)] diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_trait_selection/src/traits/codegen.rs index 657d5c123e8..45853a66efc 100644 --- a/compiler/rustc_trait_selection/src/traits/codegen.rs +++ b/compiler/rustc_trait_selection/src/traits/codegen.rs @@ -91,7 +91,7 @@ pub fn codegen_fulfill_obligation<'tcx>( }); let impl_source = drain_fulfillment_cx_or_panic(&infcx, &mut fulfill_cx, impl_source); - info!("Cache miss: {:?} => {:?}", trait_ref, impl_source); + debug!("Cache miss: {:?} => {:?}", trait_ref, impl_source); Ok(impl_source) }) } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index d4ced20f863..95f79147efd 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -647,7 +647,7 @@ fn process_trait_obligation( ProcessResult::Unchanged } Err(selection_err) => { - info!("selecting trait at depth {} yielded Err", obligation.recursion_depth); + debug!("selecting trait at depth {} yielded Err", obligation.recursion_depth); ProcessResult::Error(CodeSelectionError(selection_err)) } diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index 2827163d854..cfcbc77c172 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -80,7 +80,7 @@ fn dropck_outlives<'tcx>( let cause = ObligationCause::dummy(); let mut constraints = DtorckConstraint::empty(); while let Some((ty, depth)) = ty_stack.pop() { - info!( + debug!( "{} kinds, {} overflows, {} ty_stack", result.kinds.len(), result.overflows.len(), From be4ea06643a5bd4ff3cb91efdaafd7acb070cb30 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Fri, 12 Feb 2021 23:24:09 -0500 Subject: [PATCH 20/24] Modifiers -> Qualifiers --- src/librustdoc/json/conversions.rs | 10 +++++----- src/rustdoc-json-types/lib.rs | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 60197a0dc1c..691a7fb2a4e 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -228,19 +228,19 @@ fn from(struct_: clean::Union) -> Self { } } -crate fn from_fn_header(header: &rustc_hir::FnHeader) -> HashSet { +crate fn from_fn_header(header: &rustc_hir::FnHeader) -> HashSet { let mut v = HashSet::new(); if let rustc_hir::Unsafety::Unsafe = header.unsafety { - v.insert(Modifiers::Unsafe); + v.insert(Qualifiers::Unsafe); } if let rustc_hir::IsAsync::Async = header.asyncness { - v.insert(Modifiers::Async); + v.insert(Qualifiers::Async); } if let rustc_hir::Constness::Const = header.constness { - v.insert(Modifiers::Const); + v.insert(Qualifiers::Const); } v @@ -376,7 +376,7 @@ fn from(bare_decl: clean::BareFunctionDecl) -> Self { FunctionPointer { header: if let rustc_hir::Unsafety::Unsafe = unsafety { let mut hs = HashSet::new(); - hs.insert(Modifiers::Unsafe); + hs.insert(Qualifiers::Unsafe); hs } else { HashSet::new() diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index a2f323699c1..eae27a4a823 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -284,7 +284,7 @@ pub enum StructType { #[non_exhaustive] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] #[serde(rename_all = "snake_case")] -pub enum Modifiers { +pub enum Qualifiers { Const, Unsafe, Async, @@ -294,7 +294,7 @@ pub enum Modifiers { pub struct Function { pub decl: FnDecl, pub generics: Generics, - pub header: HashSet, + pub header: HashSet, pub abi: String, } @@ -302,7 +302,7 @@ pub struct Function { pub struct Method { pub decl: FnDecl, pub generics: Generics, - pub header: HashSet, + pub header: HashSet, pub abi: String, pub has_body: bool, } @@ -415,7 +415,7 @@ pub enum Type { pub struct FunctionPointer { pub decl: FnDecl, pub generic_params: Vec, - pub header: HashSet, + pub header: HashSet, pub abi: String, } From 77dfd71b951f3c3f1f385fa819d388aae721be68 Mon Sep 17 00:00:00 2001 From: b-naber Date: Sat, 13 Feb 2021 11:47:44 +0100 Subject: [PATCH 21/24] fix 82032 --- .../diagnostics/mutability_errors.rs | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs index 98450f5a547..0400431a542 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs @@ -1,6 +1,7 @@ use rustc_hir as hir; use rustc_hir::Node; use rustc_index::vec::Idx; +use rustc_middle::hir::map::Map; use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{ @@ -543,13 +544,24 @@ fn show_mutating_upvar( // Attempt to search similar mutable associated items for suggestion. // In the future, attempt in all path but initially for RHS of for_loop fn suggest_similar_mut_method_for_for_loop(&self, err: &mut DiagnosticBuilder<'_>) { - let hir = self.infcx.tcx.hir(); - let node = hir.item(self.mir_hir_id()); use hir::{ - Expr, + BodyId, Expr, ExprKind::{Block, Call, DropTemps, Match, MethodCall}, + HirId, ImplItem, ImplItemKind, Item, ItemKind, }; - if let hir::ItemKind::Fn(_, _, body_id) = node.kind { + + fn maybe_body_id_of_fn(hir_map: &Map<'tcx>, id: HirId) -> Option { + match hir_map.find(id) { + Some(Node::Item(Item { kind: ItemKind::Fn(_, _, body_id), .. })) + | Some(Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(_, body_id), .. })) => { + Some(*body_id) + } + _ => None, + } + } + let hir_map = self.infcx.tcx.hir(); + let mir_body_hir_id = self.mir_hir_id(); + if let Some(fn_body_id) = maybe_body_id_of_fn(&hir_map, mir_body_hir_id) { if let Block( hir::Block { expr: @@ -579,7 +591,7 @@ fn suggest_similar_mut_method_for_for_loop(&self, err: &mut DiagnosticBuilder<'_ .. }, _, - ) = hir.body(body_id).value.kind + ) = hir_map.body(fn_body_id).value.kind { let opt_suggestions = path_segment .hir_id From 26ca5fb06f9153ea84397134e24d8db208df5fd0 Mon Sep 17 00:00:00 2001 From: b-naber Date: Sat, 13 Feb 2021 12:12:57 +0100 Subject: [PATCH 22/24] add test --- src/test/ui/borrowck/issue-82032.rs | 16 ++++++++++++++++ src/test/ui/borrowck/issue-82032.stderr | 14 ++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/test/ui/borrowck/issue-82032.rs create mode 100644 src/test/ui/borrowck/issue-82032.stderr diff --git a/src/test/ui/borrowck/issue-82032.rs b/src/test/ui/borrowck/issue-82032.rs new file mode 100644 index 00000000000..4a01b60c1f6 --- /dev/null +++ b/src/test/ui/borrowck/issue-82032.rs @@ -0,0 +1,16 @@ +use std::{fs, io::*}; +use std::collections::HashMap; + +type Handle = BufWriter; +struct Thing(HashMap); + +impl Thing { + pub fn die_horribly(&mut self) { + for v in self.0.values() { + v.flush(); + //~^ ERROR cannot borrow + } + } +} + +fn main() {} diff --git a/src/test/ui/borrowck/issue-82032.stderr b/src/test/ui/borrowck/issue-82032.stderr new file mode 100644 index 00000000000..f272477a9f5 --- /dev/null +++ b/src/test/ui/borrowck/issue-82032.stderr @@ -0,0 +1,14 @@ +error[E0596]: cannot borrow `*v` as mutable, as it is behind a `&` reference + --> $DIR/issue-82032.rs:10:13 + | +LL | for v in self.0.values() { + | --------------- + | | | + | | help: use mutable method: `values_mut()` + | this iterator yields `&` references +LL | v.flush(); + | ^ `v` is a `&` reference, so the data it refers to cannot be borrowed as mutable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. From fe82365630a5bb8a785cc1601248cc996c82c37a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Wed, 10 Feb 2021 17:32:45 +0300 Subject: [PATCH 23/24] Fix MIR pretty printer for non-local DefIds --- compiler/rustc_mir/src/util/pretty.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_mir/src/util/pretty.rs b/compiler/rustc_mir/src/util/pretty.rs index 7fc1c3a73af..f46e94eea96 100644 --- a/compiler/rustc_mir/src/util/pretty.rs +++ b/compiler/rustc_mir/src/util/pretty.rs @@ -289,19 +289,19 @@ pub fn write_mir_pretty<'tcx>( } Ok(()) }; - match tcx.hir().body_const_context(def_id.expect_local()) { - None => render_body(w, tcx.optimized_mir(def_id))?, - // For `const fn` we want to render the optimized MIR. If you want the mir used in - // ctfe, you can dump the MIR after the `Deaggregator` optimization pass. - Some(rustc_hir::ConstContext::ConstFn) => { - render_body(w, tcx.optimized_mir(def_id))?; - writeln!(w)?; - writeln!(w, "// MIR FOR CTFE")?; - // Do not use `render_body`, as that would render the promoteds again, but these - // are shared between mir_for_ctfe and optimized_mir - write_mir_fn(tcx, tcx.mir_for_ctfe(def_id), &mut |_, _| Ok(()), w)?; - } - Some(_) => render_body(w, tcx.mir_for_ctfe(def_id))?, + + // For `const fn` we want to render both the optimized MIR and the MIR for ctfe. + if tcx.is_const_fn_raw(def_id) { + render_body(w, tcx.optimized_mir(def_id))?; + writeln!(w)?; + writeln!(w, "// MIR FOR CTFE")?; + // Do not use `render_body`, as that would render the promoteds again, but these + // are shared between mir_for_ctfe and optimized_mir + write_mir_fn(tcx, tcx.mir_for_ctfe(def_id), &mut |_, _| Ok(()), w)?; + } else { + let instance_mir = + tcx.instance_mir(ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id))); + render_body(w, instance_mir)?; } } Ok(()) From 93c8ebe022d0eac6fb02848dc85f003cf7b7503c Mon Sep 17 00:00:00 2001 From: klensy Date: Sun, 14 Feb 2021 17:37:30 +0300 Subject: [PATCH 24/24] bumped smallvec deps --- Cargo.lock | 80 +++++++++++------------ compiler/rustc_apfloat/Cargo.toml | 2 +- compiler/rustc_arena/Cargo.toml | 2 +- compiler/rustc_ast/Cargo.toml | 2 +- compiler/rustc_ast_lowering/Cargo.toml | 2 +- compiler/rustc_builtin_macros/Cargo.toml | 2 +- compiler/rustc_codegen_llvm/Cargo.toml | 2 +- compiler/rustc_data_structures/Cargo.toml | 2 +- compiler/rustc_expand/Cargo.toml | 2 +- compiler/rustc_hir/Cargo.toml | 2 +- compiler/rustc_infer/Cargo.toml | 2 +- compiler/rustc_interface/Cargo.toml | 2 +- compiler/rustc_metadata/Cargo.toml | 2 +- compiler/rustc_middle/Cargo.toml | 2 +- compiler/rustc_mir/Cargo.toml | 2 +- compiler/rustc_mir_build/Cargo.toml | 2 +- compiler/rustc_parse/Cargo.toml | 2 +- compiler/rustc_query_system/Cargo.toml | 2 +- compiler/rustc_resolve/Cargo.toml | 2 +- compiler/rustc_serialize/Cargo.toml | 2 +- compiler/rustc_trait_selection/Cargo.toml | 2 +- compiler/rustc_traits/Cargo.toml | 2 +- compiler/rustc_typeck/Cargo.toml | 2 +- src/librustdoc/Cargo.toml | 2 +- src/tools/rustc-workspace-hack/Cargo.toml | 4 +- 25 files changed, 65 insertions(+), 65 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9e65ffc391..c1011c0f479 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -593,7 +593,7 @@ dependencies = [ "rustc-semver", "semver 0.11.0", "serde", - "smallvec 1.4.2", + "smallvec 1.6.1", "syn", "toml", "unicode-normalization", @@ -2086,7 +2086,7 @@ checksum = "22bf8d885d073610aee20e7fa205c4341ed32a761dbde96da5fd96301a8d3e82" dependencies = [ "parking_lot", "rustc-hash", - "smallvec 1.4.2", + "smallvec 1.6.1", ] [[package]] @@ -2236,7 +2236,7 @@ dependencies = [ "rustc-workspace-hack", "rustc_version", "shell-escape", - "smallvec 1.4.2", + "smallvec 1.6.1", ] [[package]] @@ -2459,7 +2459,7 @@ dependencies = [ "instant", "libc", "redox_syscall", - "smallvec 1.4.2", + "smallvec 1.6.1", "winapi 0.3.9", ] @@ -3110,7 +3110,7 @@ version = "705.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93575affa286089b92c8208aea4e60fe9fdd251a619a09b566d6e4e2cc123212" dependencies = [ - "smallvec 1.4.2", + "smallvec 1.6.1", ] [[package]] @@ -3126,7 +3126,7 @@ dependencies = [ "rustc-ap-rustc_macros", "rustc-ap-rustc_serialize", "rustc-ap-rustc_span", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", ] @@ -3201,7 +3201,7 @@ dependencies = [ "rustc-hash", "rustc-rayon", "rustc-rayon-core", - "smallvec 1.4.2", + "smallvec 1.6.1", "stable_deref_trait", "stacker", "tempfile", @@ -3249,7 +3249,7 @@ dependencies = [ "rustc-ap-rustc_serialize", "rustc-ap-rustc_session", "rustc-ap-rustc_span", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", ] @@ -3337,7 +3337,7 @@ dependencies = [ "rustc-ap-rustc_lexer", "rustc-ap-rustc_session", "rustc-ap-rustc_span", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", "unicode-normalization", ] @@ -3349,7 +3349,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc232e2a351d8131c8f1386ce372ee22ef7b1b0b897bbf817a8ce4792029a564" dependencies = [ "indexmap", - "smallvec 1.4.2", + "smallvec 1.6.1", ] [[package]] @@ -3497,8 +3497,8 @@ dependencies = [ "quote", "serde", "serde_json", - "smallvec 0.6.13", - "smallvec 1.4.2", + "smallvec 0.6.14", + "smallvec 1.6.1", "syn", "url 2.1.1", "winapi 0.3.9", @@ -3509,14 +3509,14 @@ name = "rustc_apfloat" version = "0.0.0" dependencies = [ "bitflags", - "smallvec 1.4.2", + "smallvec 1.6.1", ] [[package]] name = "rustc_arena" version = "0.0.0" dependencies = [ - "smallvec 1.4.2", + "smallvec 1.6.1", ] [[package]] @@ -3530,7 +3530,7 @@ dependencies = [ "rustc_macros", "rustc_serialize", "rustc_span", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", ] @@ -3548,7 +3548,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", ] @@ -3611,7 +3611,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", ] @@ -3639,7 +3639,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", - "smallvec 1.4.2", + "smallvec 1.6.1", "snap", "tracing", ] @@ -3697,7 +3697,7 @@ dependencies = [ "rustc_index", "rustc_macros", "rustc_serialize", - "smallvec 1.4.2", + "smallvec 1.6.1", "stable_deref_trait", "stacker", "tempfile", @@ -3778,7 +3778,7 @@ dependencies = [ "rustc_serialize", "rustc_session", "rustc_span", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", ] @@ -3810,7 +3810,7 @@ dependencies = [ "rustc_serialize", "rustc_span", "rustc_target", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", ] @@ -3868,7 +3868,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", ] @@ -3909,7 +3909,7 @@ dependencies = [ "rustc_traits", "rustc_ty_utils", "rustc_typeck", - "smallvec 1.4.2", + "smallvec 1.6.1", "tempfile", "tracing", "winapi 0.3.9", @@ -3999,7 +3999,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", - "smallvec 1.4.2", + "smallvec 1.6.1", "snap", "stable_deref_trait", "tracing", @@ -4031,7 +4031,7 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_type_ir", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", ] @@ -4062,7 +4062,7 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_trait_selection", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", ] @@ -4085,7 +4085,7 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_trait_selection", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", ] @@ -4102,7 +4102,7 @@ dependencies = [ "rustc_lexer", "rustc_session", "rustc_span", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", "unicode-normalization", ] @@ -4178,7 +4178,7 @@ dependencies = [ "rustc_macros", "rustc_serialize", "rustc_span", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", ] @@ -4202,7 +4202,7 @@ dependencies = [ "rustc_middle", "rustc_session", "rustc_span", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", ] @@ -4231,7 +4231,7 @@ version = "0.0.0" dependencies = [ "indexmap", "rustc_macros", - "smallvec 1.4.2", + "smallvec 1.6.1", ] [[package]] @@ -4328,7 +4328,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", ] @@ -4348,7 +4348,7 @@ dependencies = [ "rustc_middle", "rustc_span", "rustc_trait_selection", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", ] @@ -4398,7 +4398,7 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_trait_selection", - "smallvec 1.4.2", + "smallvec 1.6.1", "tracing", ] @@ -4425,7 +4425,7 @@ dependencies = [ "rustdoc-json-types", "serde", "serde_json", - "smallvec 1.4.2", + "smallvec 1.6.1", "tempfile", ] @@ -4759,18 +4759,18 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" [[package]] name = "smallvec" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" +checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" dependencies = [ "maybe-uninit", ] [[package]] name = "smallvec" -version = "1.4.2" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" [[package]] name = "snap" @@ -5237,7 +5237,7 @@ dependencies = [ "serde", "serde_json", "sharded-slab", - "smallvec 1.4.2", + "smallvec 1.6.1", "thread_local", "tracing", "tracing-core", diff --git a/compiler/rustc_apfloat/Cargo.toml b/compiler/rustc_apfloat/Cargo.toml index 306513f1a7e..103e64be5ac 100644 --- a/compiler/rustc_apfloat/Cargo.toml +++ b/compiler/rustc_apfloat/Cargo.toml @@ -6,4 +6,4 @@ edition = "2018" [dependencies] bitflags = "1.2.1" -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_arena/Cargo.toml b/compiler/rustc_arena/Cargo.toml index 29caa852ed4..f2d039c82ab 100644 --- a/compiler/rustc_arena/Cargo.toml +++ b/compiler/rustc_arena/Cargo.toml @@ -5,4 +5,4 @@ version = "0.0.0" edition = "2018" [dependencies] -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml index 13e17a807c4..6b9b9e8155e 100644 --- a/compiler/rustc_ast/Cargo.toml +++ b/compiler/rustc_ast/Cargo.toml @@ -15,5 +15,5 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_index = { path = "../rustc_index" } rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } bitflags = "1.2.1" diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index 177a9066edf..0cced00189e 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -19,4 +19,4 @@ rustc_span = { path = "../rustc_span" } rustc_errors = { path = "../rustc_errors" } rustc_session = { path = "../rustc_session" } rustc_ast = { path = "../rustc_ast" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index eb022b5b2b1..962dfbac934 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -19,7 +19,7 @@ rustc_lexer = { path = "../rustc_lexer" } rustc_parse = { path = "../rustc_parse" } rustc_target = { path = "../rustc_target" } rustc_session = { path = "../rustc_session" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } rustc_ast = { path = "../rustc_ast" } rustc_expand = { path = "../rustc_expand" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index f9373640dce..ebbb852f21c 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -29,6 +29,6 @@ rustc_llvm = { path = "../rustc_llvm" } rustc_session = { path = "../rustc_session" } rustc_serialize = { path = "../rustc_serialize" } rustc_target = { path = "../rustc_target" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 23e689fcae7..e3476517de5 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -22,7 +22,7 @@ stable_deref_trait = "1.0.0" rayon = { version = "0.3.0", package = "rustc-rayon" } rayon-core = { version = "0.3.0", package = "rustc-rayon-core" } rustc-hash = "1.1.0" -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } rustc_index = { path = "../rustc_index", package = "rustc_index" } bitflags = "1.2.1" measureme = "9.0.0" diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml index 7413b0d9431..59c1604e844 100644 --- a/compiler/rustc_expand/Cargo.toml +++ b/compiler/rustc_expand/Cargo.toml @@ -23,5 +23,5 @@ rustc_macros = { path = "../rustc_macros" } rustc_lexer = { path = "../rustc_lexer" } rustc_parse = { path = "../rustc_parse" } rustc_session = { path = "../rustc_session" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } rustc_ast = { path = "../rustc_ast" } diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index c14165454ed..d41b81f8f21 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -17,4 +17,4 @@ rustc_span = { path = "../rustc_span" } rustc_serialize = { path = "../rustc_serialize" } rustc_ast = { path = "../rustc_ast" } tracing = "0.1" -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index 5dba4106c94..a75ad7b31a6 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -20,5 +20,5 @@ rustc_session = { path = "../rustc_session" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } rustc_ast = { path = "../rustc_ast" } diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index 2481a27dee7..f3e4aab941b 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -11,7 +11,7 @@ doctest = false libc = "0.2" tracing = "0.1" rayon = { version = "0.3.0", package = "rustc-rayon" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } rustc_ast = { path = "../rustc_ast" } rustc_attr = { path = "../rustc_attr" } rustc_builtin_macros = { path = "../rustc_builtin_macros" } diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index f1975e78801..2aabc2c407b 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -12,7 +12,7 @@ libc = "0.2" snap = "1" tracing = "0.1" memmap = "0.7" -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } rustc_middle = { path = "../rustc_middle" } rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index d33aad3b710..7de398a1898 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -27,7 +27,7 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } chalk-ir = "0.55.0" -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } measureme = "9.0.0" rustc_session = { path = "../rustc_session" } rustc_type_ir = { path = "../rustc_type_ir" } diff --git a/compiler/rustc_mir/Cargo.toml b/compiler/rustc_mir/Cargo.toml index 10dbf35fedc..59a0c9a5dd5 100644 --- a/compiler/rustc_mir/Cargo.toml +++ b/compiler/rustc_mir/Cargo.toml @@ -31,7 +31,7 @@ rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } rustc_apfloat = { path = "../rustc_apfloat" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } [dev-dependencies] coverage_test_macros = { path = "src/transform/coverage/test_macros" } diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index 2dd894a67a6..b75221bb5d5 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -24,4 +24,4 @@ rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_ast = { path = "../rustc_ast" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml index 52835e5c8a9..c887729c355 100644 --- a/compiler/rustc_parse/Cargo.toml +++ b/compiler/rustc_parse/Cargo.toml @@ -19,4 +19,4 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_ast = { path = "../rustc_ast" } unicode-normalization = "0.1.11" -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index f38d62dec00..d18a2a6faed 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -18,4 +18,4 @@ rustc_index = { path = "../rustc_index" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } parking_lot = "0.11" -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index 821f9ea4738..7441f4a9f22 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -26,4 +26,4 @@ rustc_index = { path = "../rustc_index" } rustc_metadata = { path = "../rustc_metadata" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml index 16c5dff7341..05fc6a4e11d 100644 --- a/compiler/rustc_serialize/Cargo.toml +++ b/compiler/rustc_serialize/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] indexmap = "1" -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } [dev-dependencies] rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index a72c172918b..c5d4c2400f8 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -22,4 +22,4 @@ rustc_macros = { path = "../rustc_macros" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml index 8fdbc3b76b4..a7ce14afaa3 100644 --- a/compiler/rustc_traits/Cargo.toml +++ b/compiler/rustc_traits/Cargo.toml @@ -16,6 +16,6 @@ rustc_span = { path = "../rustc_span" } chalk-ir = "0.55.0" chalk-solve = "0.55.0" chalk-engine = "0.55.0" -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } rustc_infer = { path = "../rustc_infer" } rustc_trait_selection = { path = "../rustc_trait_selection" } diff --git a/compiler/rustc_typeck/Cargo.toml b/compiler/rustc_typeck/Cargo.toml index e3ba0bea7e8..d92d317e34a 100644 --- a/compiler/rustc_typeck/Cargo.toml +++ b/compiler/rustc_typeck/Cargo.toml @@ -20,7 +20,7 @@ rustc_hir = { path = "../rustc_hir" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_target = { path = "../rustc_target" } rustc_session = { path = "../rustc_session" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } rustc_index = { path = "../rustc_index" } diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index b6965898b4e..1b9a35e6491 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -14,7 +14,7 @@ minifier = "0.0.33" rayon = { version = "0.3.0", package = "rustc-rayon" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -smallvec = "1.0" +smallvec = "1.6.1" tempfile = "3" itertools = "0.9" regex = "1" diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml index 1cde0e25ced..8da7db2dfdd 100644 --- a/src/tools/rustc-workspace-hack/Cargo.toml +++ b/src/tools/rustc-workspace-hack/Cargo.toml @@ -71,8 +71,8 @@ proc-macro2 = { version = "1", features = ["default"] } quote = { version = "1", features = ["default"] } serde = { version = "1.0.82", features = ['derive'] } serde_json = { version = "1.0.31", features = ["raw_value", "unbounded_depth"] } -smallvec-0_6 = { package = "smallvec", version = "0.6", features = ['union', 'may_dangle'] } -smallvec = { version = "1.0", features = ['union', 'may_dangle'] } +smallvec-0_6 = { package = "smallvec", version = "0.6.14", features = ['union', 'may_dangle'] } +smallvec = { version = "1.6.1", features = ['union', 'may_dangle'] } syn = { version = "1", features = ['fold', 'full', 'extra-traits', 'visit', 'visit-mut'] } url = { version = "2.0", features = ['serde'] }