mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
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:
commit
2fb0e8d162
@ -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))]
|
||||
|
@ -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> {
|
||||
|
@ -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()
|
||||
|
@ -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())
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
});
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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).
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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())
|
||||
}
|
||||
|
||||
|
@ -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 =
|
||||
|
@ -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}
|
||||
|
@ -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}`
|
||||
|
@ -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)]
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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>>,
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 =
|
||||
|
@ -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(..) => {
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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() => {
|
||||
|
@ -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>
|
||||
|
@ -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))
|
||||
})
|
||||
|
@ -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) => {
|
||||
|
@ -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());
|
||||
|
@ -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),
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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() {
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
),
|
||||
|
@ -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,
|
||||
|
@ -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))
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -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)| {
|
||||
|
@ -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 })
|
||||
|
@ -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()))
|
||||
}
|
||||
}
|
||||
|
@ -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 ®ion_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:?}"),
|
||||
}
|
||||
}
|
@ -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),
|
||||
|
@ -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");
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
8
tests/rustdoc/issue-109695-crate-doc-hidden.rs
Normal file
8
tests/rustdoc/issue-109695-crate-doc-hidden.rs
Normal 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)]
|
1
tests/ui-fulldeps/fluent-messages/invalid-escape.ftl
Normal file
1
tests/ui-fulldeps/fluent-messages/invalid-escape.ftl
Normal file
@ -0,0 +1 @@
|
||||
no_crate_bad_escape = don't use \n, \', or \"
|
@ -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 `\'`
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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")]
|
||||
|
6
tests/ui/lint/issue-109529.fixed
Normal file
6
tests/ui/lint/issue-109529.fixed
Normal 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
|
||||
}
|
6
tests/ui/lint/issue-109529.rs
Normal file
6
tests/ui/lint/issue-109529.rs
Normal 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
|
||||
}
|
23
tests/ui/lint/issue-109529.stderr
Normal file
23
tests/ui/lint/issue-109529.stderr
Normal 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
|
||||
|
12
tests/ui/traits/new-solver/dont-elaborate-for-projections.rs
Normal file
12
tests/ui/traits/new-solver/dont-elaborate-for-projections.rs
Normal 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() {}
|
@ -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
|
||||
|
@ -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`.
|
||||
|
Loading…
Reference in New Issue
Block a user