Auto merge of #109734 - matthiaskrgr:rollup-oy4nlli, r=matthiaskrgr

Rollup of 8 pull requests

Successful merges:

 - #107387 (Use random `HashMap` keys on Hermit)
 - #109511 (Make `EvalCtxt`'s `infcx` private)
 - #109554 (Suggest ..= when someone tries to create an overflowing range)
 - #109675 (Do not consider elaborated projection predicates for objects in new solver)
 - #109693 (Remove ~const from alloc)
 - #109700 (Lint against escape sequences in Fluent files)
 - #109716 (Move `mir::Field` → `abi::FieldIdx`)
 - #109726 (rustdoc: Don't strip crate module)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2023-03-29 21:57:11 +00:00
commit 2fb0e8d162
77 changed files with 516 additions and 298 deletions

View File

@ -1057,6 +1057,32 @@ impl Scalar {
}
}
rustc_index::newtype_index! {
/// The *source-order* index of a field in a variant.
///
/// This is how most code after type checking refers to fields, rather than
/// using names (as names have hygiene complications and more complex lookup).
///
/// Particularly for `repr(Rust)` types, this may not be the same as *layout* order.
/// (It is for `repr(C)` `struct`s, however.)
///
/// For example, in the following types,
/// ```rust
/// # enum Never {}
/// # #[repr(u16)]
/// enum Demo1 {
/// Variant0 { a: Never, b: i32 } = 100,
/// Variant1 { c: u8, d: u64 } = 10,
/// }
/// struct Demo2 { e: u8, f: u16, g: u8 }
/// ```
/// `b` is `FieldIdx(1)` in `VariantIdx(0)`,
/// `d` is `FieldIdx(1)` in `VariantIdx(1)`, and
/// `f` is `FieldIdx(1)` in `VariantIdx(0)`.
#[derive(HashStable_Generic)]
pub struct FieldIdx {}
}
/// Describes how the fields of a type are located in memory.
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]

View File

@ -9,15 +9,15 @@ use rustc_hir::GeneratorKind;
use rustc_infer::infer::{LateBoundRegionConversionTime, TyCtxtInferExt};
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::{
AggregateKind, Constant, FakeReadCause, Field, Local, LocalInfo, LocalKind, Location, Operand,
Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
AggregateKind, Constant, FakeReadCause, Local, LocalInfo, LocalKind, Location, Operand, Place,
PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
};
use rustc_middle::ty::print::Print;
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult};
use rustc_span::def_id::LocalDefId;
use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP};
use rustc_target::abi::VariantIdx;
use rustc_target::abi::{FieldIdx, VariantIdx};
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
use rustc_trait_selection::traits::{
type_known_to_meet_bound_modulo_regions, Obligation, ObligationCause,
@ -302,7 +302,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn describe_field(
&self,
place: PlaceRef<'tcx>,
field: Field,
field: FieldIdx,
including_tuple_field: IncludingTupleField,
) -> Option<String> {
let place_ty = match place {
@ -331,7 +331,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn describe_field_from_ty(
&self,
ty: Ty<'_>,
field: Field,
field: FieldIdx,
variant_index: Option<VariantIdx>,
including_tuple_field: IncludingTupleField,
) -> Option<String> {

View File

@ -12,6 +12,7 @@ use rustc_middle::{
use rustc_span::source_map::DesugaringKind;
use rustc_span::symbol::{kw, Symbol};
use rustc_span::{sym, BytePos, Span};
use rustc_target::abi::FieldIdx;
use crate::diagnostics::BorrowedContentSource;
use crate::MirBorrowckCtxt;
@ -1275,7 +1276,7 @@ fn is_closure_or_generator(ty: Ty<'_>) -> bool {
fn get_mut_span_in_struct_field<'tcx>(
tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>,
field: mir::Field,
field: FieldIdx,
) -> Option<Span> {
// Expect our local to be a reference to a struct of some kind.
if let ty::Ref(_, ty, _) = ty.kind()

View File

@ -33,12 +33,13 @@ use rustc_middle::mir::{
Place, PlaceElem, PlaceRef, VarDebugInfoContents,
};
use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
use rustc_middle::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind};
use rustc_middle::mir::{ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, CapturedPlace, ParamEnv, RegionVid, TyCtxt};
use rustc_session::lint::builtin::UNUSED_MUT;
use rustc_span::{Span, Symbol};
use rustc_target::abi::FieldIdx;
use either::Either;
use smallvec::SmallVec;
@ -597,7 +598,7 @@ struct MirBorrowckCtxt<'cx, 'tcx> {
used_mut: FxIndexSet<Local>,
/// If the function we're checking is a closure, then we'll need to report back the list of
/// mutable upvars that have been used. This field keeps track of them.
used_mut_upvars: SmallVec<[Field; 8]>,
used_mut_upvars: SmallVec<[FieldIdx; 8]>,
/// Region inference context. This contains the results from region inference and lets us e.g.
/// find out which CFG points are contained in each borrow region.
regioncx: Rc<RegionInferenceContext<'tcx>>,
@ -2277,7 +2278,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
/// then returns the index of the field being projected. Note that this closure will always
/// be `self` in the current MIR, because that is the only time we directly access the fields
/// of a closure type.
fn is_upvar_field_projection(&self, place_ref: PlaceRef<'tcx>) -> Option<Field> {
fn is_upvar_field_projection(&self, place_ref: PlaceRef<'tcx>) -> Option<FieldIdx> {
path_utils::is_upvar_field_projection(self.infcx.tcx, &self.upvars, place_ref, self.body())
}

View File

@ -7,8 +7,9 @@ use crate::BorrowIndex;
use crate::Upvar;
use rustc_data_structures::graph::dominators::Dominators;
use rustc_middle::mir::BorrowKind;
use rustc_middle::mir::{BasicBlock, Body, Field, Location, Place, PlaceRef, ProjectionElem};
use rustc_middle::mir::{BasicBlock, Body, Location, Place, PlaceRef, ProjectionElem};
use rustc_middle::ty::TyCtxt;
use rustc_target::abi::FieldIdx;
/// Returns `true` if the borrow represented by `kind` is
/// allowed to be split into separate Reservation and
@ -148,7 +149,7 @@ pub(crate) fn is_upvar_field_projection<'tcx>(
upvars: &[Upvar<'tcx>],
place_ref: PlaceRef<'tcx>,
body: &Body<'tcx>,
) -> Option<Field> {
) -> Option<FieldIdx> {
let mut place_ref = place_ref;
let mut by_ref = false;

View File

@ -36,7 +36,7 @@ use rustc_middle::ty::{
};
use rustc_span::def_id::CRATE_DEF_ID;
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::FIRST_VARIANT;
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints;
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
@ -786,7 +786,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
&mut self,
parent: &dyn fmt::Debug,
base_ty: PlaceTy<'tcx>,
field: Field,
field: FieldIdx,
location: Location,
) -> Result<Ty<'tcx>, FieldAccessError> {
let tcx = self.tcx();

View File

@ -327,7 +327,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_
ArgKind::Spread(params) => {
for (i, param) in params.into_iter().enumerate() {
if let Some(param) = param {
place.place_field(fx, mir::Field::new(i)).write_cvalue(fx, param);
place.place_field(fx, FieldIdx::new(i)).write_cvalue(fx, param);
}
}
}
@ -460,7 +460,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
args.push(self_arg);
for i in 0..tupled_arguments.len() {
args.push(CallArgument {
value: pack_arg.value.value_field(fx, mir::Field::new(i)),
value: pack_arg.value.value_field(fx, FieldIdx::new(i)),
is_owned: pack_arg.is_owned,
});
}

View File

@ -797,7 +797,7 @@ fn codegen_stmt<'tcx>(
let index = fx.bcx.ins().iconst(fx.pointer_type, field_index as i64);
variant_dest.place_index(fx, index)
} else {
variant_dest.place_field(fx, mir::Field::new(field_index))
variant_dest.place_field(fx, FieldIdx::new(field_index))
};
to.write_cvalue(fx, operand);
}

View File

@ -26,7 +26,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
tag_encoding: TagEncoding::Direct,
variants: _,
} => {
let ptr = place.place_field(fx, mir::Field::new(tag_field));
let ptr = place.place_field(fx, FieldIdx::new(tag_field));
let to = layout.ty.discriminant_for_variant(fx.tcx, variant_index).unwrap().val;
let to = if ptr.layout().abi.is_signed() {
ty::ScalarInt::try_from_int(
@ -47,7 +47,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
variants: _,
} => {
if variant_index != untagged_variant {
let niche = place.place_field(fx, mir::Field::new(tag_field));
let niche = place.place_field(fx, FieldIdx::new(tag_field));
let niche_type = fx.clif_type(niche.layout().ty).unwrap();
let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();
let niche_value = (niche_value as u128).wrapping_add(niche_start);
@ -107,7 +107,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
let cast_to = fx.clif_type(dest_layout.ty).unwrap();
// Read the tag/niche-encoded discriminant from memory.
let tag = value.value_field(fx, mir::Field::new(tag_field));
let tag = value.value_field(fx, FieldIdx::new(tag_field));
let tag = tag.load_scalar(fx);
// Decode the discriminant (specifically if it's niche-encoded).

View File

@ -179,8 +179,8 @@ fn llvm_add_sub<'tcx>(
// c + carry -> c + first intermediate carry or borrow respectively
let int0 = crate::num::codegen_checked_int_binop(fx, bin_op, a, b);
let c = int0.value_field(fx, mir::Field::new(0));
let cb0 = int0.value_field(fx, mir::Field::new(1)).load_scalar(fx);
let c = int0.value_field(fx, FieldIdx::new(0));
let cb0 = int0.value_field(fx, FieldIdx::new(1)).load_scalar(fx);
// c + carry -> c + second intermediate carry or borrow respectively
let cb_in_as_u64 = fx.bcx.ins().uextend(types::I64, cb_in);

View File

@ -253,7 +253,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
}
ret.write_cvalue(fx, base);
let ret_lane = ret.place_field(fx, mir::Field::new(idx.try_into().unwrap()));
let ret_lane = ret.place_field(fx, FieldIdx::new(idx.try_into().unwrap()));
ret_lane.write_cvalue(fx, val);
}

View File

@ -86,7 +86,7 @@ mod prelude {
self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut,
TypeFoldable, TypeVisitableExt, UintTy,
};
pub(crate) use rustc_target::abi::{Abi, Scalar, Size, VariantIdx, FIRST_VARIANT};
pub(crate) use rustc_target::abi::{Abi, FieldIdx, Scalar, Size, VariantIdx, FIRST_VARIANT};
pub(crate) use rustc_data_structures::fx::FxHashMap;

View File

@ -147,8 +147,8 @@ pub(crate) fn coerce_unsized_into<'tcx>(
assert_eq!(def_a, def_b);
for i in 0..def_a.variant(FIRST_VARIANT).fields.len() {
let src_f = src.value_field(fx, mir::Field::new(i));
let dst_f = dst.place_field(fx, mir::Field::new(i));
let src_f = src.value_field(fx, FieldIdx::new(i));
let dst_f = dst.place_field(fx, FieldIdx::new(i));
if dst_f.layout().is_zst() {
continue;

View File

@ -10,7 +10,7 @@ fn codegen_field<'tcx>(
base: Pointer,
extra: Option<Value>,
layout: TyAndLayout<'tcx>,
field: mir::Field,
field: FieldIdx,
) -> (Pointer, TyAndLayout<'tcx>) {
let field_offset = layout.fields.offset(field.index());
let field_layout = layout.field(&*fx, field.index());
@ -210,7 +210,7 @@ impl<'tcx> CValue<'tcx> {
pub(crate) fn value_field(
self,
fx: &mut FunctionCx<'_, '_, 'tcx>,
field: mir::Field,
field: FieldIdx,
) -> CValue<'tcx> {
let layout = self.1;
match self.0 {
@ -687,7 +687,7 @@ impl<'tcx> CPlace<'tcx> {
pub(crate) fn place_field(
self,
fx: &mut FunctionCx<'_, '_, 'tcx>,
field: mir::Field,
field: FieldIdx,
) -> CPlace<'tcx> {
let layout = self.layout();

View File

@ -50,7 +50,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
if let Abi::Scalar(_) = arg.layout().abi {
'descend_newtypes: while !arg.layout().ty.is_unsafe_ptr() && !arg.layout().ty.is_ref() {
for i in 0..arg.layout().fields.count() {
let field = arg.value_field(fx, mir::Field::new(i));
let field = arg.value_field(fx, FieldIdx::new(i));
if !field.layout().is_zst() {
// we found the one non-zero-sized field that is allowed
// now find *its* non-zero-sized field, or stop if it's a
@ -68,9 +68,9 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
if ty.is_dyn_star() {
let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap().ty);
let dyn_star = CPlace::for_ptr(Pointer::new(arg.load_scalar(fx)), inner_layout);
let ptr = dyn_star.place_field(fx, mir::Field::new(0)).to_ptr();
let ptr = dyn_star.place_field(fx, FieldIdx::new(0)).to_ptr();
let vtable =
dyn_star.place_field(fx, mir::Field::new(1)).to_cvalue(fx).load_scalar(fx);
dyn_star.place_field(fx, FieldIdx::new(1)).to_cvalue(fx).load_scalar(fx);
break 'block (ptr, vtable);
}
}

View File

@ -27,7 +27,8 @@ codegen_llvm_error_calling_dlltool =
Error calling dlltool: {$error}
codegen_llvm_dlltool_fail_import_library =
Dlltool could not create import library: {$stdout}\n{$stderr}
Dlltool could not create import library: {$stdout}
{$stderr}
codegen_llvm_target_feature_disable_or_enable =
the target features {$features} must all be either enabled or disabled together

View File

@ -6,7 +6,7 @@ use rustc_hir::def::CtorKind;
use rustc_index::vec::IndexVec;
use rustc_middle::{
bug,
mir::{Field, GeneratorLayout, GeneratorSavedLocal},
mir::{GeneratorLayout, GeneratorSavedLocal},
ty::{
self,
layout::{IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout},
@ -14,7 +14,9 @@ use rustc_middle::{
},
};
use rustc_span::Symbol;
use rustc_target::abi::{HasDataLayout, Integer, Primitive, TagEncoding, VariantIdx, Variants};
use rustc_target::abi::{
FieldIdx, HasDataLayout, Integer, Primitive, TagEncoding, VariantIdx, Variants,
};
use std::borrow::Cow;
use crate::{
@ -353,7 +355,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
let state_specific_fields: SmallVec<_> = (0..variant_layout.fields.count())
.map(|field_index| {
let generator_saved_local = generator_layout.variant_fields[variant_index]
[Field::from_usize(field_index)];
[FieldIdx::from_usize(field_index)];
let field_name_maybe = state_specific_upvar_names[generator_saved_local];
let field_name = field_name_maybe
.as_ref()

View File

@ -8,7 +8,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
use rustc_session::config::DebugInfo;
use rustc_span::symbol::{kw, Symbol};
use rustc_span::{BytePos, Span};
use rustc_target::abi::{Abi, Size, VariantIdx};
use rustc_target::abi::{Abi, FieldIdx, Size, VariantIdx};
use super::operand::{OperandRef, OperandValue};
use super::place::PlaceRef;
@ -79,7 +79,7 @@ impl<'tcx, S: Copy, L: Copy> DebugScope<S, L> {
trait DebugInfoOffsetLocation<'tcx, Bx> {
fn deref(&self, bx: &mut Bx) -> Self;
fn layout(&self) -> TyAndLayout<'tcx>;
fn project_field(&self, bx: &mut Bx, field: mir::Field) -> Self;
fn project_field(&self, bx: &mut Bx, field: FieldIdx) -> Self;
fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self;
}
@ -94,7 +94,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx>
self.layout
}
fn project_field(&self, bx: &mut Bx, field: mir::Field) -> Self {
fn project_field(&self, bx: &mut Bx, field: FieldIdx) -> Self {
PlaceRef::project_field(*self, bx, field.index())
}
@ -116,7 +116,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx>
*self
}
fn project_field(&self, bx: &mut Bx, field: mir::Field) -> Self {
fn project_field(&self, bx: &mut Bx, field: FieldIdx) -> Self {
self.field(bx.cx(), field.index())
}

View File

@ -39,17 +39,25 @@ const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn
const_eval_unallowed_mutable_refs =
mutable references are not allowed in the final value of {$kind}s
.teach_note =
References in statics and constants may only refer to immutable values.\n\n
References in statics and constants may only refer to immutable values.
Statics are shared everywhere, and if they refer to mutable data one might violate memory
safety since holding multiple mutable references to shared data is not allowed.\n\n
safety since holding multiple mutable references to shared data is not allowed.
If you really want global mutable state, try using static mut or a global UnsafeCell.
const_eval_unallowed_mutable_refs_raw =
raw mutable references are not allowed in the final value of {$kind}s
.teach_note =
References in statics and constants may only refer to immutable values.\n\n
References in statics and constants may only refer to immutable values.
Statics are shared everywhere, and if they refer to mutable data one might violate memory
safety since holding multiple mutable references to shared data is not allowed.\n\n
safety since holding multiple mutable references to shared data is not allowed.
If you really want global mutable state, try using static mut or a global UnsafeCell.
const_eval_non_const_fmt_macro_call =

View File

@ -24,7 +24,7 @@ incremental_field_associated_value_expected = associated value expected for `{$n
incremental_no_field = no field `{$name}`
incremental_assertion_auto =
`except` specified DepNodes that can not be affected for \"{$name}\": \"{$e}\"
`except` specified DepNodes that can not be affected for "{$name}": "{$e}"
incremental_undefined_clean_dirty_assertions_item =
clean/dirty auto-assertions not yet defined for Node::Item.node={$kind}

View File

@ -91,7 +91,7 @@ lint_ty_qualified = usage of qualified `ty::{$ty}`
lint_lintpass_by_hand = implementing `LintPass` by hand
.help = try using `declare_lint_pass!` or `impl_lint_pass!` instead
lint_non_existant_doc_keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = \"...\")]`
lint_non_existant_doc_keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = "...")]`
.help = only existing keywords are allowed in core/std
lint_diag_out_of_impl =
@ -197,7 +197,9 @@ lint_drop_glue =
types that do not implement `Drop` can still have drop glue, consider instead using `{$needs_drop}` to detect whether a type is trivially dropped
lint_range_endpoint_out_of_range = range endpoint is out of range for `{$ty}`
.suggestion = use an inclusive range instead
lint_range_use_inclusive_range = use an inclusive range instead
lint_overflowing_bin_hex = literal out of range for `{$ty}`
.negative_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}`

View File

@ -1210,11 +1210,33 @@ impl<'a> DecorateLint<'a, ()> for DropGlue<'_> {
#[diag(lint_range_endpoint_out_of_range)]
pub struct RangeEndpointOutOfRange<'a> {
pub ty: &'a str,
#[suggestion(code = "{start}..={literal}{suffix}", applicability = "machine-applicable")]
pub suggestion: Span,
pub start: String,
pub literal: u128,
pub suffix: &'a str,
#[subdiagnostic]
pub sub: UseInclusiveRange<'a>,
}
#[derive(Subdiagnostic)]
pub enum UseInclusiveRange<'a> {
#[suggestion(
lint_range_use_inclusive_range,
code = "{start}..={literal}{suffix}",
applicability = "machine-applicable"
)]
WithoutParen {
#[primary_span]
sugg: Span,
start: String,
literal: u128,
suffix: &'a str,
},
#[multipart_suggestion(lint_range_use_inclusive_range, applicability = "machine-applicable")]
WithParen {
#[suggestion_part(code = "=")]
eq_sugg: Span,
#[suggestion_part(code = "{literal}{suffix}")]
lit_sugg: Span,
literal: u128,
suffix: &'a str,
},
}
#[derive(LintDiagnostic)]

View File

@ -4,7 +4,8 @@ use crate::{
AtomicOrderingFence, AtomicOrderingLoad, AtomicOrderingStore, ImproperCTypes,
InvalidAtomicOrderingDiag, OnlyCastu8ToChar, OverflowingBinHex, OverflowingBinHexSign,
OverflowingBinHexSub, OverflowingInt, OverflowingIntHelp, OverflowingLiteral,
OverflowingUInt, RangeEndpointOutOfRange, UnusedComparisons, VariantSizeDifferencesDiag,
OverflowingUInt, RangeEndpointOutOfRange, UnusedComparisons, UseInclusiveRange,
VariantSizeDifferencesDiag,
},
};
use crate::{LateContext, LateLintPass, LintContext};
@ -136,6 +137,14 @@ fn lint_overflowing_range_endpoint<'tcx>(
expr: &'tcx hir::Expr<'tcx>,
ty: &str,
) -> bool {
// Look past casts to support cases like `0..256 as u8`
let (expr, lit_span) = if let Node::Expr(par_expr) = cx.tcx.hir().get(cx.tcx.hir().parent_id(expr.hir_id))
&& let ExprKind::Cast(_, _) = par_expr.kind {
(par_expr, expr.span)
} else {
(expr, expr.span)
};
// We only want to handle exclusive (`..`) ranges,
// which are represented as `ExprKind::Struct`.
let par_id = cx.tcx.hir().parent_id(expr.hir_id);
@ -155,7 +164,6 @@ fn lint_overflowing_range_endpoint<'tcx>(
if !(eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max) {
return false;
};
let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) else { return false };
use rustc_ast::{LitIntType, LitKind};
let suffix = match lit.node {
@ -164,16 +172,28 @@ fn lint_overflowing_range_endpoint<'tcx>(
LitKind::Int(_, LitIntType::Unsuffixed) => "",
_ => bug!(),
};
cx.emit_spanned_lint(
OVERFLOWING_LITERALS,
struct_expr.span,
RangeEndpointOutOfRange {
ty,
suggestion: struct_expr.span,
let sub_sugg = if expr.span.lo() == lit_span.lo() {
let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) else { return false };
UseInclusiveRange::WithoutParen {
sugg: struct_expr.span.shrink_to_lo().to(lit_span.shrink_to_hi()),
start,
literal: lit_val - 1,
suffix,
},
}
} else {
UseInclusiveRange::WithParen {
eq_sugg: expr.span.shrink_to_lo(),
lit_sugg: lit_span,
literal: lit_val - 1,
suffix,
}
};
cx.emit_spanned_lint(
OVERFLOWING_LITERALS,
struct_expr.span,
RangeEndpointOutOfRange { ty, sub: sub_sugg },
);
// We've just emitted a lint, special cased for `(...)..MAX+1` ranges,

View File

@ -111,6 +111,18 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
.emit();
return failed(&crate_name);
}
let mut bad = false;
for esc in ["\\n", "\\\"", "\\'"] {
for _ in resource_contents.matches(esc) {
bad = true;
Diagnostic::spanned(resource_span, Level::Error, format!("invalid escape `{esc}` in Fluent resource"))
.note("Fluent does not interpret these escape sequences (<https://projectfluent.org/fluent/guide/special.html>)")
.emit();
}
}
if bad {
return failed(&crate_name);
}
let resource = match FluentResource::try_new(resource_contents) {
Ok(resource) => resource,

View File

@ -21,7 +21,7 @@ use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
use rustc_hir::{self, GeneratorKind, ImplicitSelfKind};
use rustc_hir::{self as hir, HirId};
use rustc_session::Session;
use rustc_target::abi::{Size, VariantIdx};
use rustc_target::abi::{FieldIdx, Size, VariantIdx};
use polonius_engine::Atom;
pub use rustc_ast::Mutability;
@ -1512,7 +1512,7 @@ impl<V, T> ProjectionElem<V, T> {
}
/// Returns `true` if this is a `Field` projection with the given index.
pub fn is_field_to(&self, f: Field) -> bool {
pub fn is_field_to(&self, f: FieldIdx) -> bool {
matches!(*self, Self::Field(x, _) if x == f)
}
}
@ -1521,22 +1521,6 @@ impl<V, T> ProjectionElem<V, T> {
/// need neither the `V` parameter for `Index` nor the `T` for `Field`.
pub type ProjectionKind = ProjectionElem<(), ()>;
rustc_index::newtype_index! {
/// A [newtype'd][wrapper] index type in the MIR [control-flow graph][CFG]
///
/// A field (e.g., `f` in `_1.f`) is one variant of [`ProjectionElem`]. Conceptually,
/// rustc can identify that a field projection refers to either two different regions of memory
/// or the same one between the base and the 'projection element'.
/// Read more about projections in the [rustc-dev-guide][mir-datatypes]
///
/// [wrapper]: https://rustc-dev-guide.rust-lang.org/appendix/glossary.html#newtype
/// [CFG]: https://rustc-dev-guide.rust-lang.org/appendix/background.html#cfg
/// [mir-datatypes]: https://rustc-dev-guide.rust-lang.org/mir/index.html#mir-data-types
#[derive(HashStable)]
#[debug_format = "field[{}]"]
pub struct Field {}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct PlaceRef<'tcx> {
pub local: Local,
@ -2685,12 +2669,17 @@ impl<'tcx> UserTypeProjections {
self.map_projections(|pat_ty_proj| pat_ty_proj.deref())
}
pub fn leaf(self, field: Field) -> Self {
pub fn leaf(self, field: FieldIdx) -> Self {
self.map_projections(|pat_ty_proj| pat_ty_proj.leaf(field))
}
pub fn variant(self, adt_def: AdtDef<'tcx>, variant_index: VariantIdx, field: Field) -> Self {
self.map_projections(|pat_ty_proj| pat_ty_proj.variant(adt_def, variant_index, field))
pub fn variant(
self,
adt_def: AdtDef<'tcx>,
variant_index: VariantIdx,
field_index: FieldIdx,
) -> Self {
self.map_projections(|pat_ty_proj| pat_ty_proj.variant(adt_def, variant_index, field_index))
}
}
@ -2733,7 +2722,7 @@ impl UserTypeProjection {
self
}
pub(crate) fn leaf(mut self, field: Field) -> Self {
pub(crate) fn leaf(mut self, field: FieldIdx) -> Self {
self.projs.push(ProjectionElem::Field(field, ()));
self
}
@ -2742,13 +2731,13 @@ impl UserTypeProjection {
mut self,
adt_def: AdtDef<'_>,
variant_index: VariantIdx,
field: Field,
field_index: FieldIdx,
) -> Self {
self.projs.push(ProjectionElem::Downcast(
Some(adt_def.variant(variant_index).name),
variant_index,
));
self.projs.push(ProjectionElem::Field(field, ()));
self.projs.push(ProjectionElem::Field(field_index, ()));
self
}
}

View File

@ -10,12 +10,12 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_index::bit_set::BitMatrix;
use rustc_index::vec::{Idx, IndexVec};
use rustc_span::Span;
use rustc_target::abi::VariantIdx;
use rustc_target::abi::{FieldIdx, VariantIdx};
use smallvec::SmallVec;
use std::cell::Cell;
use std::fmt::{self, Debug};
use super::{Field, SourceInfo};
use super::SourceInfo;
#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
pub enum UnsafetyViolationKind {
@ -152,7 +152,7 @@ pub struct GeneratorLayout<'tcx> {
/// Which of the above fields are in each variant. Note that one field may
/// be stored in multiple variants.
pub variant_fields: IndexVec<VariantIdx, IndexVec<Field, GeneratorSavedLocal>>,
pub variant_fields: IndexVec<VariantIdx, IndexVec<FieldIdx, GeneratorSavedLocal>>,
/// The source that led to each variant being created (usually, a yield or
/// await).
@ -229,7 +229,7 @@ pub struct BorrowCheckResult<'tcx> {
/// unerased regions.
pub concrete_opaque_types: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
pub closure_requirements: Option<ClosureRegionRequirements<'tcx>>,
pub used_mut_upvars: SmallVec<[Field; 8]>,
pub used_mut_upvars: SmallVec<[FieldIdx; 8]>,
pub tainted_by_errors: Option<ErrorGuaranteed>,
}
@ -353,7 +353,7 @@ pub enum ConstraintCategory<'tcx> {
/// like `Foo { field: my_val }`)
Usage,
OpaqueType,
ClosureUpvar(Field),
ClosureUpvar(FieldIdx),
/// A constraint from a user-written predicate
/// with the provided span, written on the item
@ -375,7 +375,7 @@ pub enum ConstraintCategory<'tcx> {
#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)]
pub enum ReturnConstraint {
Normal,
ClosureUpvar(Field),
ClosureUpvar(FieldIdx),
}
/// The subject of a `ClosureOutlivesRequirement` -- that is, the thing

View File

@ -3,7 +3,7 @@
//! This is in a dedicated file so that changes to this file can be reviewed more carefully.
//! The intention is that this file only contains datatype declarations, no code.
use super::{BasicBlock, Constant, Field, Local, SwitchTargets, UserTypeProjection};
use super::{BasicBlock, Constant, Local, SwitchTargets, UserTypeProjection};
use crate::mir::coverage::{CodeRegion, CoverageKind};
use crate::traits::Reveal;
@ -16,7 +16,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir};
use rustc_hir::{self, GeneratorKind};
use rustc_target::abi::VariantIdx;
use rustc_target::abi::{FieldIdx, VariantIdx};
use rustc_ast::Mutability;
use rustc_span::def_id::LocalDefId;
@ -888,7 +888,15 @@ pub struct Place<'tcx> {
#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
pub enum ProjectionElem<V, T> {
Deref,
Field(Field, T),
/// A field (e.g., `f` in `_1.f`) is one variant of [`ProjectionElem`]. Conceptually,
/// rustc can identify that a field projection refers to either two different regions of memory
/// or the same one between the base and the 'projection element'.
/// Read more about projections in the [rustc-dev-guide][mir-datatypes]
///
/// [mir-datatypes]: https://rustc-dev-guide.rust-lang.org/mir/index.html#mir-data-types
Field(FieldIdx, T),
/// Index into a slice/array.
///
/// Note that this does not also dereference, and so it does not exactly correspond to slice

View File

@ -6,7 +6,7 @@
use crate::mir::*;
use crate::ty::{self, Ty, TyCtxt};
use rustc_hir as hir;
use rustc_target::abi::VariantIdx;
use rustc_target::abi::{FieldIdx, VariantIdx};
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)]
pub struct PlaceTy<'tcx> {
@ -33,7 +33,7 @@ impl<'tcx> PlaceTy<'tcx> {
///
/// Note that the resulting type has not been normalized.
#[instrument(level = "debug", skip(tcx), ret)]
pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: Field) -> Ty<'tcx> {
pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: FieldIdx) -> Ty<'tcx> {
match self.ty.kind() {
ty::Adt(adt_def, substs) => {
let variant_def = match self.variant_index {
@ -61,14 +61,14 @@ impl<'tcx> PlaceTy<'tcx> {
/// `place_ty.projection_ty_core(tcx, elem, |...| { ... })`
/// projects `place_ty` onto `elem`, returning the appropriate
/// `Ty` or downcast variant corresponding to that projection.
/// The `handle_field` callback must map a `Field` to its `Ty`,
/// The `handle_field` callback must map a `FieldIdx` to its `Ty`,
/// (which should be trivial when `T` = `Ty`).
pub fn projection_ty_core<V, T>(
self,
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
elem: &ProjectionElem<V, T>,
mut handle_field: impl FnMut(&Self, Field, T) -> Ty<'tcx>,
mut handle_field: impl FnMut(&Self, FieldIdx, T) -> Ty<'tcx>,
mut handle_opaque_cast: impl FnMut(&Self, T) -> Ty<'tcx>,
) -> PlaceTy<'tcx>
where

View File

@ -12,6 +12,7 @@ use rustc_hir::hir_id::{HirId, OwnerId};
use rustc_query_system::query::{DefaultCacheSelector, SingleCacheSelector, VecCacheSelector};
use rustc_span::symbol::{Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::FieldIdx;
/// Placeholder for `CrateNum`'s "local" counterpart
#[derive(Copy, Clone, Debug)]
@ -332,7 +333,7 @@ impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) {
}
}
impl<'tcx> Key for (ty::Const<'tcx>, mir::Field) {
impl<'tcx> Key for (ty::Const<'tcx>, FieldIdx) {
type CacheSelector = DefaultCacheSelector<Self>;
fn default_span(&self, _: TyCtxt<'_>) -> Span {

View File

@ -17,14 +17,14 @@ use rustc_index::newtype_index;
use rustc_index::vec::IndexVec;
use rustc_middle::middle::region;
use rustc_middle::mir::interpret::AllocId;
use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, Field, Mutability, UnOp};
use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, Mutability, UnOp};
use rustc_middle::ty::adjustment::PointerCast;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, AdtDef, FnSig, Ty, UpvarSubsts};
use rustc_middle::ty::{CanonicalUserType, CanonicalUserTypeAnnotation};
use rustc_span::def_id::LocalDefId;
use rustc_span::{sym, Span, Symbol, DUMMY_SP};
use rustc_target::abi::VariantIdx;
use rustc_target::abi::{FieldIdx, VariantIdx};
use rustc_target::asm::InlineAsmRegOrRegClass;
use std::fmt;
use std::ops::Index;
@ -366,7 +366,7 @@ pub enum ExprKind<'tcx> {
/// Variant containing the field.
variant_index: VariantIdx,
/// This can be a named (`.foo`) or unnamed (`.0`) field.
name: Field,
name: FieldIdx,
},
/// A *non-overloaded* indexing operation.
Index {
@ -491,7 +491,7 @@ pub enum ExprKind<'tcx> {
/// This is used in struct constructors.
#[derive(Clone, Debug, HashStable)]
pub struct FieldExpr {
pub name: Field,
pub name: FieldIdx,
pub expr: ExprId,
}
@ -570,7 +570,7 @@ pub enum BindingMode {
#[derive(Clone, Debug, HashStable)]
pub struct FieldPat<'tcx> {
pub field: Field,
pub field: FieldIdx,
pub pattern: Box<Pat<'tcx>>,
}

View File

@ -12,9 +12,7 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
use crate::middle::resolve_bound_vars;
use crate::middle::stability;
use crate::mir::interpret::{self, Allocation, ConstAllocation};
use crate::mir::{
Body, BorrowCheckResult, Field, Local, Place, PlaceElem, ProjectionKind, Promoted,
};
use crate::mir::{Body, BorrowCheckResult, Local, Place, PlaceElem, ProjectionKind, Promoted};
use crate::query::LocalCrate;
use crate::thir::Thir;
use crate::traits;
@ -65,7 +63,7 @@ use rustc_span::def_id::{DefPathHash, StableCrateId};
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx};
use rustc_target::abi::{FieldIdx, Layout, LayoutS, TargetDataLayout, VariantIdx};
use rustc_target::spec::abi;
use rustc_type_ir::sty::TyKind::*;
use rustc_type_ir::WithCachedTypeInfo;
@ -2125,7 +2123,7 @@ impl<'tcx> TyCtxt<'tcx> {
}
}
pub fn mk_place_field(self, place: Place<'tcx>, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {
pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
self.mk_place_elem(place, PlaceElem::Field(f, ty))
}

View File

@ -4,7 +4,7 @@
//! to help with the tedium.
use crate::mir::interpret;
use crate::mir::{Field, ProjectionKind};
use crate::mir::ProjectionKind;
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
@ -217,6 +217,7 @@ CloneLiftImpls! {
// implementation and traversal implementations (the latter only for
// TyCtxt<'_> interners).
TrivialTypeTraversalAndLiftImpls! {
::rustc_target::abi::FieldIdx,
::rustc_target::abi::VariantIdx,
crate::middle::region::Scope,
crate::ty::FloatTy,
@ -268,7 +269,6 @@ TrivialTypeTraversalAndLiftImpls! {
::rustc_span::Span,
::rustc_span::symbol::Ident,
::rustc_errors::ErrorGuaranteed,
Field,
interpret::Scalar,
rustc_target::abi::Size,
ty::BoundVar,

View File

@ -3,7 +3,7 @@ use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::ty::cast::mir_cast_kind;
use rustc_middle::{mir::*, thir::*, ty};
use rustc_span::Span;
use rustc_target::abi::VariantIdx;
use rustc_target::abi::{FieldIdx, VariantIdx};
use crate::build::custom::ParseError;
use crate::build::expr::as_constant::as_constant_inner;
@ -223,7 +223,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
let (parent, proj) = parse_by_kind!(self, expr_id, expr, "place",
@call("mir_field", args) => {
let (parent, ty) = self.parse_place_inner(args[0])?;
let field = Field::from_u32(self.parse_integer_literal(args[1])? as u32);
let field = FieldIdx::from_u32(self.parse_integer_literal(args[1])? as u32);
let field_ty = ty.field_ty(self.tcx, field);
let proj = PlaceElem::Field(field, field_ty);
let place = parent.project_deeper(&[proj], self.tcx);

View File

@ -13,7 +13,7 @@ use rustc_middle::thir::*;
use rustc_middle::ty::AdtDef;
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, Variance};
use rustc_span::Span;
use rustc_target::abi::{VariantIdx, FIRST_VARIANT};
use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
use std::assert_matches::assert_matches;
use std::iter;
@ -293,7 +293,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
&self.projection
}
pub(crate) fn field(self, f: Field, ty: Ty<'tcx>) -> Self {
pub(crate) fn field(self, f: FieldIdx, ty: Ty<'tcx>) -> Self {
self.project(PlaceElem::Field(f, ty))
}

View File

@ -17,6 +17,7 @@ use rustc_middle::thir::*;
use rustc_middle::ty::cast::{mir_cast_kind, CastTy};
use rustc_middle::ty::{self, Ty, UpvarSubsts};
use rustc_span::Span;
use rustc_target::abi::FieldIdx;
impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Returns an rvalue suitable for use until the end of the current
@ -553,8 +554,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
result_value,
Rvalue::CheckedBinaryOp(op, Box::new((lhs.to_copy(), rhs.to_copy()))),
);
let val_fld = Field::new(0);
let of_fld = Field::new(1);
let val_fld = FieldIdx::new(0);
let of_fld = FieldIdx::new(1);
let tcx = self.tcx;
let val = tcx.mk_place_field(result_value, val_fld, ty);

View File

@ -10,6 +10,7 @@ use rustc_index::vec::Idx;
use rustc_middle::mir::*;
use rustc_middle::thir::*;
use rustc_middle::ty::CanonicalUserTypeAnnotation;
use rustc_target::abi::FieldIdx;
use std::iter;
impl<'a, 'tcx> Builder<'a, 'tcx> {
@ -344,7 +345,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.collect();
let field_names: Vec<_> =
(0..adt_def.variant(variant_index).fields.len()).map(Field::new).collect();
(0..adt_def.variant(variant_index).fields.len()).map(FieldIdx::new).collect();
let fields: Vec<_> = if let Some(FruInfo { base, field_types }) = base {
let place_builder =

View File

@ -25,6 +25,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_span::Symbol;
use rustc_target::abi::FieldIdx;
use rustc_target::spec::abi::Abi;
use super::lints;
@ -793,7 +794,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let mutability = captured_place.mutability;
let mut projs = closure_env_projs.clone();
projs.push(ProjectionElem::Field(Field::new(i), ty));
projs.push(ProjectionElem::Field(FieldIdx::new(i), ty));
match capture {
ty::UpvarCapture::ByValue => {}
ty::UpvarCapture::ByRef(..) => {

View File

@ -10,7 +10,7 @@ use rustc_middle::hir::place::Place as HirPlace;
use rustc_middle::hir::place::PlaceBase as HirPlaceBase;
use rustc_middle::hir::place::ProjectionKind as HirProjectionKind;
use rustc_middle::middle::region;
use rustc_middle::mir::{self, BinOp, BorrowKind, Field, UnOp};
use rustc_middle::mir::{self, BinOp, BorrowKind, UnOp};
use rustc_middle::thir::*;
use rustc_middle::ty::adjustment::{
Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCast,
@ -20,7 +20,7 @@ use rustc_middle::ty::{
self, AdtKind, InlineConstSubsts, InlineConstSubstsParts, ScalarInt, Ty, UpvarSubsts, UserType,
};
use rustc_span::{sym, Span};
use rustc_target::abi::FIRST_VARIANT;
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
impl<'tcx> Cx<'tcx> {
pub(crate) fn mirror_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> ExprId {
@ -379,7 +379,7 @@ impl<'tcx> Cx<'tcx> {
.iter()
.enumerate()
.map(|(idx, e)| FieldExpr {
name: Field::new(idx),
name: FieldIdx::new(idx),
expr: self.mirror_expr(e),
})
.collect();
@ -733,7 +733,7 @@ impl<'tcx> Cx<'tcx> {
hir::ExprKind::Field(ref source, ..) => ExprKind::Field {
lhs: self.mirror_expr(source),
variant_index: FIRST_VARIANT,
name: Field::new(self.typeck_results.field_index(expr.hir_id)),
name: FieldIdx::new(self.typeck_results.field_index(expr.hir_id)),
},
hir::ExprKind::Cast(ref source, ref cast_ty) => {
// Check for a user-given type annotation on this `cast`
@ -1053,7 +1053,7 @@ impl<'tcx> Cx<'tcx> {
HirProjectionKind::Field(field, variant_index) => ExprKind::Field {
lhs: self.thir.exprs.push(captured_place_expr),
variant_index,
name: Field::new(field as usize),
name: FieldIdx::new(field as usize),
},
HirProjectionKind::Index | HirProjectionKind::Subslice => {
// We don't capture these projections, so we can ignore them here
@ -1107,7 +1107,7 @@ impl<'tcx> Cx<'tcx> {
fields
.iter()
.map(|field| FieldExpr {
name: Field::new(self.typeck_results.field_index(field.hir_id)),
name: FieldIdx::new(self.typeck_results.field_index(field.hir_id)),
expr: self.mirror_expr(field.expr),
})
.collect()

View File

@ -2,11 +2,12 @@ use rustc_hir as hir;
use rustc_index::vec::Idx;
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::Obligation;
use rustc_middle::mir::{self, Field};
use rustc_middle::mir;
use rustc_middle::thir::{FieldPat, Pat, PatKind};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_session::lint;
use rustc_span::Span;
use rustc_target::abi::FieldIdx;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
use rustc_trait_selection::traits::{self, ObligationCause};
@ -218,7 +219,7 @@ impl<'tcx> ConstToPat<'tcx> {
) -> Result<Vec<FieldPat<'tcx>>, FallbackToConstRef> {
vals.enumerate()
.map(|(idx, val)| {
let field = Field::new(idx);
let field = FieldIdx::new(idx);
Ok(FieldPat { field, pattern: self.recur(val, false)? })
})
.collect()

View File

@ -53,14 +53,14 @@ use smallvec::{smallvec, SmallVec};
use rustc_data_structures::captures::Captures;
use rustc_hir::{HirId, RangeEnd};
use rustc_index::vec::Idx;
use rustc_middle::mir::{self, Field};
use rustc_middle::mir;
use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange};
use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef};
use rustc_middle::{middle::stability::EvalResult, mir::interpret::ConstValue};
use rustc_session::lint;
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::{Integer, Size, VariantIdx, FIRST_VARIANT};
use rustc_target::abi::{FieldIdx, Integer, Size, VariantIdx, FIRST_VARIANT};
use self::Constructor::*;
use self::SliceKind::*;
@ -1126,7 +1126,7 @@ impl<'tcx> SplitWildcard<'tcx> {
/// Note that the number of fields of a constructor may not match the fields declared in the
/// original struct/variant. This happens if a private or `non_exhaustive` field is uninhabited,
/// because the code mustn't observe that it is uninhabited. In that case that field is not
/// included in `fields`. For that reason, when you have a `mir::Field` you must use
/// included in `fields`. For that reason, when you have a `FieldIdx` you must use
/// `index_with_declared_idx`.
#[derive(Debug, Clone, Copy)]
pub(super) struct Fields<'p, 'tcx> {
@ -1165,7 +1165,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
cx: &'a MatchCheckCtxt<'p, 'tcx>,
ty: Ty<'tcx>,
variant: &'a VariantDef,
) -> impl Iterator<Item = (Field, Ty<'tcx>)> + Captures<'a> + Captures<'p> {
) -> impl Iterator<Item = (FieldIdx, Ty<'tcx>)> + Captures<'a> + Captures<'p> {
let ty::Adt(adt, substs) = ty.kind() else { bug!() };
// Whether we must not match the fields of this variant exhaustively.
let is_non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did().is_local();
@ -1180,7 +1180,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
if is_uninhabited && (!is_visible || is_non_exhaustive) {
None
} else {
Some((Field::new(i), ty))
Some((FieldIdx::new(i), ty))
}
})
}
@ -1438,7 +1438,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
ty::Tuple(..) => PatKind::Leaf {
subpatterns: subpatterns
.enumerate()
.map(|(i, pattern)| FieldPat { field: Field::new(i), pattern })
.map(|(i, pattern)| FieldPat { field: FieldIdx::new(i), pattern })
.collect(),
},
ty::Adt(adt_def, _) if adt_def.is_box() => {

View File

@ -21,12 +21,13 @@ use rustc_middle::mir::interpret::{
ConstValue, ErrorHandled, LitToConstError, LitToConstInput, Scalar,
};
use rustc_middle::mir::{self, UserTypeProjection};
use rustc_middle::mir::{BorrowKind, Field, Mutability};
use rustc_middle::mir::{BorrowKind, Mutability};
use rustc_middle::thir::{Ascription, BindingMode, FieldPat, LocalVarId, Pat, PatKind, PatRange};
use rustc_middle::ty::subst::{GenericArg, SubstsRef};
use rustc_middle::ty::CanonicalUserTypeAnnotation;
use rustc_middle::ty::{self, AdtDef, ConstKind, Region, Ty, TyCtxt, UserType};
use rustc_span::{Span, Symbol};
use rustc_target::abi::FieldIdx;
use std::cmp::Ordering;
@ -356,7 +357,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
let subpatterns = fields
.iter()
.map(|field| FieldPat {
field: Field::new(self.typeck_results.field_index(field.hir_id)),
field: FieldIdx::new(self.typeck_results.field_index(field.hir_id)),
pattern: self.lower_pattern(&field.pat),
})
.collect();
@ -379,7 +380,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
pats.iter()
.enumerate_and_adjust(expected_len, gap_pos)
.map(|(i, subpattern)| FieldPat {
field: Field::new(i),
field: FieldIdx::new(i),
pattern: self.lower_pattern(subpattern),
})
.collect()
@ -723,7 +724,7 @@ macro_rules! ClonePatternFoldableImpls {
}
ClonePatternFoldableImpls! { <'tcx>
Span, Field, Mutability, Symbol, LocalVarId, usize,
Span, FieldIdx, Mutability, Symbol, LocalVarId, usize,
Region<'tcx>, Ty<'tcx>, BindingMode, AdtDef<'tcx>,
SubstsRef<'tcx>, &'tcx GenericArg<'tcx>, UserType<'tcx>,
UserTypeProjection, CanonicalUserTypeAnnotation<'tcx>

View File

@ -7,7 +7,7 @@ use rustc_middle::traits::Reveal;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_target::abi::{VariantIdx, FIRST_VARIANT};
use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
use std::{fmt, iter};
/// The value of an inserted drop flag.
@ -129,7 +129,7 @@ pub trait DropElaborator<'a, 'tcx>: fmt::Debug {
/// Returns the subpath of a field of `path` (or `None` if there is no dedicated subpath).
///
/// If this returns `None`, `field` will not get a dedicated drop flag.
fn field_subpath(&self, path: Self::Path, field: Field) -> Option<Self::Path>;
fn field_subpath(&self, path: Self::Path, field: FieldIdx) -> Option<Self::Path>;
/// Returns the subpath of a dereference of `path` (or `None` if there is no dedicated subpath).
///
@ -269,7 +269,7 @@ where
.iter()
.enumerate()
.map(|(i, f)| {
let field = Field::new(i);
let field = FieldIdx::new(i);
let subpath = self.elaborator.field_subpath(variant_path, field);
let tcx = self.tcx();
@ -397,8 +397,8 @@ where
.enumerate()
.map(|(i, &ty)| {
(
self.tcx().mk_place_field(self.place, Field::new(i), ty),
self.elaborator.field_subpath(self.path, Field::new(i)),
self.tcx().mk_place_field(self.place, FieldIdx::new(i), ty),
self.elaborator.field_subpath(self.path, FieldIdx::new(i)),
)
})
.collect();
@ -416,9 +416,9 @@ where
unique_ty.ty_adt_def().unwrap().non_enum_variant().fields[0].ty(self.tcx(), substs);
let ptr_ty = self.tcx().mk_imm_ptr(substs[0].expect_ty());
let unique_place = self.tcx().mk_place_field(self.place, Field::new(0), unique_ty);
let nonnull_place = self.tcx().mk_place_field(unique_place, Field::new(0), nonnull_ty);
let ptr_place = self.tcx().mk_place_field(nonnull_place, Field::new(0), ptr_ty);
let unique_place = self.tcx().mk_place_field(self.place, FieldIdx::new(0), unique_ty);
let nonnull_place = self.tcx().mk_place_field(unique_place, FieldIdx::new(0), nonnull_ty);
let ptr_place = self.tcx().mk_place_field(nonnull_place, FieldIdx::new(0), ptr_ty);
let interior = self.tcx().mk_place_deref(ptr_place);
let interior_path = self.elaborator.deref_subpath(self.path);
@ -899,7 +899,7 @@ where
.iter()
.enumerate()
.map(|(i, f)| {
let field = Field::new(i);
let field = FieldIdx::new(i);
let field_ty = f.ty(tcx, substs);
Operand::Move(tcx.mk_place_field(self.place, field, field_ty))
})

View File

@ -40,7 +40,7 @@ use rustc_index::vec::IndexVec;
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_target::abi::VariantIdx;
use rustc_target::abi::{FieldIdx, VariantIdx};
use crate::lattice::{HasBottom, HasTop};
use crate::{
@ -919,7 +919,7 @@ impl<V: HasTop> ValueOrPlace<V> {
/// Although only field projections are currently allowed, this could change in the future.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum TrackElem {
Field(Field),
Field(FieldIdx),
Variant(VariantIdx),
Discriminant,
}
@ -941,7 +941,7 @@ pub fn iter_fields<'tcx>(
ty: Ty<'tcx>,
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
mut f: impl FnMut(Option<VariantIdx>, Field, Ty<'tcx>),
mut f: impl FnMut(Option<VariantIdx>, FieldIdx, Ty<'tcx>),
) {
match ty.kind() {
ty::Tuple(list) => {

View File

@ -13,8 +13,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_mir_dataflow::value_analysis::{Map, State, TrackElem, ValueAnalysis, ValueOrPlace};
use rustc_mir_dataflow::{lattice::FlatSet, Analysis, ResultsVisitor, SwitchIntEdgeEffects};
use rustc_span::DUMMY_SP;
use rustc_target::abi::Align;
use rustc_target::abi::VariantIdx;
use rustc_target::abi::{Align, FieldIdx, VariantIdx};
use crate::MirPass;
@ -148,7 +147,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
for (field_index, operand) in operands.iter().enumerate() {
if let Some(field) = self.map().apply(
variant_target_idx,
TrackElem::Field(Field::from_usize(field_index)),
TrackElem::Field(FieldIdx::from_usize(field_index)),
) {
let result = self.handle_operand(operand, state);
state.insert_idx(field, result, self.map());

View File

@ -9,6 +9,7 @@ use rustc_middle::mir::patch::MirPatch;
use rustc_middle::mir::visit::MutVisitor;
use rustc_middle::mir::*;
use rustc_middle::ty::{Ty, TyCtxt};
use rustc_target::abi::FieldIdx;
/// Constructs the types used when accessing a Box's pointer
pub fn build_ptr_tys<'tcx>(
@ -32,9 +33,9 @@ pub fn build_projection<'tcx>(
ptr_ty: Ty<'tcx>,
) -> [PlaceElem<'tcx>; 3] {
[
PlaceElem::Field(Field::new(0), unique_ty),
PlaceElem::Field(Field::new(0), nonnull_ty),
PlaceElem::Field(Field::new(0), ptr_ty),
PlaceElem::Field(FieldIdx::new(0), unique_ty),
PlaceElem::Field(FieldIdx::new(0), nonnull_ty),
PlaceElem::Field(FieldIdx::new(0), ptr_ty),
]
}

View File

@ -15,7 +15,7 @@ use rustc_mir_dataflow::MoveDataParamEnv;
use rustc_mir_dataflow::{on_all_children_bits, on_all_drop_children_bits};
use rustc_mir_dataflow::{Analysis, ResultsCursor};
use rustc_span::{DesugaringKind, Span};
use rustc_target::abi::VariantIdx;
use rustc_target::abi::{FieldIdx, VariantIdx};
use std::fmt;
/// During MIR building, Drop terminators are inserted in every place where a drop may occur.
@ -252,7 +252,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> {
}
}
fn field_subpath(&self, path: Self::Path, field: Field) -> Option<Self::Path> {
fn field_subpath(&self, path: Self::Path, field: FieldIdx) -> Option<Self::Path> {
rustc_mir_dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| match e {
ProjectionElem::Field(idx, _) => idx == field,
_ => false,

View File

@ -73,7 +73,7 @@ use rustc_mir_dataflow::{self, Analysis};
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_target::abi::VariantIdx;
use rustc_target::abi::{FieldIdx, VariantIdx};
use rustc_target::spec::PanicStrategy;
use std::{iter, ops};
@ -162,9 +162,10 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
place,
Place {
local: SELF_ARG,
projection: self
.tcx()
.mk_place_elems(&[ProjectionElem::Field(Field::new(0), self.ref_gen_ty)]),
projection: self.tcx().mk_place_elems(&[ProjectionElem::Field(
FieldIdx::new(0),
self.ref_gen_ty,
)]),
},
self.tcx,
);
@ -297,7 +298,7 @@ impl<'tcx> TransformVisitor<'tcx> {
let self_place = Place::from(SELF_ARG);
let base = self.tcx.mk_place_downcast_unnamed(self_place, variant_index);
let mut projection = base.projection.to_vec();
projection.push(ProjectionElem::Field(Field::new(idx), ty));
projection.push(ProjectionElem::Field(FieldIdx::new(idx), ty));
Place { local: base.local, projection: self.tcx.mk_place_elems(&projection) }
}
@ -967,7 +968,7 @@ fn compute_layout<'tcx>(
// Build the generator variant field list.
// Create a map from local indices to generator struct indices.
let mut variant_fields: IndexVec<VariantIdx, IndexVec<Field, GeneratorSavedLocal>> =
let mut variant_fields: IndexVec<VariantIdx, IndexVec<FieldIdx, GeneratorSavedLocal>> =
iter::repeat(IndexVec::new()).take(RESERVED_VARIANTS).collect();
let mut remap = FxHashMap::default();
for (suspension_point_idx, live_locals) in live_locals_at_suspension_points.iter().enumerate() {

View File

@ -10,7 +10,7 @@ use rustc_middle::mir::*;
use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
use rustc_session::config::OptLevel;
use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span};
use rustc_target::abi::FIRST_VARIANT;
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
use rustc_target::spec::abi::Abi;
use crate::simplify::{remove_dead_blocks, CfgSimplifier};
@ -701,7 +701,7 @@ impl<'tcx> Inliner<'tcx> {
// The `tmp0`, `tmp1`, and `tmp2` in our example above.
let tuple_tmp_args = tuple_tys.iter().enumerate().map(|(i, ty)| {
// This is e.g., `tuple_tmp.0` in our example above.
let tuple_field = Operand::Move(tcx.mk_place_field(tuple, Field::new(i), ty));
let tuple_field = Operand::Move(tcx.mk_place_field(tuple, FieldIdx::new(i), ty));
// Spill to a local to make e.g., `tmp0`.
self.create_temp_if_necessary(tuple_field, callsite, caller_body)

View File

@ -3,14 +3,14 @@
use crate::MirPass;
use rustc_hir::Mutability;
use rustc_middle::mir::{
BinOp, Body, CastKind, Constant, ConstantKind, Field, LocalDecls, Operand, Place,
ProjectionElem, Rvalue, SourceInfo, Statement, StatementKind, SwitchTargets, Terminator,
TerminatorKind, UnOp,
BinOp, Body, CastKind, Constant, ConstantKind, LocalDecls, Operand, Place, ProjectionElem,
Rvalue, SourceInfo, Statement, StatementKind, SwitchTargets, Terminator, TerminatorKind, UnOp,
};
use rustc_middle::ty::layout::ValidityRequirement;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, ParamEnv, SubstsRef, Ty, TyCtxt};
use rustc_span::symbol::Symbol;
use rustc_target::abi::FieldIdx;
pub struct InstCombine;
@ -187,7 +187,7 @@ impl<'tcx> InstCombineContext<'tcx, '_> {
for (i, field) in variant.fields.iter().enumerate() {
let field_ty = field.ty(self.tcx, substs);
if field_ty == *cast_ty {
let place = place.project_deeper(&[ProjectionElem::Field(Field::from_usize(i), *cast_ty)], self.tcx);
let place = place.project_deeper(&[ProjectionElem::Field(FieldIdx::from_usize(i), *cast_ty)], self.tcx);
let operand = if operand.is_move() { Operand::Move(place) } else { Operand::Copy(place) };
*rvalue = Rvalue::Use(operand);
return;

View File

@ -6,7 +6,7 @@ use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span;
use rustc_target::abi::VariantIdx;
use rustc_target::abi::{FieldIdx, VariantIdx};
pub struct LowerIntrinsics;
@ -211,7 +211,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
Some(sym::Some),
VariantIdx::from_u32(1),
),
PlaceElem::Field(Field::from_u32(0), *dest_ty),
PlaceElem::Field(FieldIdx::from_u32(0), *dest_ty),
],
tcx,
),

View File

@ -1,10 +1,11 @@
use rustc_index::bit_set::ChunkedBitSet;
use rustc_middle::mir::{Body, Field, TerminatorKind};
use rustc_middle::mir::{Body, TerminatorKind};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, VariantDef};
use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex};
use rustc_mir_dataflow::{self, move_path_children_matching, Analysis, MoveDataParamEnv};
use rustc_target::abi::FieldIdx;
use crate::MirPass;
@ -130,7 +131,7 @@ fn is_needs_drop_and_init<'tcx>(
.fields
.iter()
.enumerate()
.map(|(f, field)| (Field::from_usize(f), field.ty(tcx, substs), mpi))
.map(|(f, field)| (FieldIdx::from_usize(f), field.ty(tcx, substs), mpi))
.any(field_needs_drop_and_init)
})
}
@ -138,7 +139,7 @@ fn is_needs_drop_and_init<'tcx>(
ty::Tuple(fields) => fields
.iter()
.enumerate()
.map(|(f, f_ty)| (Field::from_usize(f), f_ty, mpi))
.map(|(f, f_ty)| (FieldIdx::from_usize(f), f_ty, mpi))
.any(field_needs_drop_and_init),
_ => true,

View File

@ -5,7 +5,7 @@ use rustc_middle::mir::*;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::InternalSubsts;
use rustc_middle::ty::{self, EarlyBinder, GeneratorSubsts, Ty, TyCtxt};
use rustc_target::abi::{VariantIdx, FIRST_VARIANT};
use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
use rustc_index::vec::{Idx, IndexVec};
@ -309,7 +309,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> {
fn clear_drop_flag(&mut self, _location: Location, _path: Self::Path, _mode: DropFlagMode) {}
fn field_subpath(&self, _path: Self::Path, _field: Field) -> Option<Self::Path> {
fn field_subpath(&self, _path: Self::Path, _field: FieldIdx) -> Option<Self::Path> {
None
}
fn deref_subpath(&self, _path: Self::Path) -> Option<Self::Path> {
@ -530,7 +530,7 @@ impl<'tcx> CloneShimBuilder<'tcx> {
// created by block 2*i. We store this block in `unwind` so that the next clone block
// will unwind to it if cloning fails.
let field = Field::new(i);
let field = FieldIdx::new(i);
let src_field = self.tcx.mk_place_field(src, field, ity);
let dest_field = self.tcx.mk_place_field(dest, field, ity);
@ -753,7 +753,7 @@ fn build_call_shim<'tcx>(
if let Some(untuple_args) = untuple_args {
let tuple_arg = Local::new(1 + (sig.inputs().len() - 1));
args.extend(untuple_args.iter().enumerate().map(|(i, ity)| {
Operand::Move(tcx.mk_place_field(Place::from(tuple_arg), Field::new(i), *ity))
Operand::Move(tcx.mk_place_field(Place::from(tuple_arg), FieldIdx::new(i), *ity))
}));
}

View File

@ -6,6 +6,7 @@ use rustc_middle::mir::visit::*;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_mir_dataflow::value_analysis::{excluded_locals, iter_fields};
use rustc_target::abi::FieldIdx;
pub struct ScalarReplacementOfAggregates;
@ -115,7 +116,7 @@ fn escaping_locals(excluded: &BitSet<Local>, body: &Body<'_>) -> BitSet<Local> {
struct ReplacementMap<'tcx> {
/// Pre-computed list of all "new" locals for each "old" local. This is used to expand storage
/// and deinit statement and debuginfo.
fragments: IndexVec<Local, Option<IndexVec<Field, Option<(Ty<'tcx>, Local)>>>>,
fragments: IndexVec<Local, Option<IndexVec<FieldIdx, Option<(Ty<'tcx>, Local)>>>>,
}
impl<'tcx> ReplacementMap<'tcx> {
@ -129,7 +130,7 @@ impl<'tcx> ReplacementMap<'tcx> {
fn place_fragments(
&self,
place: Place<'tcx>,
) -> Option<impl Iterator<Item = (Field, Ty<'tcx>, Local)> + '_> {
) -> Option<impl Iterator<Item = (FieldIdx, Ty<'tcx>, Local)> + '_> {
let local = place.as_local()?;
let fields = self.fragments[local].as_ref()?;
Some(fields.iter_enumerated().filter_map(|(field, &opt_ty_local)| {

View File

@ -6,6 +6,7 @@ use super::trait_goals::structural_traits::*;
use super::{EvalCtxt, SolverMode};
use crate::traits::coherence;
use itertools::Itertools;
use rustc_data_structures::fx::FxIndexSet;
use rustc_hir::def_id::DefId;
use rustc_infer::traits::query::NoSolution;
use rustc_infer::traits::util::elaborate_predicates;
@ -489,9 +490,21 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
};
let tcx = self.tcx();
for assumption in
elaborate_predicates(tcx, bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty)))
{
let own_bounds: FxIndexSet<_> =
bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty)).collect();
for assumption in elaborate_predicates(tcx, own_bounds.iter().copied()) {
// FIXME: Predicates are fully elaborated in the object type's existential bounds
// list. We want to only consider these pre-elaborated projections, and not other
// projection predicates that we reach by elaborating the principal trait ref,
// since that'll cause ambiguity.
//
// We can remove this when we have implemented intersections in responses.
if assumption.to_opt_poly_projection_pred().is_some()
&& !own_bounds.contains(&assumption)
{
continue;
}
match G::consider_object_bound_candidate(self, goal, assumption) {
Ok(result) => {
candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })

View File

@ -6,9 +6,9 @@ use rustc_infer::infer::{
DefineOpaqueTypes, InferCtxt, InferOk, LateBoundRegionConversionTime, TyCtxtInferExt,
};
use rustc_infer::traits::query::NoSolution;
use rustc_infer::traits::solve::{CanonicalGoal, Certainty, MaybeCause, QueryResult};
use rustc_infer::traits::ObligationCause;
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::traits::solve::{CanonicalGoal, Certainty, MaybeCause, QueryResult};
use rustc_middle::ty::{
self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
TypeVisitor,
@ -16,13 +16,32 @@ use rustc_middle::ty::{
use rustc_span::DUMMY_SP;
use std::ops::ControlFlow;
use crate::traits::specialization_graph;
use super::search_graph::{self, OverflowHandler};
use super::SolverMode;
use super::{search_graph::SearchGraph, Goal};
mod canonical;
pub struct EvalCtxt<'a, 'tcx> {
// FIXME: should be private.
pub(super) infcx: &'a InferCtxt<'tcx>,
/// The inference context that backs (mostly) inference and placeholder terms
/// instantiated while solving goals.
///
/// NOTE: The `InferCtxt` that backs the `EvalCtxt` is intentionally private,
/// because the `InferCtxt` is much more general than `EvalCtxt`. Methods such
/// as `take_registered_region_obligations` can mess up query responses,
/// using `At::normalize` is totally wrong, calling `evaluate_root_goal` can
/// cause coinductive unsoundness, etc.
///
/// Methods that are generally of use for trait solving are *intentionally*
/// re-declared through the `EvalCtxt` below, often with cleaner signatures
/// since we don't care about things like `ObligationCause`s and `Span`s here.
/// If some `InferCtxt` method is missing, please first think defensively about
/// the method's compatibility with this solver, or if an existing one does
/// the job already.
infcx: &'a InferCtxt<'tcx>,
pub(super) var_values: CanonicalVarValues<'tcx>,
/// The highest universe index nameable by the caller.
///
@ -393,7 +412,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
if let &ty::Infer(ty::TyVar(vid)) = ty.kind() {
match self.infcx.probe_ty_var(vid) {
Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
Err(universe) => universe == self.universe(),
Err(universe) => universe == self.infcx.universe(),
}
} else {
false
@ -403,7 +422,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() {
match self.infcx.probe_const_var(vid) {
Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
Err(universe) => universe == self.universe(),
Err(universe) => universe == self.infcx.universe(),
}
} else {
false
@ -545,7 +564,43 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
self.infcx.fresh_substs_for_item(DUMMY_SP, def_id)
}
pub(super) fn universe(&self) -> ty::UniverseIndex {
self.infcx.universe()
pub(super) fn translate_substs(
&self,
param_env: ty::ParamEnv<'tcx>,
source_impl: DefId,
source_substs: ty::SubstsRef<'tcx>,
target_node: specialization_graph::Node,
) -> ty::SubstsRef<'tcx> {
crate::traits::translate_substs(
self.infcx,
param_env,
source_impl,
source_substs,
target_node,
)
}
pub(super) fn register_ty_outlives(&self, ty: Ty<'tcx>, lt: ty::Region<'tcx>) {
self.infcx.register_region_obligation_with_cause(ty, lt, &ObligationCause::dummy());
}
pub(super) fn register_region_outlives(&self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) {
// `b : a` ==> `a <= b`
// (inlined from `InferCtxt::region_outlives_predicate`)
self.infcx.sub_regions(
rustc_infer::infer::SubregionOrigin::RelateRegionParamBound(DUMMY_SP),
b,
a,
);
}
/// Computes the list of goals required for `arg` to be well-formed
pub(super) fn well_formed_goals(
&self,
param_env: ty::ParamEnv<'tcx>,
arg: ty::GenericArg<'tcx>,
) -> Option<impl Iterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>> {
crate::traits::wf::unnormalized_obligations(self.infcx, param_env, arg)
.map(|obligations| obligations.into_iter().map(|obligation| obligation.into()))
}
}

View File

@ -8,22 +8,19 @@
/// section of the [rustc-dev-guide][c].
///
/// [c]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html
use self::canonicalize::{CanonicalizeMode, Canonicalizer};
use super::{CanonicalGoal, Certainty, EvalCtxt, Goal};
use super::{CanonicalResponse, ExternalConstraints, QueryResult, Response};
use crate::solve::canonicalize::{CanonicalizeMode, Canonicalizer};
use crate::solve::{CanonicalResponse, QueryResult, Response};
use rustc_infer::infer::canonical::query_response::make_query_region_constraints;
use rustc_infer::infer::canonical::CanonicalVarValues;
use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints};
use rustc_infer::traits::query::NoSolution;
use rustc_infer::traits::solve::ExternalConstraintsData;
use rustc_infer::traits::ObligationCause;
use rustc_middle::traits::query::NoSolution;
use rustc_middle::traits::solve::{ExternalConstraints, ExternalConstraintsData};
use rustc_middle::ty::{self, GenericArgKind};
use rustc_span::DUMMY_SP;
use std::iter;
use std::ops::Deref;
mod canonicalize;
impl<'tcx> EvalCtxt<'_, 'tcx> {
/// Canonicalizes the goal remembering the original values
/// for each bound variable.
@ -48,7 +45,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
/// - `external_constraints`: additional constraints which aren't expressable
/// using simple unification of inference variables.
#[instrument(level = "debug", skip(self))]
pub(super) fn evaluate_added_goals_and_make_canonical_response(
pub(in crate::solve) fn evaluate_added_goals_and_make_canonical_response(
&mut self,
certainty: Certainty,
) -> QueryResult<'tcx> {
@ -219,15 +216,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
fn register_region_constraints(&mut self, region_constraints: &QueryRegionConstraints<'tcx>) {
for &(ty::OutlivesPredicate(lhs, rhs), _) in &region_constraints.outlives {
match lhs.unpack() {
GenericArgKind::Lifetime(lhs) => self.infcx.region_outlives_predicate(
&ObligationCause::dummy(),
ty::Binder::dummy(ty::OutlivesPredicate(lhs, rhs)),
),
GenericArgKind::Type(lhs) => self.infcx.register_region_obligation_with_cause(
lhs,
rhs,
&ObligationCause::dummy(),
),
GenericArgKind::Lifetime(lhs) => self.register_region_outlives(lhs, rhs),
GenericArgKind::Type(lhs) => self.register_ty_outlives(lhs, rhs),
GenericArgKind::Const(_) => bug!("const outlives: {lhs:?}: {rhs:?}"),
}
}

View File

@ -13,18 +13,15 @@ use rustc_hir::def_id::DefId;
use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues};
use rustc_infer::traits::query::NoSolution;
use rustc_middle::traits::solve::{
CanonicalGoal, CanonicalResponse, Certainty, ExternalConstraints, ExternalConstraintsData,
Goal, QueryResult, Response,
CanonicalResponse, Certainty, ExternalConstraintsData, Goal, QueryResult, Response,
};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{
CoercePredicate, RegionOutlivesPredicate, SubtypePredicate, TypeOutlivesPredicate,
};
use crate::traits::ObligationCause;
mod assembly;
mod canonical;
mod canonicalize;
mod eval_ctxt;
mod fulfill;
mod project_goals;
@ -66,7 +63,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
goal: Goal<'tcx, TypeOutlivesPredicate<'tcx>>,
) -> QueryResult<'tcx> {
let ty::OutlivesPredicate(ty, lt) = goal.predicate;
self.infcx.register_region_obligation_with_cause(ty, lt, &ObligationCause::dummy());
self.register_ty_outlives(ty, lt);
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}
@ -75,10 +72,8 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
&mut self,
goal: Goal<'tcx, RegionOutlivesPredicate<'tcx>>,
) -> QueryResult<'tcx> {
self.infcx.region_outlives_predicate(
&ObligationCause::dummy(),
ty::Binder::dummy(goal.predicate),
);
let ty::OutlivesPredicate(a, b) = goal.predicate;
self.register_region_outlives(a, b);
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}
@ -142,13 +137,9 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
&mut self,
goal: Goal<'tcx, ty::GenericArg<'tcx>>,
) -> QueryResult<'tcx> {
match crate::traits::wf::unnormalized_obligations(
self.infcx,
goal.param_env,
goal.predicate,
) {
Some(obligations) => {
self.add_goals(obligations.into_iter().map(|o| o.into()));
match self.well_formed_goals(goal.param_env, goal.predicate) {
Some(goals) => {
self.add_goals(goals);
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}
None => self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS),

View File

@ -1,4 +1,4 @@
use crate::traits::{specialization_graph, translate_substs};
use crate::traits::specialization_graph;
use super::assembly;
use super::trait_goals::structural_traits;
@ -7,7 +7,6 @@ use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::LangItem;
use rustc_infer::infer::InferCtxt;
use rustc_infer::traits::query::NoSolution;
use rustc_infer::traits::specialization_graph::LeafDef;
use rustc_infer::traits::Reveal;
@ -165,7 +164,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
// return ambiguity this would otherwise be incomplete, resulting in
// unsoundness during coherence (#105782).
let Some(assoc_def) = fetch_eligible_assoc_item_def(
ecx.infcx,
ecx,
goal.param_env,
goal_trait_ref,
goal.predicate.def_id(),
@ -196,8 +195,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
goal_trait_ref.def_id,
impl_substs,
);
let substs = translate_substs(
ecx.infcx,
let substs = ecx.translate_substs(
goal.param_env,
impl_def_id,
impl_substs_with_gat,
@ -504,15 +502,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
///
/// FIXME: We should merge these 3 implementations as it's likely that they otherwise
/// diverge.
#[instrument(level = "debug", skip(infcx, param_env), ret)]
#[instrument(level = "debug", skip(ecx, param_env), ret)]
fn fetch_eligible_assoc_item_def<'tcx>(
infcx: &InferCtxt<'tcx>,
ecx: &EvalCtxt<'_, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
goal_trait_ref: ty::TraitRef<'tcx>,
trait_assoc_def_id: DefId,
impl_def_id: DefId,
) -> Result<Option<LeafDef>, NoSolution> {
let node_item = specialization_graph::assoc_def(infcx.tcx, impl_def_id, trait_assoc_def_id)
let node_item = specialization_graph::assoc_def(ecx.tcx(), impl_def_id, trait_assoc_def_id)
.map_err(|ErrorGuaranteed { .. }| NoSolution)?;
let eligible = if node_item.is_final() {
@ -524,7 +522,7 @@ fn fetch_eligible_assoc_item_def<'tcx>(
// transmute checking and polymorphic MIR optimizations could
// get a result which isn't correct for all monomorphizations.
if param_env.reveal() == Reveal::All {
let poly_trait_ref = infcx.resolve_vars_if_possible(goal_trait_ref);
let poly_trait_ref = ecx.resolve_vars_if_possible(goal_trait_ref);
!poly_trait_ref.still_further_specializable()
} else {
debug!(?node_item.item.def_id, "not eligible due to default");

View File

@ -14,8 +14,6 @@ use core::ptr::{self, NonNull};
#[doc(inline)]
pub use core::alloc::*;
use core::marker::Destruct;
#[cfg(test)]
mod tests;
@ -331,16 +329,12 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
#[cfg_attr(not(test), lang = "box_free")]
#[inline]
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
// This signature has to be the same as `Box`, otherwise an ICE will happen.
// When an additional parameter to `Box` is added (like `A: Allocator`), this has to be added here as
// well.
// For example if `Box` is changed to `struct Box<T: ?Sized, A: Allocator>(Unique<T>, A)`,
// this function has to be changed to `fn box_free<T: ?Sized, A: Allocator>(Unique<T>, A)` as well.
pub(crate) const unsafe fn box_free<T: ?Sized, A: ~const Allocator + ~const Destruct>(
ptr: Unique<T>,
alloc: A,
) {
pub(crate) unsafe fn box_free<T: ?Sized, A: Allocator>(ptr: Unique<T>, alloc: A) {
unsafe {
let size = size_of_val(ptr.as_ref());
let align = min_align_of_val(ptr.as_ref());

View File

@ -328,10 +328,9 @@ impl<B: ?Sized + ToOwned> Cow<'_, B> {
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
impl<B: ?Sized + ToOwned> const Deref for Cow<'_, B>
impl<B: ?Sized + ToOwned> Deref for Cow<'_, B>
where
B::Owned: ~const Borrow<B>,
B::Owned: Borrow<B>,
{
type Target = B;

View File

@ -159,7 +159,7 @@ use core::hash::{Hash, Hasher};
use core::iter::FromIterator;
use core::iter::{FusedIterator, Iterator};
use core::marker::Tuple;
use core::marker::{Destruct, Unpin, Unsize};
use core::marker::{Unpin, Unsize};
use core::mem;
use core::ops::{
CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Generator, GeneratorState, Receiver,
@ -376,12 +376,11 @@ impl<T, A: Allocator> Box<T, A> {
/// ```
#[cfg(not(no_global_oom_handling))]
#[unstable(feature = "allocator_api", issue = "32838")]
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
#[must_use]
#[inline]
pub const fn new_in(x: T, alloc: A) -> Self
pub fn new_in(x: T, alloc: A) -> Self
where
A: ~const Allocator + ~const Destruct,
A: Allocator,
{
let mut boxed = Self::new_uninit_in(alloc);
unsafe {
@ -406,12 +405,10 @@ impl<T, A: Allocator> Box<T, A> {
/// # Ok::<(), std::alloc::AllocError>(())
/// ```
#[unstable(feature = "allocator_api", issue = "32838")]
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
#[inline]
pub const fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError>
pub fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError>
where
T: ~const Destruct,
A: ~const Allocator + ~const Destruct,
A: Allocator,
{
let mut boxed = Self::try_new_uninit_in(alloc)?;
unsafe {
@ -441,13 +438,12 @@ impl<T, A: Allocator> Box<T, A> {
/// assert_eq!(*five, 5)
/// ```
#[unstable(feature = "allocator_api", issue = "32838")]
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
#[cfg(not(no_global_oom_handling))]
#[must_use]
// #[unstable(feature = "new_uninit", issue = "63291")]
pub const fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
pub fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
where
A: ~const Allocator + ~const Destruct,
A: Allocator,
{
let layout = Layout::new::<mem::MaybeUninit<T>>();
// NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable.
@ -482,10 +478,9 @@ impl<T, A: Allocator> Box<T, A> {
/// ```
#[unstable(feature = "allocator_api", issue = "32838")]
// #[unstable(feature = "new_uninit", issue = "63291")]
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
pub const fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
pub fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
where
A: ~const Allocator + ~const Destruct,
A: Allocator,
{
let layout = Layout::new::<mem::MaybeUninit<T>>();
let ptr = alloc.allocate(layout)?.cast();
@ -513,13 +508,12 @@ impl<T, A: Allocator> Box<T, A> {
///
/// [zeroed]: mem::MaybeUninit::zeroed
#[unstable(feature = "allocator_api", issue = "32838")]
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
#[cfg(not(no_global_oom_handling))]
// #[unstable(feature = "new_uninit", issue = "63291")]
#[must_use]
pub const fn new_zeroed_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
pub fn new_zeroed_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
where
A: ~const Allocator + ~const Destruct,
A: Allocator,
{
let layout = Layout::new::<mem::MaybeUninit<T>>();
// NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable.
@ -554,10 +548,9 @@ impl<T, A: Allocator> Box<T, A> {
/// [zeroed]: mem::MaybeUninit::zeroed
#[unstable(feature = "allocator_api", issue = "32838")]
// #[unstable(feature = "new_uninit", issue = "63291")]
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
pub const fn try_new_zeroed_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
pub fn try_new_zeroed_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
where
A: ~const Allocator + ~const Destruct,
A: Allocator,
{
let layout = Layout::new::<mem::MaybeUninit<T>>();
let ptr = alloc.allocate_zeroed(layout)?.cast();
@ -573,12 +566,11 @@ impl<T, A: Allocator> Box<T, A> {
/// construct a (pinned) `Box` in a different way than with [`Box::new_in`].
#[cfg(not(no_global_oom_handling))]
#[unstable(feature = "allocator_api", issue = "32838")]
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
#[must_use]
#[inline(always)]
pub const fn pin_in(x: T, alloc: A) -> Pin<Self>
pub fn pin_in(x: T, alloc: A) -> Pin<Self>
where
A: 'static + ~const Allocator + ~const Destruct,
A: 'static + Allocator,
{
Self::into_pin(Self::new_in(x, alloc))
}
@ -605,12 +597,8 @@ impl<T, A: Allocator> Box<T, A> {
/// assert_eq!(Box::into_inner(c), 5);
/// ```
#[unstable(feature = "box_into_inner", issue = "80437")]
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
#[inline]
pub const fn into_inner(boxed: Self) -> T
where
Self: ~const Destruct,
{
pub fn into_inner(boxed: Self) -> T {
*boxed
}
}

View File

@ -179,18 +179,3 @@ unsafe impl const Allocator for ConstAllocator {
self
}
}
#[test]
fn const_box() {
const VALUE: u32 = {
let mut boxed = Box::new_in(1u32, ConstAllocator);
assert!(*boxed == 1);
*boxed = 42;
assert!(*boxed == 42);
*Box::leak(boxed)
};
assert!(VALUE == 42);
}

View File

@ -3,7 +3,6 @@
#![feature(assert_matches)]
#![feature(btree_drain_filter)]
#![feature(cow_is_borrowed)]
#![feature(const_box)]
#![feature(const_convert)]
#![feature(const_cow_is_borrowed)]
#![feature(const_heap)]

View File

@ -75,9 +75,18 @@ pub fn abort_internal() -> ! {
}
}
// FIXME: just a workaround to test the system
pub fn hashmap_random_keys() -> (u64, u64) {
(1, 2)
let mut buf = [0; 16];
let mut slice = &mut buf[..];
while !slice.is_empty() {
let res = cvt(unsafe { abi::read_entropy(slice.as_mut_ptr(), slice.len(), 0) })
.expect("failed to generate random hashmap keys");
slice = &mut slice[res as usize..];
}
let key1 = buf[..8].try_into().unwrap();
let key2 = buf[8..].try_into().unwrap();
(u64::from_ne_bytes(key1), u64::from_ne_bytes(key2))
}
// This function is needed by the panic runtime. The symbol is named in

View File

@ -121,9 +121,14 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
// strip things like impl methods but when doing so
// we must not add any items to the `retained` set.
let old = mem::replace(&mut self.update_retained, false);
let ret = strip_item(self.set_is_in_hidden_item_and_fold(true, i));
let ret = self.set_is_in_hidden_item_and_fold(true, i);
self.update_retained = old;
Some(ret)
if ret.is_crate() {
// We don't strip the crate, even if it has `#[doc(hidden)]`.
Some(ret)
} else {
Some(strip_item(ret))
}
}
_ => {
let ret = self.set_is_in_hidden_item_and_fold(true, i);

View File

@ -0,0 +1,8 @@
// This test ensures that even if the crate module is `#[doc(hidden)]`, the file
// is generated.
// @has 'foo/index.html'
// @has 'foo/all.html'
#![crate_name = "foo"]
#![doc(hidden)]

View File

@ -0,0 +1 @@
no_crate_bad_escape = don't use \n, \', or \"

View File

@ -92,3 +92,12 @@ mod missing_message_ref {
fluent_messages! { "./missing-message-ref.ftl" }
//~^ ERROR referenced message `message` does not exist
}
mod bad_escape {
use super::fluent_messages;
fluent_messages! { "./invalid-escape.ftl" }
//~^ ERROR invalid escape `\n`
//~| ERROR invalid escape `\"`
//~| ERROR invalid escape `\'`
}

View File

@ -83,5 +83,29 @@ LL | fluent_messages! { "./missing-message-ref.ftl" }
|
= help: you may have meant to use a variable reference (`{$message}`)
error: aborting due to 10 previous errors
error: invalid escape `\n` in Fluent resource
--> $DIR/test.rs:99:24
|
LL | fluent_messages! { "./invalid-escape.ftl" }
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: os-specific message
error: invalid escape `\"` in Fluent resource
--> $DIR/test.rs:99:24
|
LL | fluent_messages! { "./invalid-escape.ftl" }
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: os-specific message
error: invalid escape `\'` in Fluent resource
--> $DIR/test.rs:99:24
|
LL | fluent_messages! { "./invalid-escape.ftl" }
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: os-specific message
error: aborting due to 13 previous errors

View File

@ -1,4 +1,4 @@
error: found non-existing keyword `tadam` used in `#[doc(keyword = \"...\")]`
error: found non-existing keyword `tadam` used in `#[doc(keyword = "...")]`
--> $DIR/existing_doc_keyword.rs:10:1
|
LL | #[doc(keyword = "tadam")]

View File

@ -0,0 +1,6 @@
// run-rustfix
fn main() {
for _ in 0..=255 as u8 {} //~ ERROR range endpoint is out of range
for _ in 0..=(255 as u8) {} //~ ERROR range endpoint is out of range
}

View File

@ -0,0 +1,6 @@
// run-rustfix
fn main() {
for _ in 0..256 as u8 {} //~ ERROR range endpoint is out of range
for _ in 0..(256 as u8) {} //~ ERROR range endpoint is out of range
}

View File

@ -0,0 +1,23 @@
error: range endpoint is out of range for `u8`
--> $DIR/issue-109529.rs:4:14
|
LL | for _ in 0..256 as u8 {}
| ------^^^^^^
| |
| help: use an inclusive range instead: `0..=255`
|
= note: `#[deny(overflowing_literals)]` on by default
error: range endpoint is out of range for `u8`
--> $DIR/issue-109529.rs:5:14
|
LL | for _ in 0..(256 as u8) {}
| ^^^^^^^^^^^^^^
|
help: use an inclusive range instead
|
LL | for _ in 0..=(255 as u8) {}
| + ~~~
error: aborting due to 2 previous errors

View File

@ -0,0 +1,12 @@
// compile-flags: -Ztrait-solver=next
// check-pass
trait Iter<'a, I: 'a>: Iterator<Item = &'a I> {}
fn needs_iter<'a, T: Iter<'a, I> + ?Sized, I: 'a>(_: &T) {}
fn test(x: &dyn Iter<'_, ()>) {
needs_iter(x);
}
fn main() {}

View File

@ -10,7 +10,7 @@ trait Trait: SuperTrait<A = <Self as SuperTrait>::B> {}
fn transmute<A, B>(x: A) -> B {
foo::<A, B, dyn Trait<A = A, B = B>>(x)
//~^ ERROR type annotations needed: cannot satisfy `dyn Trait<A = A, B = B>: Trait`
//~^ ERROR the trait bound `dyn Trait<A = A, B = B>: Trait` is not satisfied
}
fn foo<A, B, T: ?Sized>(x: T::A) -> B

View File

@ -1,10 +1,9 @@
error[E0283]: type annotations needed: cannot satisfy `dyn Trait<A = A, B = B>: Trait`
--> $DIR/more-object-bound.rs:12:5
error[E0277]: the trait bound `dyn Trait<A = A, B = B>: Trait` is not satisfied
--> $DIR/more-object-bound.rs:12:17
|
LL | foo::<A, B, dyn Trait<A = A, B = B>>(x)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Trait<A = A, B = B>`
|
= note: cannot satisfy `dyn Trait<A = A, B = B>: Trait`
note: required by a bound in `foo`
--> $DIR/more-object-bound.rs:18:8
|
@ -13,7 +12,11 @@ LL | fn foo<A, B, T: ?Sized>(x: T::A) -> B
LL | where
LL | T: Trait<B = B>,
| ^^^^^^^^^^^^ required by this bound in `foo`
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | fn transmute<A, B>(x: A) -> B where dyn Trait<A = A, B = B>: Trait {
| ++++++++++++++++++++++++++++++++++++
error: aborting due to previous error
For more information about this error, try `rustc --explain E0283`.
For more information about this error, try `rustc --explain E0277`.