Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Continue to borrowck even if there were previous errors #120550

Merged
merged 4 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 5 additions & 4 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,16 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
let (input_body, promoted) = tcx.mir_promoted(def);
debug!("run query mir_borrowck: {}", tcx.def_path_str(def));

if input_body.borrow().should_skip() {
debug!("Skipping borrowck because of injected body");
let input_body: &Body<'_> = &input_body.borrow();

if input_body.should_skip() || input_body.tainted_by_errors.is_some() {
debug!("Skipping borrowck because of injected body or tainted body");
// Let's make up a borrowck result! Fun times!
let result = BorrowCheckResult {
concrete_opaque_types: FxIndexMap::default(),
closure_requirements: None,
used_mut_upvars: SmallVec::new(),
tainted_by_errors: None,
tainted_by_errors: input_body.tainted_by_errors,
};
return tcx.arena.alloc(result);
}
Expand All @@ -127,7 +129,6 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {

let infcx =
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)).build();
let input_body: &Body<'_> = &input_body.borrow();
let promoted: &IndexSlice<_, _> = &promoted.borrow();
let opt_closure_req = do_mir_borrowck(&infcx, input_body, promoted, None).0;
debug!("mir_borrowck done");
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,6 @@ impl Lifetime {
(LifetimeSuggestionPosition::Normal, self.ident.span)
}
}

pub fn is_static(&self) -> bool {
self.res == LifetimeName::Static
}
}

/// A `Path` is essentially Rust's notion of a name; for instance,
Expand Down
22 changes: 4 additions & 18 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::astconv::errors::prohibit_assoc_ty_binding;
use crate::astconv::generics::{check_generic_arg_count, create_args_for_parent_generic_args};
use crate::bounds::Bounds;
use crate::collect::HirPlaceholderCollector;
use crate::errors::{AmbiguousLifetimeBound, TypeofReservedKeywordUsed};
use crate::errors::AmbiguousLifetimeBound;
use crate::middle::resolve_bound_vars as rbv;
use crate::require_c_abi_if_c_variadic;
use rustc_ast::TraitObjectSyntax;
Expand All @@ -30,8 +30,8 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause;
use rustc_middle::middle::stability::AllowUnstable;
use rustc_middle::ty::{
self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, IsSuggestable, ParamEnv, Ty,
TyCtxt, TypeVisitableExt,
self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
TypeVisitableExt,
};
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
use rustc_span::edit_distance::find_best_match_for_name;
Expand Down Expand Up @@ -2539,21 +2539,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {

Ty::new_array_with_const_len(tcx, self.ast_ty_to_ty(ty), length)
}
hir::TyKind::Typeof(e) => {
let ty_erased = tcx.type_of(e.def_id).instantiate_identity();
let ty = tcx.fold_regions(ty_erased, |r, _| {
if r.is_erased() { tcx.lifetimes.re_static } else { r }
});
let span = ast_ty.span;
let (ty, opt_sugg) = if let Some(ty) = ty.make_suggestable(tcx, false) {
(ty, Some((span, Applicability::MachineApplicable)))
} else {
(ty, None)
};
tcx.dcx().emit_err(TypeofReservedKeywordUsed { span, ty, opt_sugg });

ty
}
hir::TyKind::Typeof(e) => tcx.type_of(e.def_id).instantiate_identity(),
hir::TyKind::Infer => {
// Infer also appears as the type of arguments or return
// values in an ExprKind::Closure, or as
Expand Down
16 changes: 14 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use rustc_middle::ty::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, Ty
use rustc_span::symbol::Ident;
use rustc_span::{Span, DUMMY_SP};

use crate::errors::TypeofReservedKeywordUsed;

use super::bad_placeholder;
use super::ItemCtxt;
pub use opaque::test_opaque_hidden_types;
Expand Down Expand Up @@ -39,8 +41,18 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
{
return tcx.types.usize;
}
Node::Ty(&hir::Ty { kind: TyKind::Typeof(ref e), .. }) if e.hir_id == hir_id => {
return tcx.typeck(def_id).node_type(e.hir_id);
Node::Ty(&hir::Ty { kind: TyKind::Typeof(ref e), span, .. }) if e.hir_id == hir_id => {
let ty = tcx.typeck(def_id).node_type(e.hir_id);
let ty = tcx.fold_regions(ty, |r, _| {
if r.is_erased() { ty::Region::new_error_misc(tcx) } else { r }
});
let (ty, opt_sugg) = if let Some(ty) = ty.make_suggestable(tcx, false) {
(ty, Some((span, Applicability::MachineApplicable)))
} else {
(ty, None)
};
tcx.dcx().emit_err(TypeofReservedKeywordUsed { span, ty, opt_sugg });
return ty;
}
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
| Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {

tcx.ensure().check_unused_traits(());

if let Some(reported) = tcx.dcx().has_errors() { Err(reported) } else { Ok(()) }
Ok(())
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the motivation of this PR. removing another has_errors that affects compilation progress

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}

/// A quasi-deprecated helper used in rustdoc and clippy to get
Expand Down
21 changes: 18 additions & 3 deletions compiler/rustc_mir_build/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,7 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) -
let yield_ty = args.yield_ty();
let return_ty = args.return_ty();
(
vec![closure_ty, args.resume_ty()],
vec![closure_ty, resume_ty],
return_ty,
Some(Box::new(CoroutineInfo::initial(
tcx.coroutine_kind(def_id).unwrap(),
Expand All @@ -675,8 +675,23 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) -
))),
)
}
_ => {
span_bug!(span, "expected type of closure body to be a closure or coroutine");
ty::CoroutineClosure(did, _args) => {
// FIXME(async_closures): Recover the proper error signature
let inputs = tcx
.closure_user_provided_sig(did.expect_local())
.value
.skip_binder()
.inputs();

let err = Ty::new_error(tcx, guar);
(inputs.iter().map(|_| err).collect(), err, None)
}
ty::Error(_) => (vec![closure_ty, closure_ty], closure_ty, None),
kind => {
span_bug!(
span,
"expected type of closure body to be a closure or coroutine, got {kind:?}"
);
}
}
}
Expand Down
12 changes: 11 additions & 1 deletion compiler/rustc_mir_build/src/build/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let drops = if destination.is_some() {
&mut self.scopes.breakable_scopes[break_index].break_drops
} else {
self.scopes.breakable_scopes[break_index].continue_drops.as_mut().unwrap()
let Some(drops) = self.scopes.breakable_scopes[break_index].continue_drops.as_mut()
else {
self.tcx.dcx().span_delayed_bug(
source_info.span,
"unlabelled `continue` within labelled block",
);
self.cfg.terminate(block, source_info, TerminatorKind::Unreachable);

return self.cfg.start_new_block().unit();
};
drops
Comment on lines +658 to +668
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also part of the continue without target issue

};

