Skip to content

Rollup of 5 pull requests #124934

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

Merged
merged 10 commits into from
May 9, 2024
15 changes: 9 additions & 6 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1422,7 +1422,7 @@ pub enum ExprKind {
/// of `if` / `while` expressions. (e.g., `if let 0 = x { .. }`).
///
/// `Span` represents the whole `let pat = expr` statement.
Let(P<Pat>, P<Expr>, Span, Option<ErrorGuaranteed>),
Let(P<Pat>, P<Expr>, Span, Recovered),
/// An `if` block, with an optional `else` block.
///
/// `if expr { block } else { expr }`
Expand Down Expand Up @@ -2881,17 +2881,20 @@ pub struct FieldDef {
pub is_placeholder: bool,
}

/// Was parsing recovery performed?
#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
pub enum Recovered {
No,
Yes(ErrorGuaranteed),
}

/// Fields and constructor ids of enum variants and structs.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum VariantData {
/// Struct variant.
///
/// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
Struct {
fields: ThinVec<FieldDef>,
// FIXME: investigate making this a `Option<ErrorGuaranteed>`
recovered: bool,
},
Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
/// Tuple variant.
///
/// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
let ohs = self.lower_expr(ohs);
hir::ExprKind::AddrOf(*k, *m, ohs)
}
ExprKind::Let(pat, scrutinee, span, is_recovered) => {
ExprKind::Let(pat, scrutinee, span, recovered) => {
hir::ExprKind::Let(self.arena.alloc(hir::LetExpr {
span: self.lower_span(*span),
pat: self.lower_pat(pat),
ty: None,
init: self.lower_expr(scrutinee),
is_recovered: *is_recovered,
recovered: *recovered,
}))
}
ExprKind::If(cond, then, else_opt) => {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1283,7 +1283,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fields.iter().enumerate().map(|f| this.lower_field_def(f)),
);
let span = t.span;
let variant_data = hir::VariantData::Struct { fields, recovered: false };
let variant_data =
hir::VariantData::Struct { fields, recovered: ast::Recovered::No };
// FIXME: capture the generics from the outer adt.
let generics = hir::Generics::empty();
let kind = match t.kind {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
{
self.suggest_cloning(err, ty, expr, None, Some(move_spans));
} else if self.suggest_hoisting_call_outside_loop(err, expr) {
// The place where the the type moves would be misleading to suggest clone.
// The place where the type moves would be misleading to suggest clone.
// #121466
self.suggest_cloning(err, ty, expr, None, Some(move_spans));
}
Expand Down
19 changes: 14 additions & 5 deletions compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1326,14 +1326,20 @@ impl<'tcx> RegionInferenceContext<'tcx> {
})
}

// Evaluate whether `sup_region == sub_region`.
fn eval_equal(&self, r1: RegionVid, r2: RegionVid) -> bool {
/// Evaluate whether `sup_region == sub_region`.
///
/// Panics if called before `solve()` executes,
// This is `pub` because it's used by unstable external borrowck data users, see `consumers.rs`.
pub fn eval_equal(&self, r1: RegionVid, r2: RegionVid) -> bool {
self.eval_outlives(r1, r2) && self.eval_outlives(r2, r1)
}

// Evaluate whether `sup_region: sub_region`.
/// Evaluate whether `sup_region: sub_region`.
///
/// Panics if called before `solve()` executes,
// This is `pub` because it's used by unstable external borrowck data users, see `consumers.rs`.
#[instrument(skip(self), level = "debug", ret)]
fn eval_outlives(&self, sup_region: RegionVid, sub_region: RegionVid) -> bool {
pub fn eval_outlives(&self, sup_region: RegionVid, sub_region: RegionVid) -> bool {
debug!(
"sup_region's value = {:?} universal={:?}",
self.region_value_str(sup_region),
Expand Down Expand Up @@ -2246,7 +2252,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}

/// Access to the SCC constraint graph.
pub(crate) fn constraint_sccs(&self) -> &Sccs<RegionVid, ConstraintSccIndex> {
/// This can be used to quickly under-approximate the regions which are equal to each other
/// and their relative orderings.
// This is `pub` because it's used by unstable external borrowck data users, see `consumers.rs`.
pub fn constraint_sccs(&self) -> &Sccs<RegionVid, ConstraintSccIndex> {
self.constraint_sccs.as_ref()
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// compares lifetimes directly, so we need to map the inference variables
/// back to concrete lifetimes: `'static`, `ReEarlyParam` or `ReLateParam`.
///
/// First we map the regions in the the generic parameters `_Return<'1>` to
/// First we map the regions in the generic parameters `_Return<'1>` to
/// their `external_name` giving `_Return<'a>`. This step is a bit involved.
/// See the [rustc-dev-guide chapter] for more info.
///
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_builtin_macros/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ use rustc_ast::{token, StmtKind};
use rustc_ast::{
Expr, ExprKind, FormatAlignment, FormatArgPosition, FormatArgPositionKind, FormatArgs,
FormatArgsPiece, FormatArgument, FormatArgumentKind, FormatArguments, FormatCount,
FormatDebugHex, FormatOptions, FormatPlaceholder, FormatSign, FormatTrait,
FormatDebugHex, FormatOptions, FormatPlaceholder, FormatSign, FormatTrait, Recovered,
};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{Applicability, Diag, MultiSpan, PResult, SingleLabelManySpans};
use rustc_expand::base::*;
use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY;
use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiag, LintId};
use rustc_parse::parser::Recovered;
use rustc_parse_format as parse;
use rustc_span::symbol::{Ident, Symbol};
use rustc_span::{BytePos, ErrorGuaranteed, InnerSpan, Span};
Expand Down Expand Up @@ -112,7 +111,7 @@ fn parse_args<'a>(ecx: &ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<'a,
_ => return Err(err),
}
}
Ok(Recovered::Yes) => (),
Ok(Recovered::Yes(_)) => (),
Ok(Recovered::No) => unreachable!(),
}
}
Expand Down
15 changes: 8 additions & 7 deletions compiler/rustc_const_eval/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ const_eval_deref_function_pointer =
accessing {$allocation} which contains a function
const_eval_deref_vtable_pointer =
accessing {$allocation} which contains a vtable
const_eval_different_allocations =
`{$name}` called on pointers into different allocations

