diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 6b529d5e0837b..3976c06222187 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -281,7 +281,12 @@ impl DefId { #[inline] #[track_caller] pub fn expect_local(self) -> LocalDefId { - self.as_local().unwrap_or_else(|| panic!("DefId::expect_local: `{:?}` isn't local", self)) + // NOTE: `match` below is required to apply `#[track_caller]`, + // i.e. don't use closures. + match self.as_local() { + Some(local_def_id) => local_def_id, + None => panic!("DefId::expect_local: `{:?}` isn't local", self), + } } #[inline] diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 634ba2baf9667..294a42a114804 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -368,16 +368,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.is_fn_ty(rcvr_ty, span) { if let SelfSource::MethodCall(expr) = source { let suggest = if let ty::FnDef(def_id, _) = rcvr_ty.kind() { - let local_id = def_id.expect_local(); - let hir_id = tcx.hir().local_def_id_to_hir_id(local_id); - let node = tcx.hir().get(hir_id); - let fields = node.tuple_fields(); - - if let Some(fields) = fields - && let Some(DefKind::Ctor(of, _)) = self.tcx.opt_def_kind(local_id) { - Some((fields, of)) + if let Some(local_id) = def_id.as_local() { + let hir_id = tcx.hir().local_def_id_to_hir_id(local_id); + let node = tcx.hir().get(hir_id); + let fields = node.tuple_fields(); + if let Some(fields) = fields + && let Some(DefKind::Ctor(of, _)) = self.tcx.opt_def_kind(local_id) { + Some((fields.len(), of)) + } else { + None + } } else { - None + // The logic here isn't smart but `associated_item_def_ids` + // doesn't work nicely on local. + if let DefKind::Ctor(of, _) = tcx.def_kind(def_id) { + let parent_def_id = tcx.parent(*def_id); + Some((tcx.associated_item_def_ids(parent_def_id).len(), of)) + } else { + None + } } } else { None @@ -385,7 +394,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If the function is a tuple constructor, we recommend that they call it if let Some((fields, kind)) = suggest { - suggest_call_constructor(expr.span, kind, fields.len(), &mut err); + suggest_call_constructor(expr.span, kind, fields, &mut err); } else { // General case err.span_label( diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index 49b6cd4232cd1..63c527b64da48 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -42,8 +42,6 @@ //! [`GlobalAlloc`] trait. This type can be provided by an external library: //! //! ```rust,ignore (demonstrates crates.io usage) -//! extern crate jemallocator; -//! //! use jemallocator::Jemalloc; //! //! #[global_allocator] diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 2224bf5f66e90..fe60c6da92bfb 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -284,7 +284,19 @@ impl StepDescription { } if !attempted_run { - panic!("error: no rules matched {}", path.display()); + eprintln!( + "error: no `{}` rules matched '{}'", + builder.kind.as_str(), + path.display() + ); + eprintln!( + "help: run `x.py {} --help --verbose` to show a list of available paths", + builder.kind.as_str() + ); + eprintln!( + "note: if you are adding a new Step to bootstrap itself, make sure you register it with `describe!`" + ); + std::process::exit(1); } } } @@ -1405,8 +1417,12 @@ impl<'a> Builder<'a> { // FIXME(davidtwco): #[cfg(not(bootstrap))] - #95612 needs to be in the bootstrap compiler // for this conditional to be removed. if !target.contains("windows") || compiler.stage >= 1 { - if target.contains("linux") || target.contains("windows") || target.contains("openbsd") - { + let needs_unstable_opts = target.contains("linux") + || target.contains("windows") + || target.contains("bsd") + || target.contains("dragonfly"); + + if needs_unstable_opts { rustflags.arg("-Zunstable-options"); } match self.config.rust_split_debuginfo { diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md index 040f46f8b7c77..56fe9a31bfe3d 100644 --- a/src/doc/unstable-book/src/language-features/plugin.md +++ b/src/doc/unstable-book/src/language-features/plugin.md @@ -102,7 +102,7 @@ The components of a lint plugin are: Lint passes are syntax traversals, but they run at a late stage of compilation where type information is available. `rustc`'s [built-in -lints](https://github.com/rust-lang/rust/blob/master/src/librustc_session/lint/builtin.rs) +lints](https://github.com/rust-lang/rust/blob/master/compiler/rustc_lint_defs/src/builtin.rs) mostly use the same infrastructure as lint plugins, and provide examples of how to access type information. diff --git a/src/test/incremental/issue-96319-coinductive-cycle.rs b/src/test/incremental/issue-96319-coinductive-cycle.rs new file mode 100644 index 0000000000000..b5ff9112a2026 --- /dev/null +++ b/src/test/incremental/issue-96319-coinductive-cycle.rs @@ -0,0 +1,34 @@ +// edition:2018 +// revisions: rpass1 rpass2 + +pub struct Stmt { + pub stmt_type: StmtKind, + #[cfg(rpass1)] pub stmt_tag: Option, + #[cfg(rpass2)] pub renamed_tag: Option, +} +pub struct LintTag; +pub enum StmtKind { + If(If), + Block(&'static str), + Return(Return), +} +pub struct If { + pub condition: Function, +} +pub struct Return { + pub value: Function, +} +pub struct Function { + pub parameters: Box, +} +pub fn start_late_pass(stmt_receiver: Box) { + spawn(async { stmt_receiver }); +} + +pub fn spawn(_: T) +where + T: Send, +{ +} + +fn main() {} diff --git a/src/test/ui/hrtb/issue-94034.rs b/src/test/ui/hrtb/issue-95034.rs similarity index 97% rename from src/test/ui/hrtb/issue-94034.rs rename to src/test/ui/hrtb/issue-95034.rs index 5239e5db11c96..aee6fe61ba812 100644 --- a/src/test/ui/hrtb/issue-94034.rs +++ b/src/test/ui/hrtb/issue-95034.rs @@ -17,6 +17,8 @@ // This should not ICE. +// Refer to the issue for more minimized versions. + use std::{ future::Future, marker::PhantomData, diff --git a/src/test/ui/hrtb/issue-94034.stderr b/src/test/ui/hrtb/issue-95034.stderr similarity index 100% rename from src/test/ui/hrtb/issue-94034.stderr rename to src/test/ui/hrtb/issue-95034.stderr diff --git a/src/test/ui/typeck/issue-96738.rs b/src/test/ui/typeck/issue-96738.rs new file mode 100644 index 0000000000000..7f1d1428eb9b4 --- /dev/null +++ b/src/test/ui/typeck/issue-96738.rs @@ -0,0 +1,3 @@ +fn main() { + Some.nonexistent_method(); //~ ERROR: no method named `nonexistent_method` found +} diff --git a/src/test/ui/typeck/issue-96738.stderr b/src/test/ui/typeck/issue-96738.stderr new file mode 100644 index 0000000000000..58c83a36a3bdc --- /dev/null +++ b/src/test/ui/typeck/issue-96738.stderr @@ -0,0 +1,16 @@ +error[E0599]: no method named `nonexistent_method` found for fn item `fn(_) -> Option<_> {Option::<_>::Some}` in the current scope + --> $DIR/issue-96738.rs:2:10 + | +LL | Some.nonexistent_method(); + | ---- ^^^^^^^^^^^^^^^^^^ method not found in `fn(_) -> Option<_> {Option::<_>::Some}` + | | + | this is the constructor of an enum variant + | +help: call the constructor + | +LL | (Some)(_).nonexistent_method(); + | + ++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`.