diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index cad5a87bb1346..0c4bcbf495a55 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -813,7 +813,7 @@ fn usage(verbose: bool, include_unstable_options: bool, nightly_build: bool) { } else { "\n --help -v Print the full set of options rustc accepts" }; - let at_path = if verbose && nightly_build { + let at_path = if verbose { " @path Read newline separated options from `path`\n" } else { "" diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 64604b6459f27..53c164d44b3e1 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1018,7 +1018,7 @@ pub trait PrettyPrinter<'tcx>: p!(write("{:?}", char::try_from(int).unwrap())) } // Raw pointers - (Scalar::Int(int), ty::RawPtr(_)) => { + (Scalar::Int(int), ty::RawPtr(_) | ty::FnPtr(_)) => { let data = int.assert_bits(self.tcx().data_layout.pointer_size); self = self.typed_value( |mut this| { @@ -1030,15 +1030,18 @@ pub trait PrettyPrinter<'tcx>: )?; } (Scalar::Ptr(ptr), ty::FnPtr(_)) => { - // FIXME: this can ICE when the ptr is dangling or points to a non-function. - // We should probably have a helper method to share code with the "Byte strings" + // FIXME: We should probably have a helper method to share code with the "Byte strings" // printing above (which also has to handle pointers to all sorts of things). - let instance = self.tcx().global_alloc(ptr.alloc_id).unwrap_fn(); - self = self.typed_value( - |this| this.print_value_path(instance.def_id(), instance.substs), - |this| this.print_type(ty), - " as ", - )?; + match self.tcx().get_global_alloc(ptr.alloc_id) { + Some(GlobalAlloc::Function(instance)) => { + self = self.typed_value( + |this| this.print_value_path(instance.def_id(), instance.substs), + |this| this.print_type(ty), + " as ", + )?; + } + _ => self = self.pretty_print_const_pointer(ptr, ty, print_ty)?, + } } // For function type zsts just printing the path is enough (Scalar::Int(int), ty::FnDef(d, s)) if int == ScalarInt::ZST => { diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index f85191f459fa9..46ecd33cc5b35 100644 --- a/compiler/rustc_mir/src/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs @@ -112,7 +112,7 @@ impl std::fmt::Display for ImmTy<'tcx, Tag> { } ScalarMaybeUninit::Uninit => cx.typed_value( |mut this| { - this.write_str("{uninit ")?; + this.write_str("uninit ")?; Ok(this) }, |this| this.print_type(ty), diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 7f27325f7f96f..f5e9cc1efcc45 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1074,13 +1074,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let last_expr_ty = self.node_ty(last_expr.hir_id); let needs_box = match (last_expr_ty.kind(), expected_ty.kind()) { + (ty::Opaque(last_def_id, _), ty::Opaque(exp_def_id, _)) + if last_def_id == exp_def_id => + { + StatementAsExpression::CorrectType + } (ty::Opaque(last_def_id, last_bounds), ty::Opaque(exp_def_id, exp_bounds)) => { debug!( "both opaque, likely future {:?} {:?} {:?} {:?}", last_def_id, last_bounds, exp_def_id, exp_bounds ); - let last_hir_id = self.tcx.hir().local_def_id_to_hir_id(last_def_id.expect_local()); - let exp_hir_id = self.tcx.hir().local_def_id_to_hir_id(exp_def_id.expect_local()); + + let (last_local_id, exp_local_id) = + match (last_def_id.as_local(), exp_def_id.as_local()) { + (Some(last_hir_id), Some(exp_hir_id)) => (last_hir_id, exp_hir_id), + (_, _) => return None, + }; + + let last_hir_id = self.tcx.hir().local_def_id_to_hir_id(last_local_id); + let exp_hir_id = self.tcx.hir().local_def_id_to_hir_id(exp_local_id); + match ( &self.tcx.hir().expect_item(last_hir_id).kind, &self.tcx.hir().expect_item(exp_hir_id).kind, diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index a89e7b53e43c4..5f1f7d8cac418 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -842,13 +842,20 @@ impl fmt::Debug for Punct { } } -#[stable(feature = "proc_macro_punct_eq", since = "1.49.0")] +#[stable(feature = "proc_macro_punct_eq", since = "1.50.0")] impl PartialEq for Punct { fn eq(&self, rhs: &char) -> bool { self.as_char() == *rhs } } +#[stable(feature = "proc_macro_punct_eq_flipped", since = "1.52.0")] +impl PartialEq for char { + fn eq(&self, rhs: &Punct) -> bool { + *self == rhs.as_char() + } +} + /// An identifier (`ident`). #[derive(Clone)] #[stable(feature = "proc_macro_lib2", since = "1.29.0")] diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index e736bf19e8f93..d1f9049c8fabb 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -251,8 +251,8 @@ pub struct Stdin { /// let mut buffer = String::new(); /// let stdin = io::stdin(); // We get `Stdin` here. /// { -/// let mut stdin_lock = stdin.lock(); // We get `StdinLock` here. -/// stdin_lock.read_to_string(&mut buffer)?; +/// let mut handle = stdin.lock(); // We get `StdinLock` here. +/// handle.read_to_string(&mut buffer)?; /// } // `StdinLock` is dropped here. /// Ok(()) /// } diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 51e7d987d9d82..1883346430be0 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -299,9 +299,9 @@ opt-level=0`](#opt-level)). That is: * When `-C lto` is not specified: * `codegen-units=1`: disable LTO. * `opt-level=0`: disable LTO. -* When `-C lto=true`: - * `lto=true`: 16 codegen units, perform fat LTO across crates. - * `codegen-units=1` + `lto=true`: 1 codegen unit, fat LTO across crates. +* When `-C lto` is specified: + * `lto`: 16 codegen units, perform fat LTO across crates. + * `codegen-units=1` + `lto`: 1 codegen unit, fat LTO across crates. See also [linker-plugin-lto](#linker-plugin-lto) for cross-language LTO. diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 3e7196fa7fa03..9a2319f6e379d 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1852,6 +1852,10 @@ impl Span { self.0 } + crate fn is_dummy(&self) -> bool { + self.0.is_dummy() + } + crate fn filename(&self, sess: &Session) -> FileName { sess.source_map().span_to_filename(self.0) } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index f5eb92c1bb5aa..7ca355ed11cc7 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1638,6 +1638,9 @@ impl Context<'_> { /// may happen, for example, with externally inlined items where the source /// of their crate documentation isn't known. fn src_href(&self, item: &clean::Item) -> Option { + if item.source.is_dummy() { + return None; + } let mut root = self.root_path(); let mut path = String::new(); let cnum = item.source.cnum(self.sess()); diff --git a/src/test/rustdoc/src-links-auto-impls.rs b/src/test/rustdoc/src-links-auto-impls.rs new file mode 100644 index 0000000000000..a1d183df0f1f2 --- /dev/null +++ b/src/test/rustdoc/src-links-auto-impls.rs @@ -0,0 +1,12 @@ +#![crate_name = "foo"] + +// @has foo/struct.Unsized.html +// @has - '//h3[@id="impl-Sized"]/code' 'impl !Sized for Unsized' +// @!has - '//h3[@id="impl-Sized"]/a[@class="srclink"]' '[src]' +// @has - '//h3[@id="impl-Sync"]/code' 'impl Sync for Unsized' +// @!has - '//h3[@id="impl-Sync"]/a[@class="srclink"]' '[src]' +// @has - '//h3[@id="impl-Any"]/code' 'impl Any for T' +// @has - '//h3[@id="impl-Any"]/a[@class="srclink"]' '[src]' +pub struct Unsized { + data: [u8], +} diff --git a/src/test/ui/suggestions/auxiliary/issue-81839.rs b/src/test/ui/suggestions/auxiliary/issue-81839.rs new file mode 100644 index 0000000000000..5683c45adf26d --- /dev/null +++ b/src/test/ui/suggestions/auxiliary/issue-81839.rs @@ -0,0 +1,9 @@ +// edition:2018 + +pub struct Test {} + +impl Test { + pub async fn answer_str(&self, _s: &str) -> Test { + Test {} + } +} diff --git a/src/test/ui/suggestions/issue-81839.rs b/src/test/ui/suggestions/issue-81839.rs new file mode 100644 index 0000000000000..0b9b7aefe735d --- /dev/null +++ b/src/test/ui/suggestions/issue-81839.rs @@ -0,0 +1,17 @@ +// aux-build:issue-81839.rs +// edition:2018 + +extern crate issue_81839; + +async fn test(ans: &str, num: i32, cx: &issue_81839::Test) -> u32 { + match num { + 1 => { + cx.answer_str("hi"); + } + _ => cx.answer_str("hi"), //~ `match` arms have incompatible types + } + + 1 +} + +fn main() {} diff --git a/src/test/ui/suggestions/issue-81839.stderr b/src/test/ui/suggestions/issue-81839.stderr new file mode 100644 index 0000000000000..1a289d39e4467 --- /dev/null +++ b/src/test/ui/suggestions/issue-81839.stderr @@ -0,0 +1,27 @@ +error[E0308]: `match` arms have incompatible types + --> $DIR/issue-81839.rs:11:14 + | +LL | / match num { +LL | | 1 => { +LL | | cx.answer_str("hi"); + | | -------------------- + | | | | + | | | help: consider removing this semicolon + | | this is found to be of type `()` +LL | | } +LL | | _ => cx.answer_str("hi"), + | | ^^^^^^^^^^^^^^^^^^^ expected `()`, found opaque type +LL | | } + | |_____- `match` arms have incompatible types + | + ::: $DIR/auxiliary/issue-81839.rs:6:49 + | +LL | pub async fn answer_str(&self, _s: &str) -> Test { + | ---- the `Output` of this `async fn`'s found opaque type + | + = note: expected type `()` + found opaque type `impl Future` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr b/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr index e9803a78f94b3..fae0c498b440a 100644 --- a/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr +++ b/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr @@ -24,13 +24,10 @@ help: consider `await`ing on the `Future` | LL | false => async_dummy().await, | ^^^^^^ -help: consider removing this semicolon and boxing the expressions - | -LL | Box::new(async_dummy()) -LL | -LL | } -LL | false => Box::new(async_dummy()), +help: consider removing this semicolon | +LL | async_dummy() + | -- error[E0308]: `match` arms have incompatible types --> $DIR/match-prev-arm-needing-semi.rs:39:18