const_eval_division_by_zero =
dividing by zero
const_eval_division_overflow =
Expand Down Expand Up @@ -234,12 +231,18 @@ const_eval_not_enough_caller_args =
const_eval_nullary_intrinsic_fail =
could not evaluate nullary intrinsic

const_eval_offset_from_different_allocations =
`{$name}` called on pointers into different allocations
const_eval_offset_from_different_integers =
`{$name}` called on different pointers without provenance (i.e., without an associated allocation)
const_eval_offset_from_overflow =
`{$name}` called when first pointer is too far ahead of second

const_eval_offset_from_test = out-of-bounds `offset_from`
const_eval_offset_from_test =
out-of-bounds `offset_from`
const_eval_offset_from_underflow =
`{$name}` called when first pointer is too far before second
const_eval_offset_from_unsigned_overflow =
`ptr_offset_from_unsigned` called when first pointer has smaller offset than second: {$a_offset} < {$b_offset}

const_eval_operator_non_const =
cannot call non-const operator in {const_eval_const_context}s
Expand Down Expand Up @@ -381,8 +384,6 @@ const_eval_unreachable = entering unreachable code
const_eval_unreachable_unwind =
unwinding past a stack frame that does not allow unwinding

const_eval_unsigned_offset_from_overflow =
`ptr_offset_from_unsigned` called when first pointer has smaller offset than second: {$a_offset} < {$b_offset}
const_eval_unsized_local = unsized locals are not supported
const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn

Expand Down
29 changes: 16 additions & 13 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,16 @@ use rustc_middle::ty::layout::{LayoutOf as _, ValidityRequirement};
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{Ty, TyCtxt};
use rustc_middle::{
mir::{
self,
interpret::{
Allocation, ConstAllocation, GlobalId, InterpResult, PointerArithmetic, Scalar,
},
BinOp, ConstValue, NonDivergingIntrinsic,
},
mir::{self, BinOp, ConstValue, NonDivergingIntrinsic},
ty::layout::TyAndLayout,
};
use rustc_span::symbol::{sym, Symbol};
use rustc_target::abi::Size;

use super::{
memory::MemoryKind, util::ensure_monomorphic_enough, CheckInAllocMsg, ImmTy, InterpCx,
MPlaceTy, Machine, OpTy, Pointer,
memory::MemoryKind, util::ensure_monomorphic_enough, Allocation, CheckInAllocMsg,
ConstAllocation, GlobalId, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, Pointer,
PointerArithmetic, Scalar,
};