let drop_idx = self.scopes.scopes[scope_index + 1..]
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
ty::Closure(..) => Abi::RustCall,
ty::CoroutineClosure(..) => Abi::RustCall,
ty::Coroutine(..) => Abi::Rust,
ty::Error(_) => return false,
_ => span_bug!(body.span, "unexpected body ty: {:?}", body_ty),
};
let body_can_unwind = layout::fn_can_unwind(tcx, Some(def_id), body_abi);
Expand Down
12 changes: 11 additions & 1 deletion compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2911,12 +2911,22 @@ impl<'a> Parser<'a> {
Ok(arm) => arms.push(arm),
Err(e) => {
// Recover by skipping to the end of the block.
e.emit();
let guar = e.emit();
self.recover_stmt();
let span = lo.to(self.token.span);
if self.token == token::CloseDelim(Delimiter::Brace) {
self.bump();
}
// Always push at least one arm to make the match non-empty
arms.push(Arm {
attrs: Default::default(),
pat: self.mk_pat(span, ast::PatKind::Err(guar)),
guard: None,
body: Some(self.mk_expr_err(span)),
span,
id: DUMMY_NODE_ID,
is_placeholder: false,
});
return Ok(self.mk_expr_with_attrs(
span,
ExprKind::Match(scrutinee, arms),
Expand Down
10 changes: 6 additions & 4 deletions compiler/rustc_passes/src/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ enum LiveNodeKind {
VarDefNode(Span, HirId),
ClosureNode,
ExitNode,
ErrNode,
}

fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_>) -> String {
Expand All @@ -133,6 +134,7 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_>) -> String {
VarDefNode(s, _) => format!("Var def node [{}]", sm.span_to_diagnostic_string(s)),
ClosureNode => "Closure node".to_owned(),
ExitNode => "Exit node".to_owned(),
ErrNode => "Error node".to_owned(),
}
}

Expand Down Expand Up @@ -967,10 +969,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {

// Now that we know the label we're going to,
// look it up in the continue loop nodes table
self.cont_ln
.get(&sc)
.cloned()
.unwrap_or_else(|| span_bug!(expr.span, "continue to unknown label"))
self.cont_ln.get(&sc).cloned().unwrap_or_else(|| {
self.ir.tcx.dcx().span_delayed_bug(expr.span, "continue to unknown label");
self.ir.add_live_node(ErrNode)
})
Comment on lines -970 to +975
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't (yet) know that we should not be doing liveness checks, because the error happens in check_mod_loops for which we have no path to forward a taint to here ("here" being check_liveness)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw this (at least used to?) fire here I believe: #113379

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh neat. More evidence that those ICEs I've caused are preexisting, but hard to trigger

}

hir::ExprKind::Assign(ref l, ref r, _) => {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_lints/src/lifetimes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ fn check_fn_inner<'tcx>(
_ => None,
});
for bound in lifetimes {
if !bound.is_static() && !bound.is_elided() {
if bound.res != LifetimeName::Static && !bound.is_elided() {
return;
}
}
Expand Down
3 changes: 3 additions & 0 deletions tests/incremental/const-generics/issue-62536.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
// revisions:cfail1

#![allow(unused_variables)]

struct S<T, const N: usize>([T; N]);

fn f<T, const N: usize>(x: T) -> S<T, {N}> { panic!() }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// revisions: cfail
#![feature(generic_const_exprs)]
#![allow(incomplete_features, unused_braces)]
#![allow(incomplete_features, unused_braces, unused_variables)]

trait Delegates<T> {}

Expand Down
1 change: 1 addition & 0 deletions tests/incremental/struct_change_field_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// [cfail2] compile-flags: -Z query-dep-graph -Z assert-incr-state=loaded

#![feature(rustc_attrs)]
#![allow(unused_variables)]

#[cfg(rpass1)]
pub struct X {
Expand Down
4 changes: 2 additions & 2 deletions tests/rustdoc-ui/issues/issue-102986.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ LL | y: (typeof("hey"),),
|
help: consider replacing `typeof(...)` with an actual type
|
LL | y: (&'static str,),
| ~~~~~~~~~~~~
LL | y: (&str,),
| ~~~~

error: aborting due to 1 previous error

Expand Down