diff options
| author | bors <bors@rust-lang.org> | 2021-01-23 21:13:14 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-01-23 21:13:14 +0000 |
| commit | 1279b3b9232e4c44112d98f19cfa8846776d1fe8 (patch) | |
| tree | 2656f7f38ceb24cc242b3f814288924f8e9bc7ac | |
| parent | 4d0dd02ee07bddad9136f95c9f7846ebf3eb3fc5 (diff) | |
| parent | ebeb6b8b26f78c2c1a412a2e0e65e2e1f5ebc111 (diff) | |
| download | rust-1279b3b9232e4c44112d98f19cfa8846776d1fe8.tar.gz rust-1279b3b9232e4c44112d98f19cfa8846776d1fe8.zip | |
Auto merge of #81304 - jonas-schievink:rollup-d9kuugm, r=jonas-schievink
Rollup of 15 pull requests Successful merges: - #79841 (More clear documentation for NonNull<T>) - #81072 (PlaceRef::ty: use method call syntax) - #81130 (Edit rustc_middle::dep_graph module documentation) - #81170 (Avoid hash_slice in VecDeque's Hash implementation) - #81243 (mir: Improve size_of handling when arg is unsized) - #81245 (Update cargo) - #81249 (Lower closure prototype after its body.) - #81252 (Add more self-profile info to rustc_resolve) - #81275 (Fix <unknown> queries and add more timing info to render_html) - #81281 (Inline methods of Path and OsString) - #81283 (Note library tracking issue template in tracking issue template.) - #81285 (Remove special casing of rustdoc in rustc_lint) - #81288 (rustdoc: Fix visibility of trait and impl items) - #81298 (replace RefCell with Cell in FnCtxt) - #81301 (Fix small typo) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
37 files changed, 433 insertions, 111 deletions
diff --git a/.github/ISSUE_TEMPLATE/tracking_issue.md b/.github/ISSUE_TEMPLATE/tracking_issue.md index 24f43213897..00659605071 100644 --- a/.github/ISSUE_TEMPLATE/tracking_issue.md +++ b/.github/ISSUE_TEMPLATE/tracking_issue.md @@ -5,6 +5,8 @@ title: Tracking Issue for XXX labels: C-tracking-issue --- <!-- +NOTE: For library features, please use the "Library Tracking Issue" template instead. + Thank you for creating a tracking issue! 📜 Tracking issues are for tracking a feature from implementation to stabilisation. Make sure to include the relevant RFC for the feature if it has one. Otherwise provide a short summary of the diff --git a/Cargo.lock b/Cargo.lock index b2ae22b6abd..afcff1bfb06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -427,6 +427,7 @@ dependencies = [ "remove_dir_all", "serde_json", "tar", + "toml", "url 2.1.1", ] diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 31360158e2b..4d6afd2fe0d 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -776,10 +776,7 @@ impl<'hir> LoweringContext<'_, 'hir> { body: &Expr, fn_decl_span: Span, ) -> hir::ExprKind<'hir> { - // Lower outside new scope to preserve `is_in_loop_condition`. - let fn_decl = self.lower_fn_decl(decl, None, false, None); - - self.with_new_scopes(move |this| { + let (body_id, generator_option) = self.with_new_scopes(move |this| { let prev = this.current_item; this.current_item = Some(fn_decl_span); let mut generator_kind = None; @@ -791,8 +788,13 @@ impl<'hir> LoweringContext<'_, 'hir> { let generator_option = this.generator_movability_for_fn(&decl, fn_decl_span, generator_kind, movability); this.current_item = prev; - hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, generator_option) - }) + (body_id, generator_option) + }); + + // Lower outside new scope to preserve `is_in_loop_condition`. + let fn_decl = self.lower_fn_decl(decl, None, false, None); + + hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, generator_option) } fn generator_movability_for_fn( @@ -838,12 +840,8 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> hir::ExprKind<'hir> { let outer_decl = FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) }; - // We need to lower the declaration outside the new scope, because we - // have to conserve the state of being inside a loop condition for the - // closure argument types. - let fn_decl = self.lower_fn_decl(&outer_decl, None, false, None); - self.with_new_scopes(move |this| { + let body_id = self.with_new_scopes(|this| { // FIXME(cramertj): allow `async` non-`move` closures with arguments. if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() { struct_span_err!( @@ -874,8 +872,15 @@ impl<'hir> LoweringContext<'_, 'hir> { ); this.expr(fn_decl_span, async_body, ThinVec::new()) }); - hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, None) - }) + body_id + }); + + // We need to lower the declaration outside the new scope, because we + // have to conserve the state of being inside a loop condition for the + // closure argument types. + let fn_decl = self.lower_fn_decl(&outer_decl, None, false, None); + + hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, None) } /// Destructure the LHS of complex assignments. diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index b1e372afc65..fd0ff5b66e6 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -119,7 +119,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { ) ); if is_consume { - let base_ty = mir::PlaceRef::ty(&place_base, self.fx.mir, cx.tcx()); + let base_ty = place_base.ty(self.fx.mir, cx.tcx()); let base_ty = self.fx.monomorphize(base_ty); // ZSTs don't require any actual memory access. diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 958e4ebd078..66d9d1a1e0c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -506,7 +506,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn monomorphized_place_ty(&self, place_ref: mir::PlaceRef<'tcx>) -> Ty<'tcx> { let tcx = self.cx.tcx(); - let place_ty = mir::PlaceRef::ty(&place_ref, self.mir, tcx); + let place_ty = place_ref.ty(self.mir, tcx); self.monomorphize(place_ty.ty) } } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index ead2512d3b2..7031234e108 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -1017,13 +1017,6 @@ pub fn start_codegen<'tcx>( tcx.sess.time("assert_dep_graph", || rustc_incremental::assert_dep_graph(tcx)); tcx.sess.time("serialize_dep_graph", || rustc_incremental::save_dep_graph(tcx)); - // We assume that no queries are run past here. If there are new queries - // after this point, they'll show up as "<unknown>" in self-profiling data. - { - let _prof_timer = tcx.prof.generic_activity("self_profile_alloc_query_strings"); - tcx.alloc_self_profile_query_strings(); - } - info!("Post-codegen\n{:?}", tcx.debug_stats()); if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) { diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 9c49f926d41..ac6b6d03115 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -417,9 +417,19 @@ impl Compiler { let queries = Queries::new(&self); let ret = f(&queries); - if self.session().opts.debugging_opts.query_stats { - if let Ok(gcx) = queries.global_ctxt() { - gcx.peek_mut().print_stats(); + // NOTE: intentionally does not compute the global context if it hasn't been built yet, + // since that likely means there was a parse error. + if let Some(Ok(gcx)) = &mut *queries.global_ctxt.result.borrow_mut() { + // We assume that no queries are run past here. If there are new queries + // after this point, they'll show up as "<unknown>" in self-profiling data. + { + let _prof_timer = + queries.session().prof.generic_activity("self_profile_alloc_query_strings"); + gcx.enter(|tcx| tcx.alloc_self_profile_query_strings()); + } + + if self.session().opts.debugging_opts.query_stats { + gcx.print_stats(); } } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 08c147ec3ac..e36af234936 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -379,17 +379,9 @@ pub fn check_ast_crate<T: EarlyLintPass>( // All of the buffered lints should have been emitted at this point. // If not, that means that we somehow buffered a lint for a node id // that was not lint-checked (perhaps it doesn't exist?). This is a bug. - // - // Rustdoc runs everybody-loops before the early lints and removes - // function bodies, so it's totally possible for linted - // node ids to not exist (e.g., macros defined within functions for the - // unused_macro lint) anymore. So we only run this check - // when we're not in rustdoc mode. (see issue #47639) - if !sess.opts.actually_rustdoc { - for (_id, lints) in buffered.map { - for early_lint in lints { - sess.delay_span_bug(early_lint.span, "failed to process buffered lint here"); - } + for (_id, lints) in buffered.map { + for early_lint in lints { + sess.delay_span_bug(early_lint.span, "failed to process buffered lint here"); } } } diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 62f2874af04..1cb75757379 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -1,16 +1,17 @@ -//! This module defines the `DepNode` type which the compiler uses to represent -//! nodes in the dependency graph. +//! Nodes in the dependency graph. //! -//! A `DepNode` consists of a `DepKind` (which -//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc) -//! and a `Fingerprint`, a 128-bit hash value the exact meaning of which +//! A node in the [dependency graph] is represented by a [`DepNode`]. +//! A `DepNode` consists of a [`DepKind`] (which +//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc.) +//! and a [`Fingerprint`], a 128-bit hash value, the exact meaning of which //! depends on the node's `DepKind`. Together, the kind and the fingerprint //! fully identify a dependency node, even across multiple compilation sessions. //! In other words, the value of the fingerprint does not depend on anything //! that is specific to a given compilation session, like an unpredictable -//! interning key (e.g., NodeId, DefId, Symbol) or the numeric value of a +//! interning key (e.g., `NodeId`, `DefId`, `Symbol`) or the numeric value of a //! pointer. The concept behind this could be compared to how git commit hashes -//! uniquely identify a given commit and has a few advantages: +//! uniquely identify a given commit. The fingerprinting approach has +//! a few advantages: //! //! * A `DepNode` can simply be serialized to disk and loaded in another session //! without the need to do any "rebasing" (like we have to do for Spans and @@ -51,6 +52,8 @@ //! than a zeroed out fingerprint. More generally speaking, it relieves the //! user of the `DepNode` API of having to know how to compute the expected //! fingerprint for a given set of node parameters. +//! +//! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html use crate::ty::TyCtxt; diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 397d2ffd565..cf931ece712 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -127,6 +127,8 @@ pub enum InvalidProgramInfo<'tcx> { Layout(layout::LayoutError<'tcx>), /// An invalid transmute happened. TransmuteSizeDiff(Ty<'tcx>, Ty<'tcx>), + /// SizeOf of unsized type was requested. + SizeOfUnsizedType(Ty<'tcx>), } impl fmt::Display for InvalidProgramInfo<'_> { @@ -144,6 +146,7 @@ impl fmt::Display for InvalidProgramInfo<'_> { "transmuting `{}` to `{}` is not possible, because these types do not have the same size", from_ty, to_ty ), + SizeOfUnsizedType(ty) => write!(f, "size_of called on unsized type `{}`", ty), } } } diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs index 8f41bfae2fd..cd16a88e5fc 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs @@ -289,7 +289,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); } - let ty = PlaceRef::ty(&used_place, self.body, self.infcx.tcx).ty; + let ty = used_place.ty(self.body, self.infcx.tcx).ty; let needs_note = match ty.kind() { ty::Closure(id, _) => { let tables = self.infcx.tcx.typeck(id.expect_local()); @@ -728,6 +728,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // Define a small closure that we can use to check if the type of a place // is a union. let union_ty = |place_base| { + // Need to use fn call syntax `PlaceRef::ty` to determine the type of `place_base`; + // using a type annotation in the closure argument instead leads to a lifetime error. let ty = PlaceRef::ty(&place_base, self.body, self.infcx.tcx).ty; ty.ty_adt_def().filter(|adt| adt.is_union()).map(|_| ty) }; diff --git a/compiler/rustc_mir/src/borrow_check/mod.rs b/compiler/rustc_mir/src/borrow_check/mod.rs index 006e05072a7..7c7edfdb5fb 100644 --- a/compiler/rustc_mir/src/borrow_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/mod.rs @@ -1743,7 +1743,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let Some((place_base, ProjectionElem::Subslice { from, to, from_end: false })) = place_span.0.last_projection() { - let place_ty = PlaceRef::ty(&place_base, self.body(), self.infcx.tcx); + let place_ty = place_base.ty(self.body(), self.infcx.tcx); if let ty::Array(..) = place_ty.ty.kind() { self.check_if_subslice_element_is_moved( location, @@ -1854,7 +1854,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // assigning to `P.f` requires `P` itself // be already initialized let tcx = self.infcx.tcx; - let base_ty = PlaceRef::ty(&place_base, self.body(), tcx).ty; + let base_ty = place_base.ty(self.body(), tcx).ty; match base_ty.kind() { ty::Adt(def, _) if def.has_dtor(tcx) => { self.check_if_path_or_subpath_is_moved( @@ -1951,7 +1951,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // no move out from an earlier location) then this is an attempt at initialization // of the union - we should error in that case. let tcx = this.infcx.tcx; - if let ty::Adt(def, _) = PlaceRef::ty(&base, this.body(), tcx).ty.kind() { + if let ty::Adt(def, _) = base.ty(this.body(), tcx).ty.kind() { if def.is_union() { if this.move_data.path_map[mpi].iter().any(|moi| { this.move_data.moves[*moi].source.is_predecessor_of(location, this.body) @@ -2173,7 +2173,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { Some((place_base, elem)) => { match elem { ProjectionElem::Deref => { - let base_ty = PlaceRef::ty(&place_base, self.body(), self.infcx.tcx).ty; + let base_ty = place_base.ty(self.body(), self.infcx.tcx).ty; // Check the kind of deref to decide match base_ty.kind() { diff --git a/compiler/rustc_mir/src/borrow_check/prefixes.rs b/compiler/rustc_mir/src/borrow_check/prefixes.rs index cf04c55eb68..bdf2becb711 100644 --- a/compiler/rustc_mir/src/borrow_check/prefixes.rs +++ b/compiler/rustc_mir/src/borrow_check/prefixes.rs @@ -117,7 +117,7 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { // derefs, except we stop at the deref of a shared // reference. - let ty = PlaceRef::ty(&cursor_base, self.body, self.tcx).ty; + let ty = cursor_base.ty(self.body, self.tcx).ty; match ty.kind() { ty::RawPtr(_) | ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Not) => { // don't continue traversing over derefs of raw pointers or shared diff --git a/compiler/rustc_mir/src/interpret/step.rs b/compiler/rustc_mir/src/interpret/step.rs index 6d447acbecf..fbc72ad8adc 100644 --- a/compiler/rustc_mir/src/interpret/step.rs +++ b/compiler/rustc_mir/src/interpret/step.rs @@ -270,6 +270,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.frame().current_span(), &format!("SizeOf nullary MIR operator called for unsized type {}", ty), ); + throw_inval!(SizeOfUnsizedType(ty)); } self.write_scalar(Scalar::from_machine_usize(layout.size.bytes(), self), dest)?; } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index d293899dc0c..2b4a1d9e3fa 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1465,16 +1465,14 @@ impl<'a> Resolver<'a> { /// Entry point to crate resolution. pub fn resolve_crate(&mut self, krate: &Crate) { - let _prof_timer = self.session.prof.generic_activity("resolve_crate"); - - ImportResolver { r: self }.finalize_imports(); - self.finalize_macro_resolutions(); - - self.late_resolve_crate(krate); - - self.check_unused(krate); - self.report_errors(krate); - self.crate_loader.postprocess(krate); + self.session.time("resolve_crate", || { + self.session.time("finalize_imports", || ImportResolver { r: self }.finalize_imports()); + self.session.time("finalize_macro_resolutions", || self.finalize_macro_resolutions()); + self.session.time("late_resolve_crate", || self.late_resolve_crate(krate)); + self.session.time("resolve_check_unused", || self.check_unused(krate)); + self.session.time("resolve_report_errors", || self.report_errors(krate)); + self.session.time("resolve_postprocess", || self.crate_loader.postprocess(krate)); + }); } pub fn traits_in_scope( diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 8e339eb26b2..ab3c26fac83 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -66,7 +66,7 @@ pub(super) fn check_fn<'a, 'tcx>( // Create the function context. This is either derived from scratch or, // in the case of closures, based on the outer context. let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id); - *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id); + fcx.ps.set(UnsafetyState::function(fn_sig.unsafety, fn_id)); let tcx = fcx.tcx; let sess = tcx.sess; diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 34ad8ec0898..b2395b7bb25 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -1472,22 +1472,22 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { fn_output = Some(&fn_decl.output); // `impl Trait` return type } } - if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.borrow().as_ref(), fn_output) { - self.add_impl_trait_explanation(&mut err, cause, fcx, expected, *sp, fn_output); + if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.get(), fn_output) { + self.add_impl_trait_explanation(&mut err, cause, fcx, expected, sp, fn_output); } - if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() { + if let Some(sp) = fcx.ret_coercion_span.get() { // If the closure has an explicit return type annotation, // then a type error may occur at the first return expression we // see in the closure (if it conflicts with the declared // return type). Skip adding a note in this case, since it // would be incorrect. - if !err.span.primary_spans().iter().any(|span| span == sp) { + if !err.span.primary_spans().iter().any(|&span| span == sp) { let hir = fcx.tcx.hir(); let body_owner = hir.body_owned_by(hir.enclosing_body_owner(fcx.body_id)); if fcx.tcx.is_closure(hir.body_owner_def_id(body_owner).to_def_id()) { err.span_note( - *sp, + sp, &format!( "return type inferred to be `{}` here", fcx.resolve_vars_if_possible(expected) diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 8f463af73c4..e37b4ff742b 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -680,14 +680,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.ret_coercion.is_none() { self.tcx.sess.emit_err(ReturnStmtOutsideOfFnBody { span: expr.span }); } else if let Some(ref e) = expr_opt { - if self.ret_coercion_span.borrow().is_none() { - *self.ret_coercion_span.borrow_mut() = Some(e.span); + if self.ret_coercion_span.get().is_none() { + self.ret_coercion_span.set(Some(e.span)); } self.check_return_expr(e); } else { let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut(); - if self.ret_coercion_span.borrow().is_none() { - *self.ret_coercion_span.borrow_mut() = Some(expr.span); + if self.ret_coercion_span.get().is_none() { + self.ret_coercion_span.set(Some(expr.span)); } let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression); if let Some((fn_decl, _)) = self.get_fn_decl(expr.hir_id) { diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 6df9e3ab7db..fb6f9c03352 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -23,7 +23,6 @@ use rustc_span::{self, MultiSpan, Span}; use rustc_trait_selection::traits::{self, ObligationCauseCode, StatementAsExpression}; use crate::structured_errors::StructuredDiagnostic; -use std::mem::replace; use std::slice; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -589,11 +588,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { blk: &'tcx hir::Block<'tcx>, expected: Expectation<'tcx>, ) -> Ty<'tcx> { - let prev = { - let mut fcx_ps = self.ps.borrow_mut(); - let unsafety_state = fcx_ps.recurse(blk); - replace(&mut *fcx_ps, unsafety_state) - }; + let prev = self.ps.replace(self.ps.get().recurse(blk)); // In some cases, blocks have just one exit, but other blocks // can be targeted by multiple breaks. This can happen both @@ -709,7 +704,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.write_ty(blk.hir_id, ty); - *self.ps.borrow_mut() = prev; + self.ps.set(prev); ty } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs index 6d09043bd50..e9223f700dc 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs @@ -66,11 +66,11 @@ pub struct FnCtxt<'a, 'tcx> { pub(super) in_tail_expr: bool, /// First span of a return site that we find. Used in error messages. - pub(super) ret_coercion_span: RefCell<Option<Span>>, + pub(super) ret_coercion_span: Cell<Option<Span>>, pub(super) resume_yield_tys: Option<(Ty<'tcx>, Ty<'tcx>)>, - pub(super) ps: RefCell<UnsafetyState>, + pub(super) ps: Cell<UnsafetyState>, /// Whether the last checked node generates a divergence (e.g., /// `return` will set this to `Always`). In general, when entering @@ -127,9 +127,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ret_coercion_impl_trait: None, ret_type_span: None, in_tail_expr: false, - ret_coercion_span: RefCell::new(None), + ret_coercion_span: Cell::new(None), resume_yield_tys: None, - ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)), + 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 { diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index 52276ed4bee..c8c6fa12fae 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -184,14 +184,14 @@ impl UnsafetyState { UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true } } - pub fn recurse(&mut self, blk: &hir::Block<'_>) -> UnsafetyState { + pub fn recurse(self, blk: &hir::Block<'_>) -> UnsafetyState { use hir::BlockCheckMode; match self.unsafety { // If this unsafe, then if the outer function was already marked as // unsafe we shouldn't attribute the unsafe'ness to the block. This // way the block can be warned about instead of ignoring this // extraneous block (functions are never warned about). - hir::Unsafety::Unsafe if self.from_fn => *self, + hir::Unsafety::Unsafe if self.from_fn => self, unsafety => { let (unsafety, def, count) = match blk.rules { diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 5b61e8911a5..6f9133e2811 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2646,9 +2646,13 @@ impl<A: Ord> Ord for VecDeque<A> { impl<A: Hash> Hash for VecDeque<A> { fn hash<H: Hasher>(&self, state: &mut H) { self.len().hash(state); - let (a, b) = self.as_slices(); - Hash::hash_slice(a, state); - Hash::hash_slice(b, state); + // It's not possible to use Hash::hash_slice on slices + // returned by as_slices method as their length can vary + // in otherwise identical deques. + // + // Hasher only guarantees equivalence for the exact same + // set of calls to its methods. + self.iter().for_each(|elem| elem.hash(state)); } } diff --git a/library/alloc/src/collections/vec_deque/tests.rs b/library/alloc/src/collections/vec_deque/tests.rs index 27dc59ae644..87e06fa394d 100644 --- a/library/alloc/src/collections/vec_deque/tests.rs +++ b/library/alloc/src/collections/vec_deque/tests.rs @@ -599,3 +599,43 @@ fn issue_53529() { assert_eq!(*a, 2); } } + +#[test] +fn issue_80303() { + use core::iter; + use core::num::Wrapping; + + // This is a valid, albeit rather bad hash function implementation. + struct SimpleHasher(Wrapping<u64>); + + impl Hasher for SimpleHasher { + fn finish(&self) -> u64 { + self.0.0 + } + + fn write(&mut self, bytes: &[u8]) { + // This particular implementation hashes value 24 in addition to bytes. + // Such an implementation is valid as Hasher only guarantees equivalence + // for the exact same set of calls to its methods. + for &v in iter::once(&24).chain(bytes) { + self.0 = Wrapping(31) * self.0 + Wrapping(u64::from(v)); + } + } + } + + fn hash_code(value: impl Hash) -> u64 { + let mut hasher = SimpleHasher(Wrapping(1)); + value.hash(&mut hasher); + hasher.finish() + } + + // This creates two deques for which values returned by as_slices + // method differ. + let vda: VecDeque<u8> = (0..10).collect(); + let mut vdb = VecDeque::with_capacity(10); + vdb.extend(5..10); + (0..5).rev().for_each(|elem| vdb.push_front(elem)); + assert_ne!(vda.as_slices(), vdb.as_slices()); + assert_eq!(vda, vdb); + assert_eq!(hash_code(vda), hash_code(vdb)); +} diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs index 039112e9f34..91c61f814e1 100644 --- a/library/core/src/num/dec2flt/mod.rs +++ b/library/core/src/num/dec2flt/mod.rs @@ -3,7 +3,7 @@ //! # Problem statement //! //! We are given a decimal string such as `12.34e56`. This string consists of integral (`12`), -//! fractional (`45`), and exponent (`56`) parts. All parts are optional and interpreted as zero +//! fractional (`34`), and exponent (`56`) parts. All parts are optional and interpreted as zero //! when missing. //! //! We seek the IEEE 754 floating point number that is closest to the exact value of the decimal diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index d849008b880..e45fefc7ed7 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -19,12 +19,19 @@ use crate::slice::{self, SliceIndex}; /// as a discriminant -- `Option<NonNull<T>>` has the same size as `*mut T`. /// However the pointer may still dangle if it isn't dereferenced. /// -/// Unlike `*mut T`, `NonNull<T>` is covariant over `T`. If this is incorrect -/// for your use case, you should include some [`PhantomData`] in your type to -/// provide invariance, such as `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`. -/// Usually this won't be necessary; covariance is correct for most safe abstractions, -/// such as `Box`, `Rc`, `Arc`, `Vec`, and `LinkedList`. This is the case because they -/// provide a public API that follows the normal shared XOR mutable rules of Rust. +/// Unlike `*mut T`, `NonNull<T>` was chosen to be covariant over `T`. This makes it +/// possible to use `NonNull<T>` when building covariant types, but introduces the +/// risk of unsoundness if used in a type that shouldn't actually be covariant. +/// (The opposite choice was made for `*mut T` even though technically the unsoundness +/// could only be caused by calling unsafe functions.) +/// +/// Covariance is correct for most safe abstractions, such as `Box`, `Rc`, `Arc`, `Vec`, +/// and `LinkedList`. This is the case because they provide a public API that follows the +/// normal shared XOR mutable rules of Rust. +/// +/// If your type cannot safely be covariant, you must ensure it contains some +/// additional field to provide invariance. Often this field will be a [`PhantomData`] +/// type like `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`. /// /// Notice that `NonNull<T>` has a `From` instance for `&T`. However, this does /// not change the fact that mutating through a (pointer derived from a) shared diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 2eef4d58507..32f0f8a52f8 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -111,6 +111,7 @@ impl OsString { /// let os_string = OsString::new(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn new() -> OsString { OsString { inner: Buf::from_string(String::new()) } } @@ -127,6 +128,7 @@ impl OsString { /// assert_eq!(os_string.as_os_str(), os_str); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn as_os_str(&self) -> &OsStr { self } @@ -145,6 +147,7 @@ impl OsString { /// assert_eq!(string, Ok(String::from("foo"))); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn into_string(self) -> Result<String, OsString> { self.inner.into_string().map_err(|buf| OsString { inner: buf }) } @@ -163,6 +166,7 @@ impl OsString { /// assert_eq!(&os_string, "foobar"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn push<T: AsRef<OsStr>>(&mut self, s: T) { self.inner.push_slice(&s.as_ref().inner) } @@ -189,6 +193,7 @@ impl OsString { /// assert_eq!(capacity, os_string.capacity()); /// ``` #[stable(feature = "osstring_simple_functions", since = "1.9.0")] + #[inline] pub fn with_capacity(capacity: usize) -> OsString { OsString { inner: Buf::with_capacity(capacity) } } @@ -207,6 +212,7 @@ impl OsString { /// assert_eq!(&os_string, ""); /// ``` #[stable(feature = "osstring_simple_functions", since = "1.9.0")] + #[inline] pub fn clear(&mut self) { self.inner.clear() } @@ -224,6 +230,7 @@ impl OsString { /// assert!(os_string.capacity() >= 10); /// ``` #[stable(feature = "osstring_simple_functions", since = "1.9.0")] + #[inline] pub fn capacity(&self) -> usize { self.inner.capacity() } @@ -243,6 +250,7 @@ impl OsString { /// assert!(s.capacity() >= 10); /// ``` #[stable(feature = "osstring_simple_functions", since = "1.9.0")] + #[inline] pub fn reserve(&mut self, additional: usize) { self.inner.reserve(additional) } @@ -265,6 +273,7 @@ impl OsString { /// assert!(s.capacity() >= 10); /// ``` #[stable(feature = "osstring_simple_functions", since = "1.9.0")] + #[inline] pub fn reserve_exact(&mut self, additional: usize) { self.inner.reserve_exact(additional) } @@ -285,6 +294,7 @@ impl OsString { /// assert_eq!(3, s.capacity()); /// ``` #[stable(feature = "osstring_shrink_to_fit", since = "1.19.0")] + #[inline] pub fn shrink_to_fit(&mut self) { self.inner.shrink_to_fit() } @@ -342,6 +352,7 @@ impl From<String> for OsString { /// Converts a [`String`] into a [`OsString`]. /// /// The conversion copies the data, and includes an allocation on the heap. + #[inline] fn from(s: String) -> OsString { OsString { inner: Buf::from_string(s) } } @@ -408,6 +419,7 @@ impl fmt::Debug for OsString { #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for OsString { + #[inline] fn eq(&self, other: &OsString) -> bool { &**self == &**other } @@ -415,6 +427,7 @@ impl PartialEq for OsString { #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq<str> for OsString { + #[inline] fn eq(&self, other: &str) -> bool { &**self == other } @@ -422,6 +435,7 @@ impl PartialEq<str> for OsString { #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq<OsString> for str { + #[inline] fn eq(&self, other: &OsString) -> bool { &**other == self } @@ -429,6 +443,7 @@ impl PartialEq<OsString> for str { #[stable(feature = "os_str_str_ref_eq", since = "1.29.0")] impl PartialEq<&str> for OsString { + #[inline] fn eq(&self, other: &&str) -> bool { **self == **other } @@ -436,6 +451,7 @@ impl PartialEq<&str> for OsString { #[stable(feature = "os_str_str_ref_eq", since = "1.29.0")] impl<'a> PartialEq<OsString> for &'a str { + #[inline] fn eq(&self, other: &OsString) -> bool { **other == **self } @@ -539,6 +555,7 @@ impl OsStr { /// assert_eq!(os_str.to_str(), Some("foo")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn to_str(&self) -> Option<&str> { self.inner.to_str() } @@ -589,6 +606,7 @@ impl OsStr { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn to_string_lossy(&self) -> Cow<'_, str> { self.inner.to_string_lossy() } @@ -605,6 +623,7 @@ impl OsStr { /// assert_eq!(os_string, OsString::from("foo")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn to_os_string(&self) -> OsString { OsString { inner: self.inner.to_owned() } } @@ -655,6 +674,7 @@ impl OsStr { /// ``` #[doc(alias = "length")] #[stable(feature = "osstring_simple_functions", since = "1.9.0")] + #[inline] pub fn len(&self) -> usize { self.inner.inner.len() } @@ -696,6 +716,7 @@ impl OsStr { /// assert_eq!("grÜße, jÜrgen ❤", s); /// ``` #[unstable(feature = "osstring_ascii", issue = "70516")] + #[inline] pub fn make_ascii_lowercase(&mut self) { self.inner.make_ascii_lowercase() } @@ -721,6 +742,7 @@ impl OsStr { /// assert_eq!("GRüßE, JüRGEN ❤", s); /// ``` #[unstable(feature = "osstring_ascii", issue = "70516")] + #[inline] pub fn make_ascii_uppercase(&mut self) { self.inner.make_ascii_uppercase() } @@ -784,6 +806,7 @@ impl OsStr { /// assert!(!non_ascii.is_ascii()); /// ``` #[unstable(feature = "osstring_ascii", issue = "70516")] + #[inline] pub fn is_ascii(&self) -> bool { self.inner.is_ascii() } @@ -811,6 +834,7 @@ impl OsStr { #[stable(feature = "box_from_os_str", since = "1.17.0")] impl From<&OsStr> for Box<OsStr> { + #[inline] fn from(s: &OsStr) -> Box<OsStr> { let rw = Box::into_raw(s.inner.into_box()) as *mut OsStr; unsafe { Box::from_raw(rw) } @@ -832,6 +856,7 @@ impl From<Cow<'_, OsStr>> for Box<OsStr> { impl From<Box<OsStr>> for OsString { /// Converts a [`Box`]`<`[`OsStr`]`>` into a `OsString` without copying or /// allocating. + #[inline] fn from(boxed: Box<OsStr>) -> OsString { boxed.into_os_string() } @@ -840,6 +865,7 @@ impl From<Box<OsStr>> for OsString { #[stable(feature = "box_from_os_string", since = "1.20.0")] impl From<OsString> for Box<OsStr> { /// Converts a [`OsString`] into a [`Box`]`<OsStr>` without copying or allocating. + #[inline] fn from(s: OsString) -> Box<OsStr> { s.into_boxed_os_str() } @@ -925,6 +951,7 @@ impl<'a> From<Cow<'a, OsStr>> for OsString { #[stable(feature = "box_default_extra", since = "1.17.0")] impl Default for Box<OsStr> { + #[inline] fn default() -> Box<OsStr> { let rw = Box::into_raw(Slice::empty_box()) as *mut OsStr; unsafe { Box::from_raw(rw) } @@ -1075,6 +1102,7 @@ impl OsStr { #[stable(feature = "rust1", since = "1.0.0")] impl Borrow<OsStr> for OsString { + #[inline] fn borrow(&self) -> &OsStr { &self[..] } @@ -1083,9 +1111,11 @@ impl Borrow<OsStr> for OsString { #[stable(feature = "rust1", since = "1.0.0")] impl ToOwned for OsStr { type Owned = OsString; + #[inline] fn to_owned(&self) -> OsString { self.to_os_string() } + #[inline] fn clone_into(&self, target: &mut OsString) { self.inner.clone_into(&mut target.inner) } @@ -1093,6 +1123,7 @@ impl ToOwned for OsStr { #[stable(feature = "rust1", since = "1.0.0")] impl AsRef<OsStr> for OsStr { + #[inline] fn as_ref(&self) -> &OsStr { self } @@ -1123,12 +1154,14 @@ impl AsRef<OsStr> for String { } impl FromInner<Buf> for OsString { + #[inline] fn from_inner(buf: Buf) -> OsString { OsString { inner: buf } } } impl IntoInner<Buf> for OsString { + #[inline] fn into_inner(self) -> Buf { self.inner } @@ -1145,6 +1178,7 @@ impl AsInner<Slice> for OsStr { impl FromStr for OsString { type Err = core::convert::Infallible; + #[inline] fn from_str(s: &str) -> Result<Self, Self::Err> { Ok(OsString::from(s)) } diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 243761e3897..1889e549338 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -401,12 +401,14 @@ impl<'a> PrefixComponent<'a> { /// See [`Prefix`]'s documentation for more information on the different /// kinds of prefixes. #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn kind(&self) -> Prefix<'a> { self.parsed } /// Returns the raw [`OsStr`] slice for this prefix. #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn as_os_str(&self) -> &'a OsStr { self.raw } @@ -414,6 +416,7 @@ impl<'a> PrefixComponent<'a> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a> cmp::PartialEq for PrefixComponent<'a> { + #[inline] fn eq(&self, other: &PrefixComponent<'a>) -> bool { cmp::PartialEq::eq(&self.parsed, &other.parsed) } @@ -421,6 +424,7 @@ impl<'a> cmp::PartialEq for PrefixComponent<'a> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a> cmp::PartialOrd for PrefixComponent<'a> { + #[inline] fn partial_cmp(&self, other: &PrefixComponent<'a>) -> Option<cmp::Ordering> { cmp::PartialOrd::partial_cmp(&self.parsed, &other.parsed) } @@ -428,6 +432,7 @@ impl<'a> cmp::PartialOrd for PrefixComponent<'a> { #[stable(feature = "rust1", since = "1.0.0")] impl cmp::Ord for PrefixComponent<'_> { + #[inline] fn cmp(&self, other: &Self) -> cmp::Ordering { cmp::Ord::cmp(&self.parsed, &other.parsed) } @@ -522,6 +527,7 @@ impl<'a> Component<'a> { #[stable(feature = "rust1", since = "1.0.0")] impl AsRef<OsStr> for Component<'_> { + #[inline] fn as_ref(&self) -> &OsStr { self.as_os_str() } @@ -529,6 +535,7 @@ impl AsRef<OsStr> for Component<'_> { #[stable(feature = "path_component_asref", since = "1.25.0")] impl AsRef<Path> for Component<'_> { + #[inline] fn as_ref(&self) -> &Path { self.as_os_str().as_ref() } @@ -750,6 +757,7 @@ impl<'a> Components<'a> { #[stable(feature = "rust1", since = "1.0.0")] impl AsRef<Path> for Components<'_> { + #[inline] fn as_ref(&self) -> &Path { self.as_path() } @@ -757,6 +765,7 @@ impl AsRef<Path> for Components<'_> { #[stable(feature = "rust1", since = "1.0.0")] impl AsRef<OsStr> for Components<'_> { + #[inline] fn as_ref(&self) -> &OsStr { self.as_path().as_os_str() } @@ -792,6 +801,7 @@ impl<'a> Iter<'a> { /// assert_eq!(Path::new("foo/bar.txt"), iter.as_path()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn as_path(&self) -> &'a Path { self.inner.as_path() } @@ -799,6 +809,7 @@ impl<'a> Iter<'a> { #[stable(feature = "rust1", since = "1.0.0")] impl AsRef<Path> for Iter<'_> { + #[inline] fn as_ref(&self) -> &Path { self.as_path() } @@ -806,6 +817,7 @@ impl AsRef<Path> for Iter<'_> { #[stable(feature = "rust1", since = "1.0.0")] impl AsRef<OsStr> for Iter<'_> { + #[inline] fn as_ref(&self) -> &OsStr { self.as_path().as_os_str() } @@ -815,6 +827,7 @@ impl AsRef<OsStr> for Iter<'_> { impl<'a> Iterator for Iter<'a> { type Item = &'a OsStr; + #[inline] fn next(&mut self) -> Option<&'a OsStr> { self.inner.next().map(Component::as_os_str) } @@ -822,6 +835,7 @@ impl<'a> Iterator for Iter<'a> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a> DoubleEndedIterator for Iter<'a> { + #[inline] fn next_back(&mut self) -> Option<&'a OsStr> { self.inner.next_back().map(Component::as_os_str) } @@ -935,6 +949,7 @@ impl FusedIterator for Components<'_> {} #[stable(feature = "rust1", since = "1.0.0")] impl<'a> cmp::PartialEq for Components<'a> { + #[inline] fn eq(&self, other: &Components<'a>) -> bool { Iterator::eq(self.clone(), other.clone()) } @@ -945,6 +960,7 @@ impl cmp::Eq for Components<'_> {} #[stable(feature = "rust1", since = "1.0.0")] impl<'a> cmp::PartialOrd for Components<'a> { + #[inline] fn partial_cmp(&self, other: &Components<'a>) -> Option<cmp::Ordering> { Iterator::partial_cmp(self.clone(), other.clone()) } @@ -952,6 +968,7 @@ impl<'a> cmp::PartialOrd for Components<'a> { #[stable(feature = "rust1", since = "1.0.0")] impl cmp::Ord for Components<'_> { + #[inline] fn cmp(&self, other: &Self) -> cmp::Ordering { Iterator::cmp(self.clone(), other.clone()) } @@ -985,6 +1002,7 @@ pub struct Ancestors<'a> { impl<'a> Iterator for Ancestors<'a> { type Item = &'a Path; + #[inline] fn next(&mut self) -> Option<Self::Item> { let next = self.next; self.next = next.and_then(Path::parent); @@ -1060,6 +1078,7 @@ pub struct PathBuf { } impl PathBuf { + #[inline] fn as_mut_vec(&mut self) -> &mut Vec<u8> { unsafe { &mut *(self as *mut PathBuf as *mut Vec<u8>) } } @@ -1074,6 +1093,7 @@ impl PathBuf { /// let path = PathBuf::new(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn new() -> PathBuf { PathBuf { inner: OsString::new() } } @@ -1097,6 +1117,7 @@ impl PathBuf { /// /// [`with_capacity`]: OsString::with_capacity #[stable(feature = "path_buf_capacity", since = "1.44.0")] + #[inline] pub fn with_capacity(capacity: usize) -> PathBuf { PathBuf { inner: OsString::with_capacity(capacity) } } @@ -1112,6 +1133,7 @@ impl PathBuf { /// assert_eq!(Path::new("/test"), p.as_path()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn as_path(&self) -> &Path { self } @@ -1315,12 +1337,14 @@ impl PathBuf { /// let os_str = p.into_os_string(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn into_os_string(self) -> OsString { self.inner } /// Converts this `PathBuf` into a [boxed](Box) [`Path`]. #[stable(feature = "into_boxed_path", since = "1.20.0")] + #[inline] pub fn into_boxed_path(self) -> Box<Path> { let rw = Box::into_raw(self.inner.into_boxed_os_str()) as *mut Path; unsafe { Box::from_raw(rw) } @@ -1330,6 +1354,7 @@ impl PathBuf { /// /// [`capacity`]: OsString::capacity #[stable(feature = "path_buf_capacity", since = "1.44.0")] + #[inline] pub fn capacity(&self) -> usize { self.inner.capacity() } @@ -1338,6 +1363,7 @@ impl PathBuf { /// /// [`clear`]: OsString::clear #[stable(feature = "path_buf_capacity", since = "1.44.0")] + #[inline] pub fn clear(&mut self) { self.inner.clear() } @@ -1346,6 +1372,7 @@ impl PathBuf { /// /// [`reserve`]: OsString::reserve #[stable(feature = "path_buf_capacity", since = "1.44.0")] + #[inline] pub fn reserve(&mut self, additional: usize) { self.inner.reserve(additional) } @@ -1354,6 +1381,7 @@ impl PathBuf { /// /// [`reserve_exact`]: OsString::reserve_exact #[stable(feature = "path_buf_capacity", since = "1.44.0")] + #[inline] pub fn reserve_exact(&mut self, additional: usize) { self.inner.reserve_exact(additional) } @@ -1362,6 +1390,7 @@ impl PathBuf { /// /// [`shrink_to_fit`]: OsString::shrink_to_fit #[stable(feature = "path_buf_capacity", since = "1.44.0")] + #[inline] pub fn shrink_to_fit(&mut self) { self.inner.shrink_to_fit() } @@ -1370,6 +1399,7 @@ impl PathBuf { /// /// [`shrink_to`]: OsString::shrink_to #[unstable(feature = "shrink_to", issue = "56431")] + #[inline] pub fn shrink_to(&mut self, min_capacity: usize) { self.inner.shrink_to(min_capacity) } @@ -1400,6 +1430,7 @@ impl From<Box<Path>> for PathBuf { /// Converts a `Box<Path>` into a `PathBuf` /// /// This conversion does not allocate or copy memory. + #[inline] fn from(boxed: Box<Path>) -> PathBuf { boxed.into_path_buf() } @@ -1411,6 +1442,7 @@ impl From<PathBuf> for Box<Path> { /// /// This conversion currently should not allocate memory, /// but this behavior is not guaranteed on all platforms or in all future versions. + #[inline] fn from(p: PathBuf) -> Box<Path> { p.into_boxed_path() } @@ -1426,6 +1458,7 @@ impl Clone for Box<Path> { #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized + AsRef<OsStr>> From<&T> for PathBuf { + #[inline] fn from(s: &T) -> PathBuf { PathBuf::from(s.as_ref().to_os_string()) } @@ -1447,6 +1480,7 @@ impl From<PathBuf> for OsString { /// Converts a `PathBuf` into a `OsString` /// /// This conversion does not allocate or copy memory. + #[inline] fn from(path_buf: PathBuf) -> OsString { path_buf.inner } @@ -1457,6 +1491,7 @@ impl From<String> for PathBuf { /// Converts a `String` into a `PathBuf` /// /// This conversion does not allocate or copy memory. + #[inline] fn from(s: String) -> PathBuf { PathBuf::from(OsString::from(s)) } @@ -1466,6 +1501,7 @@ impl From<String> for PathBuf { impl FromStr for PathBuf { type Err = core::convert::Infallible; + #[inline] fn from_str(s: &str) -> Result<Self, Self::Err> { Ok(PathBuf::from(s)) } @@ -1510,6 +1546,7 @@ impl ops::Deref for PathBuf { #[stable(feature = "rust1", since = "1.0.0")] impl Borrow<Path> for PathBuf { + #[inline] fn borrow(&self) -> &Path { self.deref() } @@ -1517,6 +1554,7 @@ impl Borrow<Path> for PathBuf { #[stable(feature = "default_for_pathbuf", since = "1.17.0")] impl Default for PathBuf { + #[inline] fn default() -> Self { PathBuf::new() } @@ -1597,9 +1635,11 @@ impl From<&Path> for Rc<Path> { #[stable(feature = "rust1", since = "1.0.0")] impl ToOwned for Path { type Owned = PathBuf; + #[inline] fn to_owned(&self) -> PathBuf { self.to_path_buf() } + #[inline] fn clone_into(&self, target: &mut PathBuf) { self.inner.clone_into(&mut target.inner); } @@ -1607,6 +1647,7 @@ impl ToOwned for Path { #[stable(feature = "rust1", since = "1.0.0")] impl cmp::PartialEq for PathBuf { + #[inline] fn eq(&self, other: &PathBuf) -> bool { self.components() == other.components() } @@ -1624,6 +1665,7 @@ impl cmp::Eq for PathBuf {} #[stable(feature = "rust1", since = "1.0.0")] impl cmp::PartialOrd for PathBuf { + #[inline] fn partial_cmp(&self, other: &PathBuf) -> Option<cmp::Ordering> { self.components().partial_cmp(other.components()) } @@ -1631,6 +1673,7 @@ impl cmp::PartialOrd for PathBuf { #[stable(feature = "rust1", since = "1.0.0")] impl cmp::Ord for PathBuf { + #[inline] fn cmp(&self, other: &PathBuf) -> cmp::Ordering { self.components().cmp(other.components()) } @@ -1638,6 +1681,7 @@ impl cmp::Ord for PathBuf { #[stable(feature = "rust1", since = "1.0.0")] impl AsRef<OsStr> for PathBuf { + #[inline] fn as_ref(&self) -> &OsStr { &self.inner[..] } @@ -1745,6 +1789,7 @@ impl Path { /// assert_eq!(os_str, std::ffi::OsStr::new("foo.txt")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn as_os_str(&self) -> &OsStr { &self.inner } @@ -1766,6 +1811,7 @@ impl Path { /// assert_eq!(path.to_str(), Some("foo.txt")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn to_str(&self) -> Option<&str> { self.inner.to_str() } @@ -1791,6 +1837,7 @@ impl Path { /// Had `path` contained invalid unicode, the `to_string_lossy` call might /// have returned `"fo�.txt"`. #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn to_string_lossy(&self) -> Cow<'_, str> { self.inner.to_string_lossy() } @@ -1854,6 +1901,7 @@ impl Path { /// /// [`is_absolute`]: Path::is_absolute #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn is_relative(&self) -> bool { !self.is_absolute() } @@ -1879,6 +1927,7 @@ impl Path { /// assert!(Path::new("/etc/passwd").has_root()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn has_root(&self) -> bool { self.components().has_root() } @@ -1941,6 +1990,7 @@ impl Path { /// /// [`parent`]: Path::parent #[stable(feature = "path_ancestors", since = "1.28.0")] + #[inline] pub fn ancestors(&self) -> Ancestors<'_> { Ancestors { next: Some(&self) } } @@ -2265,6 +2315,7 @@ impl Path { /// assert_eq!(it.next(), None) /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn iter(&self) -> Iter<'_> { Iter { inner: self.components() } } @@ -2284,6 +2335,7 @@ impl Path { /// println!("{}", path.display()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn display(&self) -> Display<'_> { Display { path: self } } @@ -2305,6 +2357,7 @@ impl Path { /// println!("{:?}", metadata.file_type()); /// ``` #[stable(feature = "path_ext", since = "1.5.0")] + #[inline] pub fn metadata(&self) -> io::Result<fs::Metadata> { fs::metadata(self) } @@ -2323,6 +2376,7 @@ impl Path { /// println!("{:?}", metadata.file_type()); /// ``` #[stable(feature = "path_ext", since = "1.5.0")] + #[inline] pub fn symlink_metadata(&self) -> io::Result<fs::Metadata> { fs::symlink_metadata(self) } @@ -2341,6 +2395,7 @@ impl Path { /// assert_eq!(path.canonicalize().unwrap(), PathBuf::from("/foo/test/bar.rs")); /// ``` #[stable(feature = "path_ext", since = "1.5.0")] + #[inline] pub fn canonicalize(&self) -> io::Result<PathBuf> { fs::canonicalize(self) } @@ -2358,6 +2413,7 @@ impl Path { /// let path_link = path.read_link().expect("read_link call failed"); /// ``` #[stable(feature = "path_ext", since = "1.5.0")] + #[inline] pub fn read_link(&self) -> io::Result<PathBuf> { fs::read_link(self) } @@ -2382,6 +2438,7 @@ impl Path { /// } /// ``` #[stable(feature = "path_ext", since = "1.5.0")] + #[inline] pub fn read_dir(&self) -> io::Result<fs::ReadDir> { fs::read_dir(self) } @@ -2406,6 +2463,7 @@ impl Path { /// This is a convenience function that coerces errors to false. If you want to /// check errors, call [`fs::metadata`]. #[stable(feature = "path_ext", since = "1.5.0")] + #[inline] pub fn exists(&self) -> bool { fs::metadata(self).is_ok() } @@ -2480,6 +2538,7 @@ impl Path { #[stable(feature = "rust1", since = "1.0.0")] impl AsRef<OsStr> for Path { + #[inline] fn as_ref(&self) -> &OsStr { &self.inner } @@ -2531,6 +2590,7 @@ impl fmt::Display for Display<'_> { #[stable(feature = "rust1", since = "1.0.0")] impl cmp::PartialEq for Path { + #[inline] fn eq(&self, other: &Path) -> bool { self.components().eq(other.components()) } @@ -2550,6 +2610,7 @@ impl cmp::Eq for Path {} #[stable(feature = "rust1", since = "1.0.0")] impl cmp::PartialOrd for Path { + #[inline] fn partial_cmp(&self, other: &Path) -> Option<cmp::Ordering> { self.components().partial_cmp(other.components()) } @@ -2557,6 +2618,7 @@ impl cmp::PartialOrd for Path { #[stable(feature = "rust1", since = "1.0.0")] impl cmp::Ord for Path { + #[inline] fn cmp(&self, other: &Path) -> cmp::Ordering { self.components().cmp(other.components()) } @@ -2564,6 +2626,7 @@ impl cmp::Ord for Path { #[stable(feature = "rust1", since = "1.0.0")] impl AsRef<Path> for Path { + #[inline] fn as_ref(&self) -> &Path { self } @@ -2571,6 +2634,7 @@ impl AsRef<Path> for Path { #[stable(feature = "rust1", since = "1.0.0")] impl AsRef<Path> for OsStr { + #[inline] fn as_ref(&self) -> &Path { Path::new(self) } @@ -2578,6 +2642,7 @@ impl AsRef<Path> for OsStr { #[stable(feature = "cow_os_str_as_ref_path", since = "1.8.0")] impl AsRef<Path> for Cow<'_, OsStr> { + #[inline] fn as_ref(&self) -> &Path { Path::new(self) } @@ -2585,6 +2650,7 @@ impl AsRef<Path> for Cow<'_, OsStr> { #[stable(feature = "rust1", since = "1.0.0")] impl AsRef<Path> for OsString { + #[inline] fn as_ref(&self) -> &Path { Path::new(self) } @@ -2600,6 +2666,7 @@ impl AsRef<Path> for str { #[stable(feature = "rust1", since = "1.0.0")] impl AsRef<Path> for String { + #[inline] fn as_ref(&self) -> &Path { Path::new(self) } @@ -2617,6 +2684,7 @@ impl AsRef<Path> for PathBuf { impl<'a> IntoIterator for &'a PathBuf { type Item = &'a OsStr; type IntoIter = Iter<'a>; + #[inline] fn into_iter(self) -> Iter<'a> { self.iter() } @@ -2626,6 +2694,7 @@ impl<'a> IntoIterator for &'a PathBuf { impl<'a> IntoIterator for &'a Path { type Item = &'a OsStr; type IntoIter = Iter<'a>; + #[inline] fn into_iter(self) -> Iter<'a> { self.iter() } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8fa60fa7178..a116ed686d9 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1096,7 +1096,10 @@ impl Clean<Item> for hir::TraitItem<'_> { AssocTypeItem(bounds.clean(cx), default.clean(cx)) } }; - Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx) + let what_rustc_thinks = + Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx); + // Trait items always inherit the trait's visibility -- we don't want to show `pub`. + Item { visibility: Inherited, ..what_rustc_thinks } }) } } @@ -1131,7 +1134,21 @@ impl Clean<Item> for hir::ImplItem<'_> { ) } }; - Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx) + + let what_rustc_thinks = + Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx); + let parent_item = cx.tcx.hir().expect_item(cx.tcx.hir().get_parent_item(self.hir_id)); + if let hir::ItemKind::Impl(impl_) = &parent_item.kind { + if impl_.of_trait.is_some() { + // Trait impl items always inherit the impl's visibility -- + // we don't want to show `pub`. + Item { visibility: Inherited, ..what_rustc_thinks } + } else { + what_rustc_thinks + } + } else { + panic!("found impl item with non-impl parent {:?}", parent_item); + } }) } } diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index 5c0f5e50c9e..6941fa064ec 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -12,6 +12,9 @@ use crate::formats::cache::{Cache, CACHE_KEY}; /// backend renderer has hooks for initialization, documenting an item, entering and exiting a /// module, and cleanup/finalizing output. crate trait FormatRenderer<'tcx>: Clone { + /// Gives a description of the renderer. Used for performance profiling. + fn descr() -> &'static str; + /// Sets up any state required for the renderer. When this is called the cache has already been /// populated. fn init( @@ -57,16 +60,20 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>( edition: Edition, tcx: TyCtxt<'tcx>, ) -> Result<(), Error> { - let (krate, mut cache) = Cache::from_krate( - render_info.clone(), - options.document_private, - &options.extern_html_root_urls, - &options.output, - krate, - ); - - let (mut format_renderer, mut krate) = - T::init(krate, options, render_info, edition, &mut cache, tcx)?; + let (krate, mut cache) = tcx.sess.time("create_format_cache", || { + Cache::from_krate( + render_info.clone(), + options.document_private, + &options.extern_html_root_urls, + &options.output, + krate, + ) + }); + let prof = &tcx.sess.prof; + + let (mut format_renderer, mut krate) = prof + .extra_verbose_generic_activity("create_renderer", T::descr()) + .run(|| T::init(krate, options, render_info, edition, &mut cache, tcx))?; let cache = Arc::new(cache); // Freeze the cache now that the index has been built. Put an Arc into TLS for future @@ -83,6 +90,7 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>( // Render the crate documentation let mut work = vec![(format_renderer.clone(), item)]; + let unknown = rustc_span::Symbol::intern("<unknown item>"); while let Some((mut cx, item)) = work.pop() { if item.is_mod() { // modules are special because they add a namespace. We also need to @@ -91,6 +99,7 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>( if name.is_empty() { panic!("Unexpected module with empty name"); } + let _timer = prof.generic_activity_with_arg("render_mod_item", name.as_str()); cx.mod_item_in(&item, &name, &cache)?; let module = match *item.kind { @@ -104,9 +113,10 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>( cx.mod_item_out(&name)?; } else if item.name.is_some() { - cx.item(item, &cache)?; + prof.generic_activity_with_arg("render_item", &*item.name.unwrap_or(unknown).as_str()) + .run(|| cx.item(item, &cache))?; } } - - format_renderer.after_krate(&krate, &cache, diag) + prof.extra_verbose_generic_activity("renderer_after_krate", T::descr()) + .run(|| format_renderer.after_krate(&krate, &cache, diag)) } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 6167b75ee50..8e010839ad8 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -383,6 +383,10 @@ crate fn initial_ids() -> Vec<String> { /// Generates the documentation for `crate` into the directory `dst` impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { + fn descr() -> &'static str { + "html" + } + fn init( mut krate: clean::Crate, options: RenderOptions, diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index dc50c8a76b2..512c9124727 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -125,6 +125,10 @@ impl JsonRenderer<'_> { } impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { + fn descr() -> &'static str { + "json" + } + fn init( krate: clean::Crate, options: RenderOptions, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index d17189b416d..83736295beb 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -540,7 +540,7 @@ fn main_options(options: config::Options) -> MainResult { sess.fatal("Compilation failed, aborting rustdoc"); } - let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).take(); + let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).peek_mut(); global_ctxt.enter(|tcx| { let (mut krate, render_info, render_opts) = sess.time("run_global_ctxt", || { diff --git a/src/test/rustdoc/visibility.rs b/src/test/rustdoc/visibility.rs index 59427693c5a..beb638406c4 100644 --- a/src/test/rustdoc/visibility.rs +++ b/src/test/rustdoc/visibility.rs @@ -42,3 +42,35 @@ mod a { struct FooBPriv; } } + +// @has 'foo/trait.PubTrait.html' '//pre' 'pub trait PubTrait' +// +// @has 'foo/trait.PubTrait.html' '//pre' 'type Type;' +// @!has 'foo/trait.PubTrait.html' '//pre' 'pub type Type;' +// +// @has 'foo/trait.PubTrait.html' '//pre' 'const CONST: usize;' +// @!has 'foo/trait.PubTrait.html' '//pre' 'pub const CONST: usize;' +// +// @has 'foo/trait.PubTrait.html' '//pre' 'fn function();' +// @!has 'foo/trait.PubTrait.html' '//pre' 'pub fn function();' + +pub trait PubTrait { + type Type; + const CONST: usize; + fn function(); +} + +// @has 'foo/struct.FooPublic.html' '//code' 'type Type' +// @!has 'foo/struct.FooPublic.html' '//code' 'pub type Type' +// +// @has 'foo/struct.FooPublic.html' '//code' 'const CONST: usize' +// @!has 'foo/struct.FooPublic.html' '//code' 'pub const CONST: usize' +// +// @has 'foo/struct.FooPublic.html' '//code' 'fn function()' +// @!has 'foo/struct.FooPublic.html' '//code' 'pub fn function()' + +impl PubTrait for FooPublic { + type Type = usize; + const CONST: usize = 0; + fn function() {} +} diff --git a/src/test/ui/closures/local-type-mix.rs b/src/test/ui/closures/local-type-mix.rs new file mode 100644 index 00000000000..006e6f490f0 --- /dev/null +++ b/src/test/ui/closures/local-type-mix.rs @@ -0,0 +1,17 @@ +// Check that using the parameter name in its type does not ICE. +// edition:2018 + +#![feature(async_closure)] + +fn main() { + let _ = |x: x| x; //~ ERROR expected type + let _ = |x: bool| -> x { x }; //~ ERROR expected type + let _ = async move |x: x| x; //~ ERROR expected type + let _ = async move |x: bool| -> x { x }; //~ ERROR expected type +} + +fn foo(x: x) {} //~ ERROR expected type +fn foo_ret(x: bool) -> x {} //~ ERROR expected type + +async fn async_foo(x: x) {} //~ ERROR expected type +async fn async_foo_ret(x: bool) -> x {} //~ ERROR expected type diff --git a/src/test/ui/closures/local-type-mix.stderr b/src/test/ui/closures/local-type-mix.stderr new file mode 100644 index 00000000000..68c320a065d --- /dev/null +++ b/src/test/ui/closures/local-type-mix.stderr @@ -0,0 +1,51 @@ +error[E0573]: expected type, found local variable `x` + --> $DIR/local-type-mix.rs:7:17 + | +LL | let _ = |x: x| x; + | ^ not a type + +error[E0573]: expected type, found local variable `x` + --> $DIR/local-type-mix.rs:8:26 + | +LL | let _ = |x: bool| -> x { x }; + | ^ not a type + +error[E0573]: expected type, found local variable `x` + --> $DIR/local-type-mix.rs:9:28 + | +LL | let _ = async move |x: x| x; + | ^ not a type + +error[E0573]: expected type, found local variable `x` + --> $DIR/local-type-mix.rs:10:37 + | +LL | let _ = async move |x: bool| -> x { x }; + | ^ not a type + +error[E0573]: expected type, found local variable `x` + --> $DIR/local-type-mix.rs:13:11 + | +LL | fn foo(x: x) {} + | ^ not a type + +error[E0573]: expected type, found local variable `x` + --> $DIR/local-type-mix.rs:14:24 + | +LL | fn foo_ret(x: bool) -> x {} + | ^ not a type + +error[E0573]: expected type, found local variable `x` + --> $DIR/local-type-mix.rs:16:23 + | +LL | async fn async_foo(x: x) {} + | ^ not a type + +error[E0573]: expected type, found local variable `x` + --> $DIR/local-type-mix.rs:17:36 + | +LL | async fn async_foo_ret(x: bool) -> x {} + | ^ not a type + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0573`. diff --git a/src/test/ui/mir/issue-80742.stderr b/src/test/ui/mir/issue-80742.stderr index 2ec0e950528..26f9c786ba1 100644 --- a/src/test/ui/mir/issue-80742.stderr +++ b/src/test/ui/mir/issue-80742.stderr @@ -1,3 +1,17 @@ +error[E0080]: evaluation of constant value failed + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | +LL | intrinsics::size_of::<T>() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | size_of called on unsized type `dyn Debug` + | inside `std::mem::size_of::<dyn Debug>` at $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + ::: $DIR/issue-80742.rs:23:10 + | +LL | [u8; size_of::<T>() + 1]: , + | -------------- inside `Inline::<dyn Debug>::{constant#0}` at $DIR/issue-80742.rs:23:10 + error[E0599]: no function or associated item named `new` found for struct `Inline<dyn Debug>` in the current scope --> $DIR/issue-80742.rs:31:36 | @@ -21,6 +35,20 @@ LL | pub trait Debug { = note: the method `new` exists but the following trait bounds were not satisfied: `dyn Debug: Sized` +error[E0080]: evaluation of constant value failed + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | +LL | intrinsics::size_of::<T>() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | size_of called on unsized type `dyn Debug` + | inside `std::mem::size_of::<dyn Debug>` at $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + ::: $DIR/issue-80742.rs:15:10 + | +LL | [u8; size_of::<T>() + 1]: , + | -------------- inside `Inline::<dyn Debug>::{constant#0}` at $DIR/issue-80742.rs:15:10 + error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time --> $DIR/issue-80742.rs:31:15 | @@ -36,7 +64,7 @@ help: consider relaxing the implicit `Sized` restriction LL | struct Inline<T: ?Sized> | ^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0277, E0599. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0080, E0277, E0599. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/tools/cargo b/src/tools/cargo -Subproject a73e5b7d567c3036b296fc6b33ed52c5edcd882 +Subproject 783bc43c660bf39c1e562c8c429b32078ad3099 |