use crate::fluent_generated as fluent;
Expand Down Expand Up @@ -249,22 +244,30 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
match (self.ptr_try_get_alloc_id(a), self.ptr_try_get_alloc_id(b)) {
(Err(a), Err(b)) => {
// Neither pointer points to an allocation.
// If these are inequal or null, this *will* fail the deref check below.
// This is okay only if they are the same.
if a != b {
// We'd catch this below in the "dereferenceable" check, but
// show a nicer error for this particular case.
throw_ub_custom!(
fluent::const_eval_offset_from_different_integers,
name = intrinsic_name,
);
}
(a, b)
}
(Err(_), _) | (_, Err(_)) => {
// We managed to find a valid allocation for one pointer, but not the other.
// That means they are definitely not pointing to the same allocation.
throw_ub_custom!(
fluent::const_eval_different_allocations,
fluent::const_eval_offset_from_different_allocations,
name = intrinsic_name,
);
}
(Ok((a_alloc_id, a_offset, _)), Ok((b_alloc_id, b_offset, _))) => {
// Found allocation for both. They must be into the same allocation.
if a_alloc_id != b_alloc_id {
throw_ub_custom!(
fluent::const_eval_different_allocations,
fluent::const_eval_offset_from_different_allocations,
name = intrinsic_name,
);
}
Expand All @@ -286,7 +289,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// a < b
if intrinsic_name == sym::ptr_offset_from_unsigned {
throw_ub_custom!(
fluent::const_eval_unsigned_offset_from_overflow,
fluent::const_eval_offset_from_unsigned_overflow,
a_offset = a_offset,
b_offset = b_offset,
);
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_expand/src/placeholders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,10 @@ pub(crate) fn placeholder(
}]),
AstFragmentKind::Variants => AstFragment::Variants(smallvec![ast::Variant {
attrs: Default::default(),
data: ast::VariantData::Struct { fields: Default::default(), recovered: false },
data: ast::VariantData::Struct {
fields: Default::default(),
recovered: ast::Recovered::No
},
disr_expr: None,
id,
ident,
Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1308,9 +1308,9 @@ pub struct LetExpr<'hir> {
pub pat: &'hir Pat<'hir>,
pub ty: Option<&'hir Ty<'hir>>,
pub init: &'hir Expr<'hir>,
/// `Some` when this let expressions is not in a syntanctically valid location.
/// `Recovered::Yes` when this let expressions is not in a syntanctically valid location.
/// Used to prevent building MIR in such situations.
pub is_recovered: Option<ErrorGuaranteed>,
pub recovered: ast::Recovered,
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
Expand Down Expand Up @@ -3030,11 +3030,7 @@ pub enum VariantData<'hir> {
/// A struct variant.
///
/// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
Struct {
fields: &'hir [FieldDef<'hir>],
// FIXME: investigate making this a `Option<ErrorGuaranteed>`
recovered: bool,
},
Struct { fields: &'hir [FieldDef<'hir>], recovered: ast::Recovered },
/// A tuple variant.
///
/// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
ExprKind::DropTemps(ref subexpression) => {
try_visit!(visitor.visit_expr(subexpression));
}
ExprKind::Let(LetExpr { span: _, pat, ty, init, is_recovered: _ }) => {
ExprKind::Let(LetExpr { span: _, pat, ty, init, recovered: _ }) => {
// match the visit order in walk_local
try_visit!(visitor.visit_expr(init));
try_visit!(visitor.visit_pat(pat));
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
//! At present, however, we do run collection across all items in the
//! crate as a kind of pass. This should eventually be factored away.

use rustc_ast::Recovered;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_data_structures::unord::UnordMap;
Expand Down Expand Up @@ -1005,10 +1006,7 @@ fn lower_variant(
vis: tcx.visibility(f.def_id),
})
.collect();
let recovered = match def {
hir::VariantData::Struct { recovered, .. } => *recovered,
_ => false,
};
let recovered = matches!(def, hir::VariantData::Struct { recovered: Recovered::Yes(_), .. });
ty::VariantDef::new(
ident.name,
variant_did.map(LocalDefId::to_def_id),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1271,7 +1271,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// otherwise check exactly as a let statement
self.check_decl((let_expr, hir_id).into());
// but return a bool, for this is a boolean expression
if let Some(error_guaranteed) = let_expr.is_recovered {
if let ast::Recovered::Yes(error_guaranteed) = let_expr.recovered {
self.set_tainted_by_errors(error_guaranteed);
Ty::new_error(self.tcx, error_guaranteed)
} else {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/gather_locals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl<'a> From<&'a hir::LetStmt<'a>> for Declaration<'a> {

impl<'a> From<(&'a hir::LetExpr<'a>, HirId)> for Declaration<'a> {
fn from((let_expr, hir_id): (&'a hir::LetExpr<'a>, HirId)) -> Self {
let hir::LetExpr { pat, ty, span, init, is_recovered: _ } = *let_expr;
let hir::LetExpr { pat, ty, span, init, recovered: _ } = *let_expr;
Declaration { hir_id, pat, ty, span, init: Some(init), origin: DeclOrigin::LetExpr }
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2449,7 +2449,7 @@ impl<'tcx> TyCtxt<'tcx> {
span,
msg,
format!("#![feature({feature})]\n"),
Applicability::MachineApplicable,
Applicability::MaybeIncorrect,
);
} else {
diag.help(msg);
Expand Down
Loading
Loading