From 1b09dc2596c88dcf3fb840046f05db5e8595e9ca Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 16 Jan 2021 11:34:22 +0100 Subject: PlaceRef::ty: use method call syntax --- compiler/rustc_codegen_ssa/src/mir/analyze.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/place.rs | 2 +- .../rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs | 4 +++- compiler/rustc_mir/src/borrow_check/mod.rs | 8 ++++---- compiler/rustc_mir/src/borrow_check/prefixes.rs | 2 +- 5 files changed, 10 insertions(+), 8 deletions(-) (limited to 'compiler') 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> 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_mir/src/borrow_check/diagnostics/conflict_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs index db02ee67910..727514b5007 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs @@ -287,7 +287,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()); @@ -725,6 +725,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 -- cgit 1.4.1-3-g733a5 From e3faeb486a962d19e1f533a206511b669aced988 Mon Sep 17 00:00:00 2001 From: Ömer Sinan Ağacan Date: Thu, 21 Jan 2021 20:10:40 +0300 Subject: mir: Improve size_of handling when arg is unsized --- compiler/rustc_middle/src/mir/interpret/error.rs | 3 +++ compiler/rustc_mir/src/interpret/step.rs | 1 + src/test/ui/mir/issue-80742.stderr | 34 +++++++++++++++++++++--- 3 files changed, 35 insertions(+), 3 deletions(-) (limited to 'compiler') 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/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/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::() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | size_of called on unsized type `dyn Debug` + | inside `std::mem::size_of::` at $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + ::: $DIR/issue-80742.rs:23:10 + | +LL | [u8; size_of::() + 1]: , + | -------------- inside `Inline::::{constant#0}` at $DIR/issue-80742.rs:23:10 + error[E0599]: no function or associated item named `new` found for struct `Inline` 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::() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | size_of called on unsized type `dyn Debug` + | inside `std::mem::size_of::` at $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + ::: $DIR/issue-80742.rs:15:10 + | +LL | [u8; size_of::() + 1]: , + | -------------- inside `Inline::::{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 | ^^^^^^^^ -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`. -- cgit 1.4.1-3-g733a5 From 3f42abec58ab05d37689f33efdfa6382eb4b1e1a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 21 Jan 2021 22:09:15 +0100 Subject: Lower closure prototype after its body. --- compiler/rustc_ast_lowering/src/expr.rs | 31 ++++++++++-------- src/test/ui/closures/local-type-mix.rs | 17 ++++++++++ src/test/ui/closures/local-type-mix.stderr | 51 ++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 13 deletions(-) create mode 100644 src/test/ui/closures/local-type-mix.rs create mode 100644 src/test/ui/closures/local-type-mix.stderr (limited to 'compiler') diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 1b9ccbd850b..2470a8791e1 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -770,10 +770,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; @@ -785,8 +782,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( @@ -832,12 +834,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!( @@ -868,8 +866,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/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`. -- cgit 1.4.1-3-g733a5 From 5f74ab49694a8622afd44c24021b44239573402d Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 21 Jan 2021 17:57:46 -0500 Subject: Add more self-profile info to rustc_resolve --- compiler/rustc_resolve/src/lib.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'compiler') 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( -- cgit 1.4.1-3-g733a5 From 0679a4cd93db7dfd33b45cd5bd6be52a0f5e894a Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 22 Jan 2021 14:50:21 -0500 Subject: Remove special casing of rustdoc in rustc_lint This is no longer necessary now that rustdoc doesn't run everybody_loops. --- compiler/rustc_lint/src/early.rs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'compiler') 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( // 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"); } } } -- cgit 1.4.1-3-g733a5 From b29353af09893b8b70a9d84595966b7712b60b1b Mon Sep 17 00:00:00 2001 From: pierwill Date: Sun, 17 Jan 2021 11:16:17 -0800 Subject: Edit rustc_middle::dep_graph module documentation Co-authored-by: Joshua Nelson Co-authored-by: Camelid --- compiler/rustc_middle/src/dep_graph/dep_node.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'compiler') 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; -- cgit 1.4.1-3-g733a5 From 688cf6406ab49a65b9b0e882ad4ed4c644145527 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sat, 23 Jan 2021 11:47:38 +0100 Subject: replace RefCell with Cell in FnCtxt --- compiler/rustc_typeck/src/check/check.rs | 2 +- compiler/rustc_typeck/src/check/coercion.rs | 10 +++++----- compiler/rustc_typeck/src/check/expr.rs | 8 ++++---- compiler/rustc_typeck/src/check/fn_ctxt/checks.rs | 9 ++------- compiler/rustc_typeck/src/check/fn_ctxt/mod.rs | 8 ++++---- compiler/rustc_typeck/src/check/mod.rs | 4 ++-- 6 files changed, 18 insertions(+), 23 deletions(-) (limited to 'compiler') 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>, + pub(super) ret_coercion_span: Cell>, pub(super) resume_yield_tys: Option<(Ty<'tcx>, Ty<'tcx>)>, - pub(super) ps: RefCell, + pub(super) ps: Cell, /// 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 { -- cgit 1.4.1-3-g733a5 From ca72f9ed7065a601bd2b1ec80889ec7bad177598 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 22 Jan 2021 13:46:52 -0500 Subject: Calculate self-profile strings in `Compiler::enter` instead in codegen This avoids each tool having to separately find and call `self_profile_alloc_strings`. - Don't compute the global context if it hasn't yet been computed This avoids giving extraneous errors about unresolved names if an error occurs during parsing. --- compiler/rustc_interface/src/passes.rs | 7 ------- compiler/rustc_interface/src/queries.rs | 16 +++++++++++++--- src/librustdoc/lib.rs | 9 +++------ 3 files changed, 16 insertions(+), 16 deletions(-) (limited to 'compiler') 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 "" 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 "" 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/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 19d2de58ffb..780a3b509c7 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -539,7 +539,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", || { @@ -568,7 +568,7 @@ fn main_options(options: config::Options) -> MainResult { info!("going to format"); let (error_format, edition, debugging_options) = diag_opts; let diag = core::new_handler(error_format, None, &debugging_options); - let main_result = match output_format { + match output_format { None | Some(config::OutputFormat::Html) => sess.time("render_html", || { run_renderer::>( krate, @@ -589,10 +589,7 @@ fn main_options(options: config::Options) -> MainResult { tcx, ) }), - }; - // NOTE: this is normally called in codegen, but rustdoc never goes to codegen. - tcx.alloc_self_profile_query_strings(); - main_result + } }) }) }) -- cgit 1.4.1-3-g733a5