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 bc57a00e31b1..928a405a9de2 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 c7ca0134f9ce..7572b8c6f4a8 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 e021faa50412..af44ab9868ef 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -225,15 +225,22 @@ crate fn from_ctor_kind(struct_type: CtorKind) -> StructType { } } -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 @@ impl From for Function { 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 @@ crate fn from_function_method(function: clean::Function, has_body: bool) -> Meth 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 876b1b56dee6..b31276c9dcb7 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -243,7 +243,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { ) }) .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 f4b8dc9a3ad2..790f9d62d8a9 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 000000000000..a5038e0cd2aa --- /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 000000000000..fb4f89db2673 --- /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 000000000000..27a6ec047300 --- /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 790f9d62d8a9..20bae0f14a2f 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 fb4f89db2673..29741dd50dad 100644 --- a/src/test/rustdoc-json/fns/header.rs +++ b/src/test/rustdoc-json/fns/header.rs @@ -18,3 +18,5 @@ pub async unsafe fn async_unsafe_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 27a6ec047300..50a3db75ef39 100644 --- a/src/test/rustdoc-json/methods/header.rs +++ b/src/test/rustdoc-json/methods/header.rs @@ -21,4 +21,6 @@ impl Foo { // @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 af44ab9868ef..de0240f28f7c 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -14,6 +14,7 @@ use rustdoc_json_types::*; 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 @@ crate fn from_ctor_kind(struct_type: CtorKind) -> StructType { } } -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 @@ impl From for FunctionPointer { 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 20bae0f14a2f..a2f323699c19 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 de0240f28f7c..60197a0dc1cf 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 04a9e65e6647..4d21629cd69f 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::DefId; 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 000000000000..79702cc6b56f --- /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 000000000000..968ca395f946 --- /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 000000000000..8af48501ca29 --- /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 4d21629cd69f..1ffa8c37a803 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -698,8 +698,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // `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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) } - 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 5659345f0ff9..877c7631c9bd 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2327,6 +2327,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &generics.params[..], visitor.0, true, + true ); } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index b1d98d75196d..3d0220bfd67e 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -141,6 +141,7 @@ crate fn placeholder_type_error( generics: &[hir::GenericParam<'_>], placeholder_types: Vec, suggest: bool, + is_fn: bool, ) { if placeholder_types.is_empty() { return; @@ -171,7 +172,9 @@ crate fn placeholder_type_error( } 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 ebc0883370b7..fe67e099527a 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 4127f48a093f..e602425059e1 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 000000000000..86c39d4a48c0 --- /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 000000000000..955b42838744 --- /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 1475b212b56a..f91cfe5eb621 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 684f451b7c3f..18e06bc2b355 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 0121e1863167..f868c8d48348 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 3d0220bfd67e..d26f32420483 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -172,7 +172,7 @@ crate fn placeholder_type_error( } 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 877c7631c9bd..66bded85f3f6 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2327,7 +2327,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &generics.params[..], visitor.0, true, - true + true, ); } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index d26f32420483..58e083f2c240 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 1ef2a572ddd9..259b22e5c666 100644 --- a/library/alloc/src/collections/btree/navigate.rs +++ b/library/alloc/src/collections/btree/navigate.rs @@ -103,7 +103,8 @@ where } } -/// 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 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> 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 1d632512c78b..6f67aadc161f 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -169,7 +169,7 @@ impl NodeRef { 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 000000000000..1b54401097ea --- /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 6dbcfb963ee0..473477bf22da 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 @@ impl Display for Target { 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 0e3a722e082f..2c79eeeb0e6d 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1101,17 +1101,6 @@ impl Visitor<'tcx> for CheckAttrVisitor<'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 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> { 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 a6e9ed14ff13..65d8bcd9972e 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 31959248a68c..1ad991db3be4 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 000000000000..0e606eac1e8b --- /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 000000000000..003f43d371a3 --- /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 1ffa8c37a803..0d045c1b9c47 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -540,7 +540,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// - 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 66bded85f3f6..120a59aa9d25 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2145,12 +2145,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } 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 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { 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 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // 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 229127e95d93..fce7ae8119e1 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 58e083f2c240..754fc6a9c7b2 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -141,7 +141,7 @@ crate fn placeholder_type_error( 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 @@ crate fn placeholder_type_error( 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 fe67e099527a..ebc0883370b7 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 f91cfe5eb621..1475b212b56a 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 18e06bc2b355..684f451b7c3f 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 1635a95f46ec..f4f69fc8ac62 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -159,7 +159,7 @@ impl Inliner<'tcx> { } } - #[instrument(skip(self, caller_body))] + #[instrument(level = "debug", skip(self, caller_body))] fn is_mir_available(&self, callee: Instance<'tcx>, caller_body: &Body<'tcx>) -> bool { match callee.def { InstanceDef::Item(_) => { @@ -258,7 +258,7 @@ impl Inliner<'tcx> { 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 e4d403fbf60c..4c24bec0ce3a 100644 --- a/compiler/rustc_mir/src/transform/inline/cycle.rs +++ b/compiler/rustc_mir/src/transform/inline/cycle.rs @@ -7,7 +7,7 @@ use rustc_middle::ty::{self, subst::SubstsRef, InstanceDef, TyCtxt}; // 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 @@ crate fn mir_callgraph_reachable( !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 f3f21b903ea0..010fe4fd524d 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 @@ impl<'tcx> Witness<'tcx> { /// `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 9f265f37f35f..4ccf657335fe 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -1405,8 +1405,8 @@ fn update_disambiguator(expn_id: ExpnId) { }); 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 657d5c123e8e..45853a66efc2 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 d4ced20f8631..95f79147efd4 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -647,7 +647,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { 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 2827163d854d..cfcbc77c172f 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 60197a0dc1cf..691a7fb2a4ed 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -228,19 +228,19 @@ crate fn from_ctor_kind(struct_type: CtorKind) -> StructType { } } -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 @@ impl From for FunctionPointer { 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 a2f323699c19..eae27a4a823c 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 98450f5a547d..0400431a542e 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 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // 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 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { .. }, _, - ) = 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 000000000000..4a01b60c1f62 --- /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 000000000000..f272477a9f5b --- /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 7fc1c3a73af9..f46e94eea96c 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 a9e65ffc3910..c1011c0f479c 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 306513f1a7ea..103e64be5ac0 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 29caa852ed47..f2d039c82ab7 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 13e17a807c48..6b9b9e8155ed 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 177a9066edf5..0cced00189eb 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 eb022b5b2b16..962dfbac934c 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 f9373640dce5..ebbb852f21cc 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 23e689fcae79..e3476517de58 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 7413b0d9431f..59c1604e8444 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 c14165454ed8..d41b81f8f217 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 5dba4106c942..a75ad7b31a64 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 2481a27dee79..f3e4aab941b7 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 f1975e78801e..2aabc2c407b1 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 d33aad3b7104..7de398a1898e 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 10dbf35fedcc..59a0c9a5dd5b 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 2dd894a67a6a..b75221bb5d5c 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 52835e5c8a94..c887729c3557 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 f38d62dec004..d18a2a6faed6 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 821f9ea4738f..7441f4a9f22a 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 16c5dff73412..05fc6a4e11d4 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 a72c172918bb..c5d4c2400f82 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 8fdbc3b76b45..a7ce14afaa36 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 e3ba0bea7e8e..d92d317e34ad 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 b6965898b4e4..1b9a35e64917 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 1cde0e25cedc..8da7db2dfddb 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'] }