From a0c21e4e7ea3a2143af9e65a98a19e6b1942ff53 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 31 Oct 2022 20:55:03 -0400 Subject: [PATCH 1/6] Remove let_underscore_must_use from list of uplifted lints --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index a3df56f1d2afc..ad550260c8bcf 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -6,7 +6,7 @@ Language - [Error on `as` casts of enums with `#[non_exhaustive]` variants](https://github.com/rust-lang/rust/pull/92744/) - [Stabilize `let else`](https://github.com/rust-lang/rust/pull/93628/) - [Stabilize generic associated types (GATs)](https://github.com/rust-lang/rust/pull/96709/) -- [Add lints `let_underscore_drop`, `let_underscore_lock`, and `let_underscore_must_use` from Clippy](https://github.com/rust-lang/rust/pull/97739/) +- [Add lints `let_underscore_drop` and `let_underscore_lock` from Clippy](https://github.com/rust-lang/rust/pull/97739/) - [Stabilize `break`ing from arbitrary labeled blocks ("label-break-value")](https://github.com/rust-lang/rust/pull/99332/) - [Uninitialized integers, floats, and raw pointers are now considered immediate UB](https://github.com/rust-lang/rust/pull/98919/). Usage of `MaybeUninit` is the correct way to work with uninitialized memory. From 10a5e75537e3189ffa808be7eadc19569966b266 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Tue, 1 Nov 2022 12:24:51 -0500 Subject: [PATCH 2/6] Add track_caller to some Lock methods --- compiler/rustc_data_structures/src/sync.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 9c0fb8265cff7..c550f246e094a 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -410,6 +410,7 @@ impl Lock { #[cfg(parallel_compiler)] #[inline(always)] + #[track_caller] pub fn lock(&self) -> LockGuard<'_, T> { if ERROR_CHECKING { self.0.try_lock().expect("lock was already held") @@ -420,21 +421,25 @@ impl Lock { #[cfg(not(parallel_compiler))] #[inline(always)] + #[track_caller] pub fn lock(&self) -> LockGuard<'_, T> { self.0.borrow_mut() } #[inline(always)] + #[track_caller] pub fn with_lock R, R>(&self, f: F) -> R { f(&mut *self.lock()) } #[inline(always)] + #[track_caller] pub fn borrow(&self) -> LockGuard<'_, T> { self.lock() } #[inline(always)] + #[track_caller] pub fn borrow_mut(&self) -> LockGuard<'_, T> { self.lock() } @@ -476,6 +481,7 @@ impl RwLock { #[cfg(not(parallel_compiler))] #[inline(always)] + #[track_caller] pub fn read(&self) -> ReadGuard<'_, T> { self.0.borrow() } @@ -491,6 +497,7 @@ impl RwLock { } #[inline(always)] + #[track_caller] pub fn with_read_lock R, R>(&self, f: F) -> R { f(&*self.read()) } @@ -509,6 +516,7 @@ impl RwLock { #[cfg(not(parallel_compiler))] #[inline(always)] + #[track_caller] pub fn write(&self) -> WriteGuard<'_, T> { self.0.borrow_mut() } @@ -524,16 +532,19 @@ impl RwLock { } #[inline(always)] + #[track_caller] pub fn with_write_lock R, R>(&self, f: F) -> R { f(&mut *self.write()) } #[inline(always)] + #[track_caller] pub fn borrow(&self) -> ReadGuard<'_, T> { self.read() } #[inline(always)] + #[track_caller] pub fn borrow_mut(&self) -> WriteGuard<'_, T> { self.write() } From 74fec9b95ad308c3dc064bb38778aea4ec51f5ee Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Nov 2022 02:13:27 +0000 Subject: [PATCH 3/6] Remove has_errors from FnCtxt --- compiler/rustc_hir_typeck/src/expr.rs | 2 -- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 1 - .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 8 +------ compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 4 ---- src/test/ui/error-codes/E0767.rs | 3 ++- src/test/ui/error-codes/E0767.stderr | 21 +++++++++++++++---- 6 files changed, 20 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 9fde62a81a1a6..47b5673e8b3d0 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -220,7 +220,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Hide the outer diverging and has_errors flags. let old_diverges = self.diverges.replace(Diverges::Maybe); - let old_has_errors = self.has_errors.replace(false); let ty = ensure_sufficient_stack(|| match &expr.kind { hir::ExprKind::Path( @@ -259,7 +258,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Combine the diverging and has_error flags. self.diverges.set(self.diverges.get() | old_diverges); - self.has_errors.set(self.has_errors.get() | old_has_errors); debug!("type of {} is...", self.tcx.hir().node_to_string(expr.hir_id)); debug!("... {:?}, expected is {:?}", ty, expected); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 6a1cffe3e6025..38da0a47d7161 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -143,7 +143,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.typeck_results.borrow_mut().node_types_mut().insert(id, ty); if ty.references_error() { - self.has_errors.set(true); self.set_tainted_by_errors(); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 8e0fcb56c7f37..e1955d838f253 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1334,7 +1334,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Hide the outer diverging and `has_errors` flags. let old_diverges = self.diverges.replace(Diverges::Maybe); - let old_has_errors = self.has_errors.replace(false); match stmt.kind { hir::StmtKind::Local(l) => { @@ -1364,7 +1363,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Combine the diverging and `has_error` flags. self.diverges.set(self.diverges.get() | old_diverges); - self.has_errors.set(self.has_errors.get() | old_has_errors); } pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) { @@ -1544,11 +1542,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.diverges.set(prev_diverges); } - let mut ty = ctxt.coerce.unwrap().complete(self); - - if self.has_errors.get() || ty.references_error() { - ty = self.tcx.ty_error() - } + let ty = ctxt.coerce.unwrap().complete(self); self.write_ty(blk.hir_id, ty); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 0c600daf4459e..19839ad4d4c27 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -112,9 +112,6 @@ pub struct FnCtxt<'a, 'tcx> { /// the diverges flag is set to something other than `Maybe`. pub(super) diverges: Cell, - /// Whether any child nodes have any type errors. - pub(super) has_errors: Cell, - pub(super) enclosing_breakables: RefCell>, pub(super) inh: &'a Inherited<'tcx>, @@ -145,7 +142,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { resume_yield_tys: None, ps: Cell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)), diverges: Cell::new(Diverges::Maybe), - has_errors: Cell::new(false), enclosing_breakables: RefCell::new(EnclosingBreakables { stack: Vec::new(), by_id: Default::default(), diff --git a/src/test/ui/error-codes/E0767.rs b/src/test/ui/error-codes/E0767.rs index 6c6cb746e6c75..14215d36a3833 100644 --- a/src/test/ui/error-codes/E0767.rs +++ b/src/test/ui/error-codes/E0767.rs @@ -1,6 +1,7 @@ -fn main () { +fn main() { 'a: loop { || { + //~^ ERROR mismatched types loop { break 'a; } //~ ERROR E0767 } } diff --git a/src/test/ui/error-codes/E0767.stderr b/src/test/ui/error-codes/E0767.stderr index 2429823306b6e..ee85247301c9c 100644 --- a/src/test/ui/error-codes/E0767.stderr +++ b/src/test/ui/error-codes/E0767.stderr @@ -1,14 +1,27 @@ error[E0767]: use of unreachable label `'a` - --> $DIR/E0767.rs:4:26 + --> $DIR/E0767.rs:5:26 | LL | 'a: loop { | -- unreachable label defined here -LL | || { +... LL | loop { break 'a; } | ^^ unreachable label `'a` | = note: labels are unreachable through functions, closures, async blocks and modules -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/E0767.rs:3:9 + | +LL | / || { +LL | | +LL | | loop { break 'a; } +LL | | } + | |_________^ expected `()`, found closure + | + = note: expected unit type `()` + found closure `[closure@$DIR/E0767.rs:3:9: 3:11]` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0767`. +Some errors have detailed explanations: E0308, E0767. +For more information about an error, try `rustc --explain E0308`. From 59be5151287e29d5340d6189dea2f18206f51e02 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Nov 2022 17:33:25 +0000 Subject: [PATCH 4/6] Properly render asyncness for traits without default body --- compiler/rustc_ty_utils/src/ty.rs | 2 +- src/librustdoc/clean/mod.rs | 32 +++++++++++++++++------------ src/librustdoc/clean/types.rs | 5 +---- src/test/rustdoc/async-trait-sig.rs | 14 +++++++++++++ 4 files changed, 35 insertions(+), 18 deletions(-) create mode 100644 src/test/rustdoc/async-trait-sig.rs diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 3eebb4ace477f..99d3bda6ebfff 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -413,7 +413,7 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { /// Check if a function is async. fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync { let node = tcx.hir().get_by_def_id(def_id.expect_local()); - if let Some(fn_kind) = node.fn_kind() { fn_kind.asyncness() } else { hir::IsAsync::NotAsync } + node.fn_sig().map_or(hir::IsAsync::NotAsync, |sig| sig.header.asyncness) } /// Don't call this directly: use ``tcx.conservative_is_privately_uninhabited`` instead. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1ce0d1e4ffd02..84afdadfa002a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -880,7 +880,7 @@ fn clean_fn_or_proc_macro<'tcx>( ProcMacroItem(ProcMacro { kind, helpers }) } None => { - let mut func = clean_function(cx, sig, generics, body_id); + let mut func = clean_function(cx, sig, generics, FunctionArgs::Body(body_id)); clean_fn_decl_legacy_const_generics(&mut func, attrs); FunctionItem(func) } @@ -917,16 +917,28 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attrib } } +enum FunctionArgs<'tcx> { + Body(hir::BodyId), + Names(&'tcx [Ident]), +} + fn clean_function<'tcx>( cx: &mut DocContext<'tcx>, sig: &hir::FnSig<'tcx>, generics: &hir::Generics<'tcx>, - body_id: hir::BodyId, + args: FunctionArgs<'tcx>, ) -> Box { let (generics, decl) = enter_impl_trait(cx, |cx| { // NOTE: generics must be cleaned before args let generics = clean_generics(generics, cx); - let args = clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id); + let args = match args { + FunctionArgs::Body(body_id) => { + clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id) + } + FunctionArgs::Names(names) => { + clean_args_from_types_and_names(cx, sig.decl.inputs, names) + } + }; let mut decl = clean_fn_decl_with_args(cx, sig.decl, args); if sig.header.is_async() { decl.output = decl.sugared_async_return_type(); @@ -1051,18 +1063,12 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext ), hir::TraitItemKind::Const(ty, None) => TyAssocConstItem(clean_ty(ty, cx)), hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => { - let m = clean_function(cx, sig, trait_item.generics, body); + let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Body(body)); MethodItem(m, None) } hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(names)) => { - let (generics, decl) = enter_impl_trait(cx, |cx| { - // NOTE: generics must be cleaned before args - let generics = clean_generics(trait_item.generics, cx); - let args = clean_args_from_types_and_names(cx, sig.decl.inputs, names); - let decl = clean_fn_decl_with_args(cx, sig.decl, args); - (generics, decl) - }); - TyMethodItem(Box::new(Function { decl, generics })) + let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Names(names)); + TyMethodItem(m) } hir::TraitItemKind::Type(bounds, Some(default)) => { let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); @@ -1099,7 +1105,7 @@ pub(crate) fn clean_impl_item<'tcx>( AssocConstItem(clean_ty(ty, cx), default) } hir::ImplItemKind::Fn(ref sig, body) => { - let m = clean_function(cx, sig, impl_.generics, body); + let m = clean_function(cx, sig, impl_.generics, FunctionArgs::Body(body)); let defaultness = cx.tcx.impl_defaultness(impl_.owner_id); MethodItem(m, Some(defaultness)) } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 439311f064029..f1eb438b199ce 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -694,13 +694,10 @@ impl Item { asyncness: hir::IsAsync::NotAsync, } } - ItemKind::FunctionItem(_) | ItemKind::MethodItem(_, _) => { + ItemKind::FunctionItem(_) | ItemKind::MethodItem(_, _) | ItemKind::TyMethodItem(_) => { let def_id = self.item_id.as_def_id().unwrap(); build_fn_header(def_id, tcx, tcx.asyncness(def_id)) } - ItemKind::TyMethodItem(_) => { - build_fn_header(self.item_id.as_def_id().unwrap(), tcx, hir::IsAsync::NotAsync) - } _ => return None, }; Some(header) diff --git a/src/test/rustdoc/async-trait-sig.rs b/src/test/rustdoc/async-trait-sig.rs new file mode 100644 index 0000000000000..2578bc8f7a166 --- /dev/null +++ b/src/test/rustdoc/async-trait-sig.rs @@ -0,0 +1,14 @@ +// edition:2021 + +#![feature(async_fn_in_trait)] +#![allow(incomplete_features)] + +pub trait Foo { + // @has async_trait_sig/trait.Foo.html '//h4[@class="code-header"]' "async fn bar() -> i32" + async fn bar() -> i32; + + // @has async_trait_sig/trait.Foo.html '//h4[@class="code-header"]' "async fn baz() -> i32" + async fn baz() -> i32 { + 1 + } +} From 868ccd5afefa4a6ea177eb68ec8f408e7d693a67 Mon Sep 17 00:00:00 2001 From: Yiming Lei Date: Thu, 27 Oct 2022 22:38:59 -0700 Subject: [PATCH 5/6] remove redundent "<>" for ty::Slice with reference type this fix #103271 --- .../rustc_hir_typeck/src/method/suggest.rs | 6 +++ compiler/rustc_span/src/source_map.rs | 44 +++++++++++++++++++ src/test/ui/type/issue-103271.rs | 9 ++++ src/test/ui/type/issue-103271.stderr | 22 ++++++++++ 4 files changed, 81 insertions(+) create mode 100644 src/test/ui/type/issue-103271.rs create mode 100644 src/test/ui/type/issue-103271.stderr diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index f4351bfa84aed..9e6fa814766f0 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1864,6 +1864,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::Str | ty::Projection(_) | ty::Param(_) => format!("{deref_ty}"), + // we need to test something like <&[_]>::len + // and Vec::function(); + // <&[_]>::len doesn't need an extra "<>" between + // but for Adt type like Vec::function() + // we would suggest <[_]>::function(); + _ if self.tcx.sess.source_map().span_wrapped_by_angle_bracket(ty.span) => format!("{deref_ty}"), _ => format!("<{deref_ty}>"), }; err.span_suggestion_verbose( diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index f9566eeee9465..029cd93a52a3b 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -753,6 +753,50 @@ impl SourceMap { } } + /// Given a 'Span', tries to tell if the next character is '>' + /// and the previous charactoer is '<' after skipping white space + /// return true if wrapped by '<>' + pub fn span_wrapped_by_angle_bracket(&self, span: Span) -> bool { + self.span_to_source(span, |src, start_index, end_index| { + if src.get(start_index..end_index).is_none() { + return Ok(false); + } + // test the right side to match '>' after skipping white space + let end_src = &src[end_index..]; + let mut i = 0; + while let Some(cc) = end_src.chars().nth(i) { + if cc == ' ' { + i = i + 1; + } else if cc == '>' { + // found > in the right; + break; + } else { + // failed to find '>' return false immediately + return Ok(false); + } + } + // test the left side to match '<' after skipping white space + i = start_index; + let start_src = &src[0..start_index]; + while let Some(cc) = start_src.chars().nth(i) { + if cc == ' ' { + if i == 0 { + return Ok(false); + } + i = i - 1; + } else if cc == '<' { + // found < in the left + break; + } else { + // failed to find '<' return false immediately + return Ok(false); + } + } + return Ok(true); + }) + .map_or(false, |is_accessible| is_accessible) + } + /// Given a `Span`, tries to get a shorter span ending just after the first occurrence of `char` /// `c`. pub fn span_through_char(&self, sp: Span, c: char) -> Span { diff --git a/src/test/ui/type/issue-103271.rs b/src/test/ui/type/issue-103271.rs new file mode 100644 index 0000000000000..41e99e2d82128 --- /dev/null +++ b/src/test/ui/type/issue-103271.rs @@ -0,0 +1,9 @@ +fn main() { + //~^ HELP the following trait is implemented but not in scope; perhaps add a `use` for it: + let length = <&[_]>::len; + //~^ ERROR the function or associated item `len` exists for reference `&[_]`, but its trait bounds were not satisfied [E0599] + //~| function or associated item cannot be called on `&[_]` due to unsatisfied trait bounds + //~| HELP items from traits can only be used if the trait is in scope + //~| HELP the function `len` is implemented on `[_]` + assert_eq!(length(&[1,3]), 2); +} diff --git a/src/test/ui/type/issue-103271.stderr b/src/test/ui/type/issue-103271.stderr new file mode 100644 index 0000000000000..3eec881a91b03 --- /dev/null +++ b/src/test/ui/type/issue-103271.stderr @@ -0,0 +1,22 @@ +error[E0599]: the function or associated item `len` exists for reference `&[_]`, but its trait bounds were not satisfied + --> $DIR/issue-103271.rs:3:26 + | +LL | let length = <&[_]>::len; + | ^^^ function or associated item cannot be called on `&[_]` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `&[_]: ExactSizeIterator` + which is required by `&mut &[_]: ExactSizeIterator` + = help: items from traits can only be used if the trait is in scope +help: the following trait is implemented but not in scope; perhaps add a `use` for it: + | +LL | use object::read::read_ref::ReadRef; + | +help: the function `len` is implemented on `[_]` + | +LL | let length = <[_]>::len; + | ~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. From 68e19aa4ac8812e83b80035988d915087a4183e5 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 2 Nov 2022 15:33:36 -0700 Subject: [PATCH 6/6] rustdoc: remove redundant mobile CSS `.sidebar-elems { background }` The exact same background is already set for its parent, the `nav.sidebar`. --- src/librustdoc/html/static/css/rustdoc.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 360b6b9832a55..d7526498b0d66 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1797,7 +1797,6 @@ in storage.js .sidebar-elems { margin-top: 1em; - background-color: var(--sidebar-background-color); } .content {