Merge from rustc

This commit is contained in:
The Miri Conjob Bot 2023-07-16 06:33:33 +00:00
commit 2e4a190387
792 changed files with 10688 additions and 8202 deletions

View file

@ -11,6 +11,8 @@ trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 4
[*.rs]
max_line_length = 100
[*.md]

View file

@ -16,3 +16,5 @@ cf2dff2b1e3fa55fa5415d524200070d0d7aacfe
b39a1d6f1a30ba29f25d7141038b9a5bf0126e36
# reorder fluent message files
f97fddab91fbf290ea5b691fe355d6f915220b6e
# format let-else
cc907f80b95c6ec530c5ee1b05b044a468f07eca

View file

@ -299,10 +299,14 @@ Joseph T. Lyons <JosephTLyons@gmail.com> <JosephTLyons@users.noreply.github.com>
Josh Cotton <jcotton42@outlook.com>
Josh Driver <keeperofdakeys@gmail.com>
Josh Holmer <jholmer.in@gmail.com>
Joshua Nelson <jyn514@gmail.com> <joshua@yottadb.com>
Julian Knodt <julianknodt@gmail.com>
jumbatm <jumbatm@gmail.com> <30644300+jumbatm@users.noreply.github.com>
Junyoung Cho <june0.cho@samsung.com>
Jynn Nelson <github@jyn.dev> <jyn514@gmail.com>
Jynn Nelson <github@jyn.dev> <joshua@yottadb.com>
Jynn Nelson <github@jyn.dev> <jyn.nelson@redjack.com>
Jynn Nelson <github@jyn.dev> <jnelson@cloudflare.com>
Jynn Nelson <github@jyn.dev>
Jyun-Yan You <jyyou.tw@gmail.com> <jyyou@cs.nctu.edu.tw>
Kalita Alexey <kalita.alexey@outlook.com>
Kampfkarren <boynedmaster@gmail.com>

View file

@ -1529,9 +1529,9 @@ dependencies = [
[[package]]
name = "hermit-abi"
version = "0.3.1"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
dependencies = [
"compiler_builtins",
"rustc-std-workspace-alloc",
@ -1864,7 +1864,7 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
dependencies = [
"hermit-abi 0.3.1",
"hermit-abi 0.3.2",
"libc",
"windows-sys 0.48.0",
]
@ -1881,7 +1881,7 @@ version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24fddda5af7e54bf7da53067d6e802dbcc381d0a8eef629df528e3ebf68755cb"
dependencies = [
"hermit-abi 0.3.1",
"hermit-abi 0.3.2",
"rustix 0.38.2",
"windows-sys 0.48.0",
]
@ -2396,7 +2396,7 @@ version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [
"hermit-abi 0.3.1",
"hermit-abi 0.3.2",
"libc",
]
@ -4819,7 +4819,7 @@ dependencies = [
"dlmalloc",
"fortanix-sgx-abi",
"hashbrown 0.14.0",
"hermit-abi 0.3.1",
"hermit-abi 0.3.2",
"libc",
"miniz_oxide",
"object",

View file

@ -203,7 +203,7 @@ Stabilized APIs
- [`Default for std::collections::binary_heap::IntoIter`](https://doc.rust-lang.org/stable/std/collections/binary_heap/struct.IntoIter.html)
- [`Default for std::collections::btree_map::{IntoIter, Iter, IterMut}`](https://doc.rust-lang.org/stable/std/collections/btree_map/struct.IntoIter.html)
- [`Default for std::collections::btree_map::{IntoKeys, Keys}`](https://doc.rust-lang.org/stable/std/collections/btree_map/struct.IntoKeys.html)
- [`Default for std::collections::btree_map::{IntoValues, Values}`](https://doc.rust-lang.org/stable/std/collections/btree_map/struct.IntoKeys.html)
- [`Default for std::collections::btree_map::{IntoValues, Values}`](https://doc.rust-lang.org/stable/std/collections/btree_map/struct.IntoValues.html)
- [`Default for std::collections::btree_map::Range`](https://doc.rust-lang.org/stable/std/collections/btree_map/struct.Range.html)
- [`Default for std::collections::btree_set::{IntoIter, Iter}`](https://doc.rust-lang.org/stable/std/collections/btree_set/struct.IntoIter.html)
- [`Default for std::collections::btree_set::Range`](https://doc.rust-lang.org/stable/std/collections/btree_set/struct.Range.html)
@ -2618,7 +2618,7 @@ related tools.
[`OsStr::to_ascii_lowercase`]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html#method.to_ascii_lowercase
[`OsStr::to_ascii_uppercase`]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html#method.to_ascii_uppercase
[`Peekable::peek_mut`]: https://doc.rust-lang.org/std/iter/struct.Peekable.html#method.peek_mut
[`Rc::decrement_strong_count`]: https://doc.rust-lang.org/std/rc/struct.Rc.html#method.increment_strong_count
[`Rc::decrement_strong_count`]: https://doc.rust-lang.org/std/rc/struct.Rc.html#method.decrement_strong_count
[`Rc::increment_strong_count`]: https://doc.rust-lang.org/std/rc/struct.Rc.html#method.increment_strong_count
[`Vec::extend_from_within`]: https://doc.rust-lang.org/beta/std/vec/struct.Vec.html#method.extend_from_within
[`array::from_mut`]: https://doc.rust-lang.org/beta/std/array/fn.from_mut.html
@ -2627,7 +2627,7 @@ related tools.
[`cmp::max_by`]: https://doc.rust-lang.org/beta/std/cmp/fn.max_by.html
[`cmp::min_by_key`]: https://doc.rust-lang.org/beta/std/cmp/fn.min_by_key.html
[`cmp::min_by`]: https://doc.rust-lang.org/beta/std/cmp/fn.min_by.html
[`f32::is_subnormal`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_subnormal
[`f32::is_subnormal`]: https://doc.rust-lang.org/std/primitive.f32.html#method.is_subnormal
[`f64::is_subnormal`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_subnormal
[ietf6943]: https://datatracker.ietf.org/doc/html/rfc6943#section-3.1.1
@ -2963,7 +2963,7 @@ Internal Only
[`sync::OnceState`]: https://doc.rust-lang.org/stable/std/sync/struct.OnceState.html
[`panic::panic_any`]: https://doc.rust-lang.org/stable/std/panic/fn.panic_any.html
[`slice::strip_prefix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix
[`slice::strip_suffix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix
[`slice::strip_suffix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_suffix
[`Arc::increment_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.increment_strong_count
[`Arc::decrement_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.decrement_strong_count
[`slice::fill_with`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.fill_with
@ -8033,7 +8033,7 @@ Compatibility Notes
[39379]: https://github.com/rust-lang/rust/pull/39379
[41105]: https://github.com/rust-lang/rust/issues/41105
[`<*const T>::wrapping_offset`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_offset
[`<*mut T>::wrapping_offset`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_offset
[`<*mut T>::wrapping_offset`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_offset-1
[`Duration::checked_add`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.checked_add
[`Duration::checked_div`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.checked_div
[`Duration::checked_mul`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.checked_mul
@ -9011,7 +9011,7 @@ Stabilized APIs
* [`f64::to_radians`](https://doc.rust-lang.org/std/primitive.f64.html#method.to_radians)
(in libcore - previously stabilized in libstd)
* [`Iterator::sum`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.sum)
* [`Iterator::product`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.sum)
* [`Iterator::product`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.product)
* [`Cell::get_mut`](https://doc.rust-lang.org/std/cell/struct.Cell.html#method.get_mut)
* [`RefCell::get_mut`](https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.get_mut)

View file

@ -40,6 +40,8 @@ pub trait LayoutCalculator {
largest_niche,
align,
size,
max_repr_align: None,
unadjusted_abi_align: align.abi,
}
}
@ -122,6 +124,8 @@ pub trait LayoutCalculator {
largest_niche: None,
align: dl.i8_align,
size: Size::ZERO,
max_repr_align: None,
unadjusted_abi_align: dl.i8_align.abi,
}
}
@ -289,6 +293,9 @@ pub trait LayoutCalculator {
}
let mut align = dl.aggregate_align;
let mut max_repr_align = repr.align;
let mut unadjusted_abi_align = align.abi;
let mut variant_layouts = variants
.iter_enumerated()
.map(|(j, v)| {
@ -296,6 +303,8 @@ pub trait LayoutCalculator {
st.variants = Variants::Single { index: j };
align = align.max(st.align);
max_repr_align = max_repr_align.max(st.max_repr_align);
unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align);
Some(st)
})
@ -422,6 +431,8 @@ pub trait LayoutCalculator {
largest_niche,
size,
align,
max_repr_align,
unadjusted_abi_align,
};
Some(TmpLayout { layout, variants: variant_layouts })
@ -456,6 +467,9 @@ pub trait LayoutCalculator {
let (min_ity, signed) = discr_range_of_repr(min, max); //Integer::repr_discr(tcx, ty, &repr, min, max);
let mut align = dl.aggregate_align;
let mut max_repr_align = repr.align;
let mut unadjusted_abi_align = align.abi;
let mut size = Size::ZERO;
// We're interested in the smallest alignment, so start large.
@ -498,6 +512,8 @@ pub trait LayoutCalculator {
}
size = cmp::max(size, st.size);
align = align.max(st.align);
max_repr_align = max_repr_align.max(st.max_repr_align);
unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align);
Some(st)
})
.collect::<Option<IndexVec<VariantIdx, _>>>()?;
@ -691,6 +707,8 @@ pub trait LayoutCalculator {
abi,
align,
size,
max_repr_align,
unadjusted_abi_align,
};
let tagged_layout = TmpLayout { layout: tagged_layout, variants: layout_variants };
@ -730,10 +748,7 @@ pub trait LayoutCalculator {
let dl = self.current_data_layout();
let dl = dl.borrow();
let mut align = if repr.pack.is_some() { dl.i8_align } else { dl.aggregate_align };
if let Some(repr_align) = repr.align {
align = align.max(AbiAndPrefAlign::new(repr_align));
}
let mut max_repr_align = repr.align;
// If all the non-ZST fields have the same ABI and union ABI optimizations aren't
// disabled, we can use that common ABI for the union as a whole.
@ -751,6 +766,7 @@ pub trait LayoutCalculator {
assert!(field.0.is_sized());
align = align.max(field.align());
max_repr_align = max_repr_align.max(field.max_repr_align());
size = cmp::max(size, field.size());
if field.0.is_zst() {
@ -787,6 +803,14 @@ pub trait LayoutCalculator {
if let Some(pack) = repr.pack {
align = align.min(AbiAndPrefAlign::new(pack));
}
// The unadjusted ABI alignment does not include repr(align), but does include repr(pack).
// See documentation on `LayoutS::unadjusted_abi_align`.
let unadjusted_abi_align = align.abi;
if let Some(repr_align) = repr.align {
align = align.max(AbiAndPrefAlign::new(repr_align));
}
// `align` must not be modified after this, or `unadjusted_abi_align` could be inaccurate.
let align = align;
// If all non-ZST fields have the same ABI, we may forward that ABI
// for the union as a whole, unless otherwise inhibited.
@ -809,6 +833,8 @@ pub trait LayoutCalculator {
largest_niche: None,
align,
size: size.align_to(align.abi),
max_repr_align,
unadjusted_abi_align,
})
}
}
@ -829,6 +855,7 @@ fn univariant(
) -> Option<LayoutS> {
let pack = repr.pack;
let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
let mut max_repr_align = repr.align;
let mut inverse_memory_index: IndexVec<u32, FieldIdx> = fields.indices().collect();
let optimize = !repr.inhibit_struct_field_reordering_opt();
if optimize && fields.len() > 1 {
@ -997,6 +1024,7 @@ fn univariant(
};
offset = offset.align_to(field_align.abi);
align = align.max(field_align);
max_repr_align = max_repr_align.max(field.max_repr_align());
debug!("univariant offset: {:?} field: {:#?}", offset, field);
offsets[i] = offset;
@ -1018,9 +1046,16 @@ fn univariant(
offset = offset.checked_add(field.size(), dl)?;
}
// The unadjusted ABI alignment does not include repr(align), but does include repr(pack).
// See documentation on `LayoutS::unadjusted_abi_align`.
let unadjusted_abi_align = align.abi;
if let Some(repr_align) = repr.align {
align = align.max(AbiAndPrefAlign::new(repr_align));
}
// `align` must not be modified after this point, or `unadjusted_abi_align` could be inaccurate.
let align = align;
debug!("univariant min_size: {:?}", offset);
let min_size = offset;
// As stated above, inverse_memory_index holds field indices by increasing offset.
@ -1036,6 +1071,7 @@ fn univariant(
inverse_memory_index.into_iter().map(FieldIdx::as_u32).collect()
};
let size = min_size.align_to(align.abi);
let mut layout_of_single_non_zst_field = None;
let mut abi = Abi::Aggregate { sized };
// Unpack newtype ABIs and find scalar pairs.
if sized && size.bytes() > 0 {
@ -1045,6 +1081,8 @@ fn univariant(
match (non_zst_fields.next(), non_zst_fields.next(), non_zst_fields.next()) {
// We have exactly one non-ZST field.
(Some((i, field)), None, None) => {
layout_of_single_non_zst_field = Some(field);
// Field fills the struct and it has a scalar or scalar pair ABI.
if offsets[i].bytes() == 0 && align.abi == field.align().abi && size == field.size()
{
@ -1102,6 +1140,19 @@ fn univariant(
if fields.iter().any(|f| f.abi().is_uninhabited()) {
abi = Abi::Uninhabited;
}
let unadjusted_abi_align = if repr.transparent() {
match layout_of_single_non_zst_field {
Some(l) => l.unadjusted_abi_align(),
None => {
// `repr(transparent)` with all ZST fields.
align.abi
}
}
} else {
unadjusted_abi_align
};
Some(LayoutS {
variants: Variants::Single { index: FIRST_VARIANT },
fields: FieldsShape::Arbitrary { offsets, memory_index },
@ -1109,6 +1160,8 @@ fn univariant(
largest_niche,
align,
size,
max_repr_align,
unadjusted_abi_align,
})
}

View file

@ -1531,6 +1531,16 @@ pub struct LayoutS {
pub align: AbiAndPrefAlign,
pub size: Size,
/// The largest alignment explicitly requested with `repr(align)` on this type or any field.
/// Only used on i686-windows, where the argument passing ABI is different when alignment is
/// requested, even if the requested alignment is equal to the natural alignment.
pub max_repr_align: Option<Align>,
/// The alignment the type would have, ignoring any `repr(align)` but including `repr(packed)`.
/// Only used on aarch64-linux, where the argument passing ABI ignores the requested alignment
/// in some cases.
pub unadjusted_abi_align: Align,
}
impl LayoutS {
@ -1545,6 +1555,8 @@ impl LayoutS {
largest_niche,
size,
align,
max_repr_align: None,
unadjusted_abi_align: align.abi,
}
}
}
@ -1554,7 +1566,16 @@ impl fmt::Debug for LayoutS {
// This is how `Layout` used to print before it become
// `Interned<LayoutS>`. We print it like this to avoid having to update
// expected output in a lot of tests.
let LayoutS { size, align, abi, fields, largest_niche, variants } = self;
let LayoutS {
size,
align,
abi,
fields,
largest_niche,
variants,
max_repr_align,
unadjusted_abi_align,
} = self;
f.debug_struct("Layout")
.field("size", size)
.field("align", align)
@ -1562,6 +1583,8 @@ impl fmt::Debug for LayoutS {
.field("fields", fields)
.field("largest_niche", largest_niche)
.field("variants", variants)
.field("max_repr_align", max_repr_align)
.field("unadjusted_abi_align", unadjusted_abi_align)
.finish()
}
}
@ -1602,6 +1625,14 @@ impl<'a> Layout<'a> {
self.0.0.size
}
pub fn max_repr_align(self) -> Option<Align> {
self.0.0.max_repr_align
}
pub fn unadjusted_abi_align(self) -> Align {
self.0.0.unadjusted_abi_align
}
/// Whether the layout is from a type that implements [`std::marker::PointerLike`].
///
/// Currently, that means that the type is pointer-sized, pointer-aligned,

View file

@ -11,7 +11,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc;
use rustc_macros::HashStable_Generic;
use rustc_span::symbol::{kw, sym};
#[cfg_attr(not(bootstrap), allow(hidden_glob_reexports))]
#[allow(hidden_glob_reexports)]
use rustc_span::symbol::{Ident, Symbol};
use rustc_span::{self, edition::Edition, Span, DUMMY_SP};
use std::borrow::Cow;

View file

@ -352,7 +352,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let idx2 = *o.get();
let (ref op2, op_sp2) = operands[idx2];
let Some(asm::InlineAsmRegOrRegClass::Reg(reg2)) = op2.reg() else {
let Some(asm::InlineAsmRegOrRegClass::Reg(reg2)) = op2.reg()
else {
unreachable!();
};
@ -368,7 +369,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
assert!(!*late);
let out_op_sp = if input { op_sp2 } else { op_sp };
Some(out_op_sp)
},
}
_ => None,
};
@ -377,7 +378,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
op_span2: op_sp2,
reg1_name: reg.name(),
reg2_name: reg2.name(),
in_out
in_out,
});
}
Entry::Vacant(v) => {

View file

@ -7,8 +7,8 @@ use rustc_middle::mir::{
Body, Local, Location, Place, PlaceRef, ProjectionElem, Rvalue, SourceInfo, Statement,
StatementKind, Terminator, TerminatorKind, UserTypeProjection,
};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
use crate::{
@ -49,11 +49,11 @@ struct ConstraintGeneration<'cg, 'tcx> {
}
impl<'cg, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'tcx> {
/// We sometimes have `substs` within an rvalue, or within a
/// We sometimes have `args` within an rvalue, or within a
/// call. Make them live at the location where they appear.
fn visit_substs(&mut self, substs: &SubstsRef<'tcx>, location: Location) {
self.add_regular_live_constraint(*substs, location);
self.super_substs(substs);
fn visit_args(&mut self, args: &GenericArgsRef<'tcx>, location: Location) {
self.add_regular_live_constraint(*args, location);
self.super_args(args);
}
/// We sometimes have `region` within an rvalue, or within a

View file

@ -363,21 +363,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}
let hir = self.infcx.tcx.hir();
if let Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(_, _, body_id),
..
})) = hir.find(self.mir_hir_id())
&& let Some(hir::Node::Expr(expr)) = hir.find(body_id.hir_id)
{
if let Some(body_id) = hir.maybe_body_owned_by(self.mir_def_id()) {
let expr = hir.body(body_id).value;
let place = &self.move_data.move_paths[mpi].place;
let span = place.as_local()
.map(|local| self.body.local_decls[local].source_info.span);
let mut finder = ExpressionFinder {
expr_span: move_span,
expr: None,
pat: None,
parent_pat: None,
};
let span = place.as_local().map(|local| self.body.local_decls[local].source_info.span);
let mut finder =
ExpressionFinder { expr_span: move_span, expr: None, pat: None, parent_pat: None };
finder.visit_expr(expr);
if let Some(span) = span && let Some(expr) = finder.expr {
for (_, expr) in hir.parent_iter(expr.hir_id) {
@ -461,7 +452,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} = move_spans {
// We already suggest cloning for these cases in `explain_captures`.
} else {
self.suggest_cloning(err, ty, move_span);
self.suggest_cloning(err, ty, expr, move_span);
}
}
}
@ -702,11 +693,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
.iter()
.copied()
.find_map(find_fn_kind_from_did),
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => tcx
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => tcx
.explicit_item_bounds(def_id)
.subst_iter_copied(tcx, substs)
.arg_iter_copied(tcx, args)
.find_map(|(clause, span)| find_fn_kind_from_did((clause, span))),
ty::Closure(_, substs) => match substs.as_closure().kind() {
ty::Closure(_, args) => match args.as_closure().kind() {
ty::ClosureKind::Fn => Some(hir::Mutability::Not),
ty::ClosureKind::FnMut => Some(hir::Mutability::Mut),
_ => None,
@ -714,7 +705,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
_ => None,
};
let Some(borrow_level) = borrow_level else { return false; };
let Some(borrow_level) = borrow_level else {
return false;
};
let sugg = move_sites
.iter()
.map(|move_site| {
@ -734,9 +727,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
true
}
fn suggest_cloning(&self, err: &mut Diagnostic, ty: Ty<'tcx>, span: Span) {
fn suggest_cloning(
&self,
err: &mut Diagnostic,
ty: Ty<'tcx>,
expr: &hir::Expr<'_>,
span: Span,
) {
let tcx = self.infcx.tcx;
// Try to find predicates on *generic params* that would allow copying `ty`
let suggestion =
if let Some(symbol) = tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) {
format!(": {}.clone()", symbol)
} else {
".clone()".to_owned()
};
if let Some(clone_trait_def) = tcx.lang_items().clone_trait()
&& self.infcx
.type_implements_trait(
@ -749,7 +754,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
err.span_suggestion_verbose(
span.shrink_to_hi(),
"consider cloning the value if the performance cost is acceptable",
".clone()",
suggestion,
Applicability::MachineApplicable,
);
}
@ -763,7 +768,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
.typeck_root_def_id(self.mir_def_id().to_def_id())
.as_local()
.and_then(|def_id| tcx.hir().get_generics(def_id))
else { return; };
else {
return;
};
// Try to find predicates on *generic params* that would allow copying `ty`
let ocx = ObligationCtxt::new(&self.infcx);
let copy_did = tcx.require_lang_item(LangItem::Copy, Some(span));
@ -1220,18 +1227,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
return;
};
let inner_param_uses = find_all_local_uses::find(self.body, inner_param.local);
let Some((inner_call_loc, inner_call_term)) = inner_param_uses.into_iter().find_map(|loc| {
let Either::Right(term) = self.body.stmt_at(loc) else {
debug!("{:?} is a statement, so it can't be a call", loc);
return None;
};
let TerminatorKind::Call { args, .. } = &term.kind else {
debug!("not a call: {:?}", term);
return None;
};
debug!("checking call args for uses of inner_param: {:?}", args);
args.contains(&Operand::Move(inner_param)).then_some((loc, term))
}) else {
let Some((inner_call_loc, inner_call_term)) =
inner_param_uses.into_iter().find_map(|loc| {
let Either::Right(term) = self.body.stmt_at(loc) else {
debug!("{:?} is a statement, so it can't be a call", loc);
return None;
};
let TerminatorKind::Call { args, .. } = &term.kind else {
debug!("not a call: {:?}", term);
return None;
};
debug!("checking call args for uses of inner_param: {:?}", args);
args.contains(&Operand::Move(inner_param)).then_some((loc, term))
})
else {
debug!("no uses of inner_param found as a by-move call arg");
return;
};
@ -1442,21 +1451,24 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
// Get closure's arguments
let ty::Closure(_, substs) = typeck_results.expr_ty(closure_expr).kind() else { /* hir::Closure can be a generator too */ return };
let sig = substs.as_closure().sig();
let ty::Closure(_, args) = typeck_results.expr_ty(closure_expr).kind() else {
/* hir::Closure can be a generator too */
return;
};
let sig = args.as_closure().sig();
let tupled_params =
tcx.erase_late_bound_regions(sig.inputs().iter().next().unwrap().map_bound(|&b| b));
let ty::Tuple(params) = tupled_params.kind() else { return };
// Find the first argument with a matching type, get its name
let Some((_, this_name)) = params
.iter()
.zip(hir.body_param_names(closure.body))
.find(|(param_ty, name)|{
let Some((_, this_name)) =
params.iter().zip(hir.body_param_names(closure.body)).find(|(param_ty, name)| {
// FIXME: also support deref for stuff like `Rc` arguments
param_ty.peel_refs() == local_ty && name != &Ident::empty()
})
else { return };
else {
return;
};
let spans;
if let Some((_path_expr, qpath)) = finder.error_path
@ -2667,7 +2679,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
kind: TerminatorKind::Call { call_source: CallSource::OverloadedOperator, .. },
..
}),
Some((method_did, method_substs)),
Some((method_did, method_args)),
) = (
&self.body[loan.reserve_location.block].terminator,
rustc_middle::util::find_self_call(
@ -2680,7 +2692,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if tcx.is_diagnostic_item(sym::deref_method, method_did) {
let deref_target =
tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
Instance::resolve(tcx, self.param_env, deref_target, method_substs)
Instance::resolve(tcx, self.param_env, deref_target, method_args)
.transpose()
});
if let Some(Ok(instance)) = deref_target {
@ -2847,11 +2859,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if is_closure {
None
} else {
let ty = self.infcx.tcx.type_of(self.mir_def_id()).subst_identity();
let ty = self.infcx.tcx.type_of(self.mir_def_id()).instantiate_identity();
match ty.kind() {
ty::FnDef(_, _) | ty::FnPtr(_) => self.annotate_fn_sig(
self.mir_def_id(),
self.infcx.tcx.fn_sig(self.mir_def_id()).subst_identity(),
self.infcx.tcx.fn_sig(self.mir_def_id()).instantiate_identity(),
),
_ => None,
}
@ -2893,13 +2905,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
// Check if our `target` was captured by a closure.
if let Rvalue::Aggregate(
box AggregateKind::Closure(def_id, substs),
box AggregateKind::Closure(def_id, args),
operands,
) = rvalue
{
let def_id = def_id.expect_local();
for operand in operands {
let (Operand::Copy(assigned_from) | Operand::Move(assigned_from)) = operand else {
let (Operand::Copy(assigned_from) | Operand::Move(assigned_from)) =
operand
else {
continue;
};
debug!(
@ -2908,7 +2922,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
// Find the local from the operand.
let Some(assigned_from_local) = assigned_from.local_or_deref_local() else {
let Some(assigned_from_local) =
assigned_from.local_or_deref_local()
else {
continue;
};
@ -2920,7 +2936,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// into a place then we should annotate the closure in
// case it ends up being assigned into the return place.
annotated_closure =
self.annotate_fn_sig(def_id, substs.as_closure().sig());
self.annotate_fn_sig(def_id, args.as_closure().sig());
debug!(
"annotate_argument_and_return_for_borrow: \
annotated_closure={:?} assigned_from_local={:?} \
@ -2961,7 +2977,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
// Find the local from the rvalue.
let Some(assigned_from_local) = assigned_from.local_or_deref_local() else { continue };
let Some(assigned_from_local) = assigned_from.local_or_deref_local() else {
continue;
};
debug!(
"annotate_argument_and_return_for_borrow: \
assigned_from_local={:?}",
@ -3009,7 +3027,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
assigned_to, args
);
for operand in args {
let (Operand::Copy(assigned_from) | Operand::Move(assigned_from)) = operand else {
let (Operand::Copy(assigned_from) | Operand::Move(assigned_from)) = operand
else {
continue;
};
debug!(

View file

@ -168,17 +168,17 @@ impl<'tcx> BorrowExplanation<'tcx> {
let local_decl = &body.local_decls[dropped_local];
let mut ty = local_decl.ty;
if local_decl.source_info.span.desugaring_kind() == Some(DesugaringKind::ForLoop) {
if let ty::Adt(adt, substs) = local_decl.ty.kind() {
if let ty::Adt(adt, args) = local_decl.ty.kind() {
if tcx.is_diagnostic_item(sym::Option, adt.did()) {
// in for loop desugaring, only look at the `Some(..)` inner type
ty = substs.type_at(0);
ty = args.type_at(0);
}
}
}
let (dtor_desc, type_desc) = match ty.kind() {
// If type is an ADT that implements Drop, then
// simplify output by reporting just the ADT name.
ty::Adt(adt, _substs) if adt.has_dtor(tcx) && !adt.is_box() => {
ty::Adt(adt, _args) if adt.has_dtor(tcx) && !adt.is_box() => {
("`Drop` code", format!("type `{}`", tcx.def_path_str(adt.did())))
}

View file

@ -732,18 +732,18 @@ impl<'tcx> BorrowedContentSource<'tcx> {
fn from_call(func: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option<Self> {
match *func.kind() {
ty::FnDef(def_id, substs) => {
ty::FnDef(def_id, args) => {
let trait_id = tcx.trait_of_item(def_id)?;
let lang_items = tcx.lang_items();
if Some(trait_id) == lang_items.deref_trait()
|| Some(trait_id) == lang_items.deref_mut_trait()
{
Some(BorrowedContentSource::OverloadedDeref(substs.type_at(0)))
Some(BorrowedContentSource::OverloadedDeref(args.type_at(0)))
} else if Some(trait_id) == lang_items.index_trait()
|| Some(trait_id) == lang_items.index_mut_trait()
{
Some(BorrowedContentSource::OverloadedIndex(substs.type_at(0)))
Some(BorrowedContentSource::OverloadedIndex(args.type_at(0)))
} else {
None
}
@ -847,14 +847,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
kind: TerminatorKind::Call { fn_span, call_source, .. }, ..
}) = &self.body[location.block].terminator
{
let Some((method_did, method_substs)) =
rustc_middle::util::find_self_call(
self.infcx.tcx,
&self.body,
target_temp,
location.block,
)
else {
let Some((method_did, method_args)) = rustc_middle::util::find_self_call(
self.infcx.tcx,
&self.body,
target_temp,
location.block,
) else {
return normal_ret;
};
@ -862,7 +860,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
self.infcx.tcx,
self.param_env,
method_did,
method_substs,
method_args,
*fn_span,
call_source.from_hir_call(),
Some(self.infcx.tcx.fn_arg_names(method_did)[0]),
@ -1041,7 +1039,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
});
}
}
CallKind::Normal { self_arg, desugaring, method_did, method_substs } => {
CallKind::Normal { self_arg, desugaring, method_did, method_args } => {
let self_arg = self_arg.unwrap();
let tcx = self.infcx.tcx;
if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring {
@ -1108,13 +1106,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// Erase and shadow everything that could be passed to the new infcx.
let ty = moved_place.ty(self.body, tcx).ty;
if let ty::Adt(def, substs) = ty.kind()
if let ty::Adt(def, args) = ty.kind()
&& Some(def.did()) == tcx.lang_items().pin_type()
&& let ty::Ref(_, _, hir::Mutability::Mut) = substs.type_at(0).kind()
&& let ty::Ref(_, _, hir::Mutability::Mut) = args.type_at(0).kind()
&& let self_ty = self.infcx.instantiate_binder_with_fresh_vars(
fn_call_span,
LateBoundRegionConversionTime::FnCall,
tcx.fn_sig(method_did).subst(tcx, method_substs).input(0),
tcx.fn_sig(method_did).instantiate(tcx, method_args).input(0),
)
&& self.infcx.can_eq(self.param_env, ty, self_ty)
{
@ -1163,7 +1161,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let parent_self_ty =
matches!(tcx.def_kind(parent_did), rustc_hir::def::DefKind::Impl { .. })
.then_some(parent_did)
.and_then(|did| match tcx.type_of(did).subst_identity().kind() {
.and_then(|did| match tcx.type_of(did).instantiate_identity().kind() {
ty::Adt(def, ..) => Some(def.did()),
_ => None,
});

View file

@ -184,7 +184,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}
// Error with the pattern
LookupResult::Exact(_) => {
let LookupResult::Parent(Some(mpi)) = self.move_data.rev_lookup.find(move_from.as_ref()) else {
let LookupResult::Parent(Some(mpi)) =
self.move_data.rev_lookup.find(move_from.as_ref())
else {
// move_from should be a projection from match_place.
unreachable!("Probably not unreachable...");
};
@ -322,10 +324,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
ty::Array(..) | ty::Slice(..) => {
self.cannot_move_out_of_interior_noncopy(span, ty, None)
}
ty::Closure(def_id, closure_substs)
ty::Closure(def_id, closure_args)
if def_id.as_local() == Some(self.mir_def_id()) && upvar_field.is_some() =>
{
let closure_kind_ty = closure_substs.as_closure().kind_ty();
let closure_kind_ty = closure_args.as_closure().kind_ty();
let closure_kind = match closure_kind_ty.to_opt_closure_kind() {
Some(kind @ (ty::ClosureKind::Fn | ty::ClosureKind::FnMut)) => kind,
Some(ty::ClosureKind::FnOnce) => {
@ -494,8 +496,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if let LocalInfo::User(BindingForm::Var(VarBindingForm { pat_span, .. })) =
*bind_to.local_info()
{
let Ok(pat_snippet) =
self.infcx.tcx.sess.source_map().span_to_snippet(pat_span) else { continue; };
let Ok(pat_snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(pat_span)
else {
continue;
};
let Some(stripped) = pat_snippet.strip_prefix('&') else {
suggestions.push((
bind_to.source_info.span.shrink_to_lo(),

View file

@ -2,7 +2,6 @@ use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed
use rustc_hir as hir;
use rustc_hir::intravisit::Visitor;
use rustc_hir::Node;
use rustc_middle::hir::map::Map;
use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::{
@ -646,10 +645,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}
let hir_map = self.infcx.tcx.hir();
let def_id = self.body.source.def_id();
let hir_id = hir_map.local_def_id_to_hir_id(def_id.as_local().unwrap());
let node = hir_map.find(hir_id);
let Some(hir::Node::Item(item)) = node else { return; };
let hir::ItemKind::Fn(.., body_id) = item.kind else { return; };
let Some(local_def_id) = def_id.as_local() else { return };
let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id) else { return };
let body = self.infcx.tcx.hir().body(body_id);
let mut v = V { assign_span: span, err, ty, suggested: false };
@ -786,23 +783,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
// In the future, attempt in all path but initially for RHS of for_loop
fn suggest_similar_mut_method_for_for_loop(&self, err: &mut Diagnostic) {
use hir::{
BodyId, Expr,
Expr,
ExprKind::{Block, Call, DropTemps, Match, MethodCall},
HirId, ImplItem, ImplItemKind, Item, ItemKind,
};
fn maybe_body_id_of_fn(hir_map: Map<'_>, id: HirId) -> Option<BodyId> {
match hir_map.find(id) {
Some(Node::Item(Item { kind: ItemKind::Fn(_, _, body_id), .. }))
| Some(Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(_, body_id), .. })) => {
Some(*body_id)
}
_ => None,
}
}
let hir_map = self.infcx.tcx.hir();
let mir_body_hir_id = self.mir_hir_id();
if let Some(fn_body_id) = maybe_body_id_of_fn(hir_map, mir_body_hir_id) {
if let Some(body_id) = hir_map.maybe_body_owned_by(self.mir_def_id()) {
if let Block(
hir::Block {
expr:
@ -836,7 +822,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
..
},
_,
) = hir_map.body(fn_body_id).value.kind
) = hir_map.body(body_id).value.kind
{
let opt_suggestions = self
.infcx
@ -1098,46 +1084,45 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}
let hir_map = self.infcx.tcx.hir();
let def_id = self.body.source.def_id();
let hir_id = hir_map.local_def_id_to_hir_id(def_id.expect_local());
let node = hir_map.find(hir_id);
let hir_id = if let Some(hir::Node::Item(item)) = node
&& let hir::ItemKind::Fn(.., body_id) = item.kind
{
let body = hir_map.body(body_id);
let mut v = BindingFinder {
span: err_label_span,
hir_id: None,
let hir_id = if let Some(local_def_id) = def_id.as_local() &&
let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id)
{
let body = hir_map.body(body_id);
let mut v = BindingFinder {
span: err_label_span,
hir_id: None,
};
v.visit_body(body);
v.hir_id
} else {
None
};
v.visit_body(body);
v.hir_id
} else {
None
};
if let Some(hir_id) = hir_id
&& let Some(hir::Node::Local(local)) = hir_map.find(hir_id)
{
let (changing, span, sugg) = match local.ty {
Some(ty) => ("changing", ty.span, message),
None => (
"specifying",
local.pat.span.shrink_to_hi(),
format!(": {message}"),
),
};
err.span_suggestion_verbose(
span,
format!("consider {changing} this binding's type"),
sugg,
Applicability::HasPlaceholders,
);
} else {
err.span_label(
err_label_span,
format!(
"consider changing this binding's type to be: `{message}`"
),
);
}
{
let (changing, span, sugg) = match local.ty {
Some(ty) => ("changing", ty.span, message),
None => (
"specifying",
local.pat.span.shrink_to_hi(),
format!(": {message}"),
),
};
err.span_suggestion_verbose(
span,
format!("consider {changing} this binding's type"),
sugg,
Applicability::HasPlaceholders,
);
} else {
err.span_label(
err_label_span,
format!(
"consider changing this binding's type to be: `{message}`"
),
);
}
}
None => {}
}

View file

@ -22,7 +22,7 @@ use rustc_infer::infer::{
};
use rustc_middle::hir::place::PlaceBase;
use rustc_middle::mir::{ConstraintCategory, ReturnConstraint};
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::GenericArgs;
use rustc_middle::ty::TypeVisitor;
use rustc_middle::ty::{self, RegionVid, Ty};
use rustc_middle::ty::{Region, TyCtxt};
@ -183,9 +183,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
fn is_closure_fn_mut(&self, fr: RegionVid) -> bool {
if let Some(ty::ReFree(free_region)) = self.to_error_region(fr).as_deref()
&& let ty::BoundRegionKind::BrEnv = free_region.bound_region
&& let DefiningTy::Closure(_, substs) = self.regioncx.universal_regions().defining_ty
&& let DefiningTy::Closure(_, args) = self.regioncx.universal_regions().defining_ty
{
return substs.as_closure().kind() == ty::ClosureKind::FnMut;
return args.as_closure().kind() == ty::ClosureKind::FnMut;
}
false
@ -224,12 +224,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let mut hrtb_bounds = vec![];
gat_id_and_generics.iter().flatten().for_each(|(gat_hir_id, generics)| {
for pred in generics.predicates {
let BoundPredicate(
WhereBoundPredicate {
bound_generic_params,
bounds,
..
}) = pred else { continue; };
let BoundPredicate(WhereBoundPredicate { bound_generic_params, bounds, .. }) = pred
else {
continue;
};
if bound_generic_params
.iter()
.rfind(|bgp| hir.local_def_id_to_hir_id(bgp.def_id) == *gat_hir_id)
@ -504,12 +502,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
.to_string(),
)
}
ty::Adt(adt, substs) => {
let generic_arg = substs[param_index as usize];
let identity_substs =
InternalSubsts::identity_for_item(self.infcx.tcx, adt.did());
let base_ty = Ty::new_adt(self.infcx.tcx, *adt, identity_substs);
let base_generic_arg = identity_substs[param_index as usize];
ty::Adt(adt, args) => {
let generic_arg = args[param_index as usize];
let identity_args =
GenericArgs::identity_for_item(self.infcx.tcx, adt.did());
let base_ty = Ty::new_adt(self.infcx.tcx, *adt, identity_args);
let base_generic_arg = identity_args[param_index as usize];
let adt_desc = adt.descr();
let desc = format!(
@ -522,12 +520,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}
ty::FnDef(def_id, _) => {
let name = self.infcx.tcx.item_name(*def_id);
let identity_substs =
InternalSubsts::identity_for_item(self.infcx.tcx, *def_id);
let identity_args = GenericArgs::identity_for_item(self.infcx.tcx, *def_id);
let desc = format!("a function pointer to `{name}`");
let note = format!(
"the function `{name}` is invariant over the parameter `{}`",
identity_substs[param_index as usize]
identity_args[param_index as usize]
);
(desc, note)
}
@ -575,7 +572,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty;
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *output_ty.kind() {
output_ty = self.infcx.tcx.type_of(def_id).subst_identity()
output_ty = self.infcx.tcx.type_of(def_id).instantiate_identity()
};
debug!("report_fnmut_error: output_ty={:?}", output_ty);
@ -813,7 +810,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
return;
}
let suitable_region = self.infcx.tcx.is_suitable_region(f);
let Some(suitable_region) = suitable_region else { return; };
let Some(suitable_region) = suitable_region else {
return;
};
let fn_returns = self.infcx.tcx.return_type_impl_or_dyn_traits(suitable_region.def_id);
@ -848,7 +847,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let Some((alias_tys, alias_span, lt_addition_span)) = self
.infcx
.tcx
.return_type_impl_or_dyn_traits_with_type_alias(suitable_region.def_id) else { return; };
.return_type_impl_or_dyn_traits_with_type_alias(suitable_region.def_id)
else {
return;
};
// in case the return type of the method is a type alias
let mut spans_suggs: Vec<_> = Vec::new();
@ -896,14 +898,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let tcx = self.infcx.tcx;
let instance = if let ConstraintCategory::CallArgument(Some(func_ty)) = category {
let (fn_did, substs) = match func_ty.kind() {
ty::FnDef(fn_did, substs) => (fn_did, substs),
let (fn_did, args) = match func_ty.kind() {
ty::FnDef(fn_did, args) => (fn_did, args),
_ => return,
};
debug!(?fn_did, ?substs);
debug!(?fn_did, ?args);
// Only suggest this on function calls, not closures
let ty = tcx.type_of(fn_did).subst_identity();
let ty = tcx.type_of(fn_did).instantiate_identity();
debug!("ty: {:?}, ty.kind: {:?}", ty, ty.kind());
if let ty::Closure(_, _) = ty.kind() {
return;
@ -913,7 +915,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
tcx,
self.param_env,
*fn_did,
self.infcx.resolve_vars_if_possible(substs),
self.infcx.resolve_vars_if_possible(args),
) {
instance
} else {
@ -932,8 +934,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let mut visitor = TraitObjectVisitor(FxIndexSet::default());
visitor.visit_ty(param.param_ty);
let Some((ident, self_ty)) =
NiceRegionError::get_impl_ident_and_self_ty_from_trait(tcx, instance.def_id(), &visitor.0) else { return; };
let Some((ident, self_ty)) = NiceRegionError::get_impl_ident_and_self_ty_from_trait(
tcx,
instance.def_id(),
&visitor.0,
) else {
return;
};
self.suggest_constrain_dyn_trait_in_impl(diag, &visitor.0, ident, self_ty);
}
@ -981,23 +988,25 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
sup: RegionVid,
) {
let (Some(sub), Some(sup)) = (self.to_error_region(sub), self.to_error_region(sup)) else {
return
return;
};
let Some((ty_sub, _)) = self
.infcx
.tcx
.is_suitable_region(sub)
.and_then(|anon_reg| find_anon_type(self.infcx.tcx, sub, &anon_reg.boundregion)) else {
return
.and_then(|anon_reg| find_anon_type(self.infcx.tcx, sub, &anon_reg.boundregion))
else {
return;
};
let Some((ty_sup, _)) = self
.infcx
.tcx
.is_suitable_region(sup)
.and_then(|anon_reg| find_anon_type(self.infcx.tcx, sup, &anon_reg.boundregion)) else {
return
.and_then(|anon_reg| find_anon_type(self.infcx.tcx, sup, &anon_reg.boundregion))
else {
return;
};
suggest_adding_lifetime_params(self.infcx.tcx, sub, ty_sup, ty_sub, diag);

View file

@ -5,8 +5,8 @@ use rustc_errors::Diagnostic;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_middle::ty::print::RegionHighlightMode;
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::{self, RegionVid, Ty};
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
@ -321,18 +321,18 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
ty::BoundRegionKind::BrEnv => {
let def_ty = self.regioncx.universal_regions().defining_ty;
let DefiningTy::Closure(_, substs) = def_ty else {
let DefiningTy::Closure(_, args) = def_ty else {
// Can't have BrEnv in functions, constants or generators.
bug!("BrEnv outside of closure.");
};
let hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. })
= tcx.hir().expect_expr(self.mir_hir_id()).kind
let hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }) =
tcx.hir().expect_expr(self.mir_hir_id()).kind
else {
bug!("Closure is not defined by a closure expr");
};
let region_name = self.synthesize_region_name();
let closure_kind_ty = substs.as_closure().kind_ty();
let closure_kind_ty = args.as_closure().kind_ty();
let note = match closure_kind_ty.to_opt_closure_kind() {
Some(ty::ClosureKind::Fn) => {
"closure implements `Fn`, so references to captured variables \
@ -510,10 +510,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
}
// Match up something like `Foo<'1>`
(
ty::Adt(_adt_def, substs),
hir::TyKind::Path(hir::QPath::Resolved(None, path)),
) => {
(ty::Adt(_adt_def, args), hir::TyKind::Path(hir::QPath::Resolved(None, path))) => {
match path.res {
// Type parameters of the type alias have no reason to
// be the same as those of the ADT.
@ -523,7 +520,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
_ => {
if let Some(last_segment) = path.segments.last() {
if let Some(highlight) = self.match_adt_and_segment(
substs,
args,
needle_fr,
last_segment,
search_stack,
@ -560,22 +557,22 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
None
}
/// We've found an enum/struct/union type with the substitutions
/// `substs` and -- in the HIR -- a path type with the final
/// We've found an enum/struct/union type with the generic args
/// `args` and -- in the HIR -- a path type with the final
/// segment `last_segment`. Try to find a `'_` to highlight in
/// the generic args (or, if not, to produce new zipped pairs of
/// types+hir to search through).
fn match_adt_and_segment<'hir>(
&self,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
needle_fr: RegionVid,
last_segment: &'hir hir::PathSegment<'hir>,
search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>,
) -> Option<RegionNameHighlight> {
// Did the user give explicit arguments? (e.g., `Foo<..>`)
let args = last_segment.args.as_ref()?;
let explicit_args = last_segment.args.as_ref()?;
let lifetime =
self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?;
self.try_match_adt_and_generic_args(args, needle_fr, explicit_args, search_stack)?;
if lifetime.is_anonymous() {
None
} else {
@ -583,19 +580,19 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
}
}
/// We've found an enum/struct/union type with the substitutions
/// `substs` and -- in the HIR -- a path with the generic
/// arguments `args`. If `needle_fr` appears in the args, return
/// We've found an enum/struct/union type with the generic args
/// `args` and -- in the HIR -- a path with the generic
/// arguments `hir_args`. If `needle_fr` appears in the args, return
/// the `hir::Lifetime` that corresponds to it. If not, push onto
/// `search_stack` the types+hir to search through.
fn try_match_adt_and_generic_args<'hir>(
&self,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
needle_fr: RegionVid,
args: &'hir hir::GenericArgs<'hir>,
hir_args: &'hir hir::GenericArgs<'hir>,
search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>,
) -> Option<&'hir hir::Lifetime> {
for (kind, hir_arg) in iter::zip(substs, args.args) {
for (kind, hir_arg) in iter::zip(args, hir_args.args) {
match (kind.unpack(), hir_arg) {
(GenericArgKind::Lifetime(r), hir::GenericArg::Lifetime(lt)) => {
if r.as_var() == needle_fr {
@ -849,9 +846,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
return None;
};
let found = tcx.any_free_region_meets(&tcx.type_of(region_parent).subst_identity(), |r| {
*r == ty::ReEarlyBound(region)
});
let found = tcx
.any_free_region_meets(&tcx.type_of(region_parent).instantiate_identity(), |r| {
*r == ty::ReEarlyBound(region)
});
Some(RegionName {
name: self.synthesize_region_name(),

View file

@ -301,7 +301,7 @@ fn do_mir_borrowck<'tcx>(
let movable_generator =
// The first argument is the generator type passed by value
if let Some(local) = body.local_decls.raw.get(1)
// Get the interior types and substs which typeck computed
// Get the interior types and args which typeck computed
&& let ty::Generator(_, _, hir::Movability::Static) = local.ty.kind()
{
false

View file

@ -1115,7 +1115,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
) -> Option<ClosureOutlivesSubject<'tcx>> {
let tcx = infcx.tcx;
// Opaque types' substs may include useless lifetimes.
// Opaque types' args may include useless lifetimes.
// We will replace them with ReStatic.
struct OpaqueFolder<'tcx> {
tcx: TyCtxt<'tcx>,
@ -1127,19 +1127,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
use ty::TypeSuperFoldable as _;
let tcx = self.tcx;
let &ty::Alias(ty::Opaque, ty::AliasTy { substs, def_id, .. }) = t.kind() else {
let &ty::Alias(ty::Opaque, ty::AliasTy { args, def_id, .. }) = t.kind() else {
return t.super_fold_with(self);
};
let substs =
std::iter::zip(substs, tcx.variances_of(def_id)).map(|(arg, v)| {
match (arg.unpack(), v) {
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => {
tcx.lifetimes.re_static.into()
}
_ => arg.fold_with(self),
let args = std::iter::zip(args, tcx.variances_of(def_id)).map(|(arg, v)| {
match (arg.unpack(), v) {
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => {
tcx.lifetimes.re_static.into()
}
});
Ty::new_opaque(tcx, def_id, tcx.mk_substs_from_iter(substs))
_ => arg.fold_with(self),
}
});
Ty::new_opaque(tcx, def_id, tcx.mk_args_from_iter(args))
}
}
@ -2058,10 +2057,17 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let mut extra_info = vec![];
for constraint in path.iter() {
let outlived = constraint.sub;
let Some(origin) = self.var_infos.get(outlived) else { continue; };
let RegionVariableOrigin::Nll(NllRegionVariableOrigin::Placeholder(p)) = origin.origin else { continue; };
let Some(origin) = self.var_infos.get(outlived) else {
continue;
};
let RegionVariableOrigin::Nll(NllRegionVariableOrigin::Placeholder(p)) = origin.origin
else {
continue;
};
debug!(?constraint, ?p);
let ConstraintCategory::Predicate(span) = constraint.category else { continue; };
let ConstraintCategory::Predicate(span) = constraint.category else {
continue;
};
extra_info.push(ExtraConstraintInfo::PlaceholderFromPredicate(span));
// We only want to point to one
break;

View file

@ -6,9 +6,9 @@ use rustc_infer::infer::InferCtxt;
use rustc_infer::infer::TyCtxtInferExt as _;
use rustc_infer::traits::{Obligation, ObligationCause};
use rustc_middle::traits::DefiningAnchor;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
use rustc_middle::ty::{GenericArgKind, GenericArgs};
use rustc_span::Span;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::ObligationCtxt;
@ -38,15 +38,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// back to concrete lifetimes: `'static`, `ReEarlyBound` or `ReFree`.
///
/// First we map all the lifetimes in the concrete type to an equal
/// universal region that occurs in the concrete type's substs, in this case
/// this would result in `&'1 i32`. We only consider regions in the substs
/// universal region that occurs in the concrete type's args, in this case
/// this would result in `&'1 i32`. We only consider regions in the args
/// in case there is an equal region that does not. For example, this should
/// be allowed:
/// `fn f<'a: 'b, 'b: 'a>(x: *mut &'b i32) -> impl Sized + 'a { x }`
///
/// Then we map the regions in both the type and the subst to their
/// `external_name` giving `concrete_type = &'a i32`,
/// `substs = ['static, 'a]`. This will then allow
/// `args = ['static, 'a]`. This will then allow
/// `infer_opaque_definition_from_instantiation` to determine that
/// `_Return<'_a> = &'_a i32`.
///
@ -73,8 +73,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
debug!(?member_constraints);
for (opaque_type_key, concrete_type) in opaque_ty_decls {
let substs = opaque_type_key.substs;
debug!(?concrete_type, ?substs);
let args = opaque_type_key.args;
debug!(?concrete_type, ?args);
let mut subst_regions = vec![self.universal_regions.fr_static];
@ -95,7 +95,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
ty::Region::new_error_with_message(
infcx.tcx,
concrete_type.span,
"opaque type with non-universal region substs",
"opaque type with non-universal region args",
)
}
}
@ -110,17 +110,17 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
debug!(?subst_regions);
// Next, insert universal regions from substs, so we can translate regions that appear
// in them but are not subject to member constraints, for instance closure substs.
let universal_substs = infcx.tcx.fold_regions(substs, |region, _| {
// Next, insert universal regions from args, so we can translate regions that appear
// in them but are not subject to member constraints, for instance closure args.
let universal_args = infcx.tcx.fold_regions(args, |region, _| {
if let ty::RePlaceholder(..) = region.kind() {
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the args.
return region;
}
let vid = self.to_region_vid(region);
to_universal_region(vid, &mut subst_regions)
});
debug!(?universal_substs);
debug!(?universal_args);
debug!(?subst_regions);
// Deduplicate the set of regions while keeping the chosen order.
@ -139,7 +139,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
debug!(?universal_concrete_type);
let opaque_type_key =
OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs };
OpaqueTypeKey { def_id: opaque_type_key.def_id, args: universal_args };
let ty = infcx.infer_opaque_definition_from_instantiation(
opaque_type_key,
universal_concrete_type,
@ -175,7 +175,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// Map the regions in the type to named regions. This is similar to what
/// `infer_opaque_types` does, but can infer any universal region, not only
/// ones from the substs for the opaque type. It also doesn't double check
/// ones from the args for the opaque type. It also doesn't double check
/// that the regions produced are in fact equal to the named region they are
/// replaced with. This is fine because this function is only to improve the
/// region names in error messages.
@ -238,7 +238,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
/// # Parameters
///
/// - `def_id`, the `impl Trait` type
/// - `substs`, the substs used to instantiate this opaque type
/// - `args`, the args used to instantiate this opaque type
/// - `instantiated_ty`, the inferred type C1 -- fully resolved, lifted version of
/// `opaque_defn.concrete_ty`
#[instrument(level = "debug", skip(self))]
@ -309,11 +309,11 @@ fn check_opaque_type_well_formed<'tcx>(
})
.build();
let ocx = ObligationCtxt::new(&infcx);
let identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
let identity_args = GenericArgs::identity_for_item(tcx, def_id);
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without
// the bounds that the function supplies.
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), identity_substs);
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), identity_args);
ocx.eq(&ObligationCause::misc(definition_span, def_id), param_env, opaque_ty, definition_ty)
.map_err(|err| {
infcx
@ -384,7 +384,7 @@ fn check_opaque_type_parameter_valid(
}
let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
for (i, arg) in opaque_type_key.substs.iter().enumerate() {
for (i, arg) in opaque_type_key.args.iter().enumerate() {
let arg_is_param = match arg.unpack() {
GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
GenericArgKind::Lifetime(lt) => {

View file

@ -6,7 +6,7 @@ use rustc_infer::infer::NllRegionVariableOrigin;
use rustc_middle::mir::visit::{MutVisitor, TyContext};
use rustc_middle::mir::Constant;
use rustc_middle::mir::{Body, Location, Promoted};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc_span::{Span, Symbol};
@ -94,10 +94,10 @@ impl<'a, 'tcx> MutVisitor<'tcx> for RegionRenumberer<'a, 'tcx> {
}
#[instrument(skip(self), level = "debug")]
fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) {
*substs = self.renumber_regions(*substs, || RegionCtxt::Location(location));
fn visit_args(&mut self, args: &mut GenericArgsRef<'tcx>, location: Location) {
*args = self.renumber_regions(*args, || RegionCtxt::Location(location));
debug!(?substs);
debug!(?args);
}
#[instrument(skip(self), level = "debug")]

View file

@ -5,7 +5,7 @@ use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelega
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::GenericArgKind;
use rustc_middle::ty::{self, TyCtxt};
use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
use rustc_span::{Span, DUMMY_SP};
@ -89,20 +89,20 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
/// Given an instance of the closure type, this method instantiates the "extra" requirements
/// that we computed for the closure. This has the effect of adding new outlives obligations
/// to existing region variables in `closure_substs`.
/// to existing region variables in `closure_args`.
#[instrument(skip(self), level = "debug")]
pub fn apply_closure_requirements(
&mut self,
closure_requirements: &ClosureRegionRequirements<'tcx>,
closure_def_id: DefId,
closure_substs: ty::SubstsRef<'tcx>,
closure_args: ty::GenericArgsRef<'tcx>,
) {
// Extract the values of the free regions in `closure_substs`
// Extract the values of the free regions in `closure_args`
// into a vector. These are the regions that we will be
// relating to one another.
let closure_mapping = &UniversalRegions::closure_mapping(
self.tcx,
closure_substs,
closure_args,
closure_requirements.num_external_vids,
closure_def_id.expect_local(),
);

View file

@ -2,7 +2,7 @@ use crate::def_use::{self, DefUse};
use crate::location::{LocationIndex, LocationTable};
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::{Body, Local, Location, Place};
use rustc_middle::ty::subst::GenericArg;
use rustc_middle::ty::GenericArg;
use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex};
use super::TypeChecker;

View file

@ -30,12 +30,12 @@ use rustc_middle::traits::query::NoSolution;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::cast::CastTy;
use rustc_middle::ty::subst::{SubstsRef, UserSubsts};
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{
self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic,
OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
};
use rustc_middle::ty::{GenericArgsRef, UserArgs};
use rustc_span::def_id::CRATE_DEF_ID;
use rustc_span::symbol::sym;
use rustc_span::{Span, DUMMY_SP};
@ -389,15 +389,12 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
} else {
self.cx.ascribe_user_type(
constant.literal.ty(),
UserType::TypeOf(
uv.def,
UserSubsts { substs: uv.substs, user_self_ty: None },
),
UserType::TypeOf(uv.def, UserArgs { args: uv.args, user_self_ty: None }),
locations.span(&self.cx.body),
);
}
} else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
let unnormalized_ty = tcx.type_of(static_def_id).subst_identity();
let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity();
let normalized_ty = self.cx.normalize(unnormalized_ty, locations);
let literal_ty = constant.literal.ty().builtin_deref(true).unwrap().ty;
@ -411,11 +408,11 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
}
}
if let ty::FnDef(def_id, substs) = *constant.literal.ty().kind() {
if let ty::FnDef(def_id, args) = *constant.literal.ty().kind() {
// const_trait_impl: use a non-const param env when checking that a FnDef type is well formed.
// this is because the well-formedness of the function does not need to be proved to have `const`
// impls for trait bounds.
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args);
let prev = self.cx.param_env;
self.cx.param_env = prev.without_const();
self.cx.normalize_and_prove_instantiated_predicates(
@ -666,7 +663,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
})
}
ProjectionElem::Downcast(maybe_name, index) => match base_ty.kind() {
ty::Adt(adt_def, _substs) if adt_def.is_enum() => {
ty::Adt(adt_def, _args) if adt_def.is_enum() => {
if index.as_usize() >= adt_def.variants().len() {
PlaceTy::from_ty(span_mirbug_and_err!(
self,
@ -776,16 +773,16 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
) -> Result<Ty<'tcx>, FieldAccessError> {
let tcx = self.tcx();
let (variant, substs) = match base_ty {
let (variant, args) = match base_ty {
PlaceTy { ty, variant_index: Some(variant_index) } => match *ty.kind() {
ty::Adt(adt_def, substs) => (adt_def.variant(variant_index), substs),
ty::Generator(def_id, substs, _) => {
let mut variants = substs.as_generator().state_tys(def_id, tcx);
ty::Adt(adt_def, args) => (adt_def.variant(variant_index), args),
ty::Generator(def_id, args, _) => {
let mut variants = args.as_generator().state_tys(def_id, tcx);
let Some(mut variant) = variants.nth(variant_index.into()) else {
bug!(
"variant_index of generator out of range: {:?}/{:?}",
variant_index,
substs.as_generator().state_tys(def_id, tcx).count()
args.as_generator().state_tys(def_id, tcx).count()
);
};
return match variant.nth(field.index()) {
@ -796,11 +793,11 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
_ => bug!("can't have downcast of non-adt non-generator type"),
},
PlaceTy { ty, variant_index: None } => match *ty.kind() {
ty::Adt(adt_def, substs) if !adt_def.is_enum() => {
(adt_def.variant(FIRST_VARIANT), substs)
ty::Adt(adt_def, args) if !adt_def.is_enum() => {
(adt_def.variant(FIRST_VARIANT), args)
}
ty::Closure(_, substs) => {
return match substs
ty::Closure(_, args) => {
return match args
.as_closure()
.tupled_upvars_ty()
.tuple_fields()
@ -808,17 +805,17 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
{
Some(&ty) => Ok(ty),
None => Err(FieldAccessError::OutOfRange {
field_count: substs.as_closure().upvar_tys().count(),
field_count: args.as_closure().upvar_tys().count(),
}),
};
}
ty::Generator(_, substs, _) => {
ty::Generator(_, args, _) => {
// Only prefix fields (upvars and current state) are
// accessible without a variant index.
return match substs.as_generator().prefix_tys().nth(field.index()) {
return match args.as_generator().prefix_tys().nth(field.index()) {
Some(ty) => Ok(ty),
None => Err(FieldAccessError::OutOfRange {
field_count: substs.as_generator().prefix_tys().count(),
field_count: args.as_generator().prefix_tys().count(),
}),
};
}
@ -840,7 +837,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
};
if let Some(field) = variant.fields.get(field) {
Ok(self.cx.normalize(field.ty(tcx, substs), location))
Ok(self.cx.normalize(field.ty(tcx, args), location))
} else {
Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
}
@ -1065,7 +1062,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
ocx.infcx.add_item_bounds_for_hidden_type(
opaque_type_key.def_id.to_def_id(),
opaque_type_key.substs,
opaque_type_key.args,
cause,
param_env,
hidden_ty.ty,
@ -1770,32 +1767,32 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let tcx = self.tcx();
match *ak {
AggregateKind::Adt(adt_did, variant_index, substs, _, active_field_index) => {
AggregateKind::Adt(adt_did, variant_index, args, _, active_field_index) => {
let def = tcx.adt_def(adt_did);
let variant = &def.variant(variant_index);
let adj_field_index = active_field_index.unwrap_or(field_index);
if let Some(field) = variant.fields.get(adj_field_index) {
Ok(self.normalize(field.ty(tcx, substs), location))
Ok(self.normalize(field.ty(tcx, args), location))
} else {
Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
}
}
AggregateKind::Closure(_, substs) => {
match substs.as_closure().upvar_tys().nth(field_index.as_usize()) {
AggregateKind::Closure(_, args) => {
match args.as_closure().upvar_tys().nth(field_index.as_usize()) {
Some(ty) => Ok(ty),
None => Err(FieldAccessError::OutOfRange {
field_count: substs.as_closure().upvar_tys().count(),
field_count: args.as_closure().upvar_tys().count(),
}),
}
}
AggregateKind::Generator(_, substs, _) => {
AggregateKind::Generator(_, args, _) => {
// It doesn't make sense to look at a field beyond the prefix;
// these require a variant index, and are not initialized in
// aggregate rvalues.
match substs.as_generator().prefix_tys().nth(field_index.as_usize()) {
match args.as_generator().prefix_tys().nth(field_index.as_usize()) {
Some(ty) => Ok(ty),
None => Err(FieldAccessError::OutOfRange {
field_count: substs.as_generator().prefix_tys().count(),
field_count: args.as_generator().prefix_tys().count(),
}),
}
}
@ -1821,8 +1818,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let def_id = uv.def;
if tcx.def_kind(def_id) == DefKind::InlineConst {
let def_id = def_id.expect_local();
let predicates =
self.prove_closure_bounds(tcx, def_id, uv.substs, location);
let predicates = self.prove_closure_bounds(tcx, def_id, uv.args, location);
self.normalize_and_prove_instantiated_predicates(
def_id.to_def_id(),
predicates,
@ -1939,7 +1935,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(unsafety)) => {
let sig = match op.ty(body, tcx).kind() {
ty::Closure(_, substs) => substs.as_closure().sig(),
ty::Closure(_, args) => args.as_closure().sig(),
_ => bug!(),
};
let ty_fn_ptr_from =
@ -2039,28 +2035,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
CastKind::PointerCoercion(PointerCoercion::MutToConstPointer) => {
let ty::RawPtr(ty::TypeAndMut {
ty: ty_from,
mutbl: hir::Mutability::Mut,
}) = op.ty(body, tcx).kind() else {
span_mirbug!(
self,
rvalue,
"unexpected base type for cast {:?}",
ty,
);
let ty::RawPtr(ty::TypeAndMut { ty: ty_from, mutbl: hir::Mutability::Mut }) =
op.ty(body, tcx).kind()
else {
span_mirbug!(self, rvalue, "unexpected base type for cast {:?}", ty,);
return;
};
let ty::RawPtr(ty::TypeAndMut {
ty: ty_to,
mutbl: hir::Mutability::Not,
}) = ty.kind() else {
span_mirbug!(
self,
rvalue,
"unexpected target type for cast {:?}",
ty,
);
let ty::RawPtr(ty::TypeAndMut { ty: ty_to, mutbl: hir::Mutability::Not }) =
ty.kind()
else {
span_mirbug!(self, rvalue, "unexpected target type for cast {:?}", ty,);
return;
};
if let Err(terr) = self.sub_types(
@ -2603,8 +2587,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
);
let (def_id, instantiated_predicates) = match *aggregate_kind {
AggregateKind::Adt(adt_did, _, substs, _, _) => {
(adt_did, tcx.predicates_of(adt_did).instantiate(tcx, substs))
AggregateKind::Adt(adt_did, _, args, _, _) => {
(adt_did, tcx.predicates_of(adt_did).instantiate(tcx, args))
}
// For closures, we have some **extra requirements** we
@ -2626,9 +2610,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// desugaring. A closure gets desugared to a struct, and
// these extra requirements are basically like where
// clauses on the struct.
AggregateKind::Closure(def_id, substs)
| AggregateKind::Generator(def_id, substs, _) => {
(def_id, self.prove_closure_bounds(tcx, def_id.expect_local(), substs, location))
AggregateKind::Closure(def_id, args) | AggregateKind::Generator(def_id, args, _) => {
(def_id, self.prove_closure_bounds(tcx, def_id.expect_local(), args, location))
}
AggregateKind::Array(_) | AggregateKind::Tuple => {
@ -2647,7 +2630,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
&mut self,
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
location: Location,
) -> ty::InstantiatedPredicates<'tcx> {
if let Some(closure_requirements) = &tcx.mir_borrowck(def_id).closure_requirements {
@ -2665,26 +2648,26 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
.apply_closure_requirements(
&closure_requirements,
def_id.to_def_id(),
substs,
args,
);
}
// Now equate closure substs to regions inherited from `typeck_root_def_id`. Fixes #98589.
// Now equate closure args to regions inherited from `typeck_root_def_id`. Fixes #98589.
let typeck_root_def_id = tcx.typeck_root_def_id(self.body.source.def_id());
let typeck_root_substs = ty::InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
let typeck_root_args = ty::GenericArgs::identity_for_item(tcx, typeck_root_def_id);
let parent_substs = match tcx.def_kind(def_id) {
DefKind::Closure => substs.as_closure().parent_substs(),
DefKind::Generator => substs.as_generator().parent_substs(),
DefKind::InlineConst => substs.as_inline_const().parent_substs(),
let parent_args = match tcx.def_kind(def_id) {
DefKind::Closure => args.as_closure().parent_args(),
DefKind::Generator => args.as_generator().parent_args(),
DefKind::InlineConst => args.as_inline_const().parent_args(),
other => bug!("unexpected item {:?}", other),
};
let parent_substs = tcx.mk_substs(parent_substs);
let parent_args = tcx.mk_args(parent_args);
assert_eq!(typeck_root_substs.len(), parent_substs.len());
if let Err(_) = self.eq_substs(
typeck_root_substs,
parent_substs,
assert_eq!(typeck_root_args.len(), parent_args.len());
if let Err(_) = self.eq_args(
typeck_root_args,
parent_args,
location.to_locations(),
ConstraintCategory::BoringNoLocation,
) {
@ -2692,12 +2675,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self,
def_id,
"could not relate closure to parent {:?} != {:?}",
typeck_root_substs,
parent_substs
typeck_root_args,
parent_args
);
}
tcx.predicates_of(def_id).instantiate(tcx, substs)
tcx.predicates_of(def_id).instantiate(tcx, args)
}
#[instrument(skip(self, body), level = "debug")]

View file

@ -42,10 +42,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
/// Add sufficient constraints to ensure `a == b`. See also [Self::relate_types].
pub(super) fn eq_substs(
pub(super) fn eq_args(
&mut self,
a: ty::SubstsRef<'tcx>,
b: ty::SubstsRef<'tcx>,
a: ty::GenericArgsRef<'tcx>,
b: ty::GenericArgsRef<'tcx>,
locations: Locations,
category: ConstraintCategory<'tcx>,
) -> Result<(), NoSolution> {

View file

@ -22,8 +22,8 @@ use rustc_hir::BodyOwnerKind;
use rustc_index::IndexVec;
use rustc_infer::infer::NllRegionVariableOrigin;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::{self, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt};
use rustc_middle::ty::{InternalSubsts, SubstsRef};
use rustc_middle::ty::{self, InlineConstArgs, InlineConstArgsParts, RegionVid, Ty, TyCtxt};
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
use rustc_span::symbol::{kw, sym};
use rustc_span::Symbol;
use std::iter;
@ -88,26 +88,26 @@ pub struct UniversalRegions<'tcx> {
#[derive(Copy, Clone, Debug)]
pub enum DefiningTy<'tcx> {
/// The MIR is a closure. The signature is found via
/// `ClosureSubsts::closure_sig_ty`.
Closure(DefId, SubstsRef<'tcx>),
/// `ClosureArgs::closure_sig_ty`.
Closure(DefId, GenericArgsRef<'tcx>),
/// The MIR is a generator. The signature is that generators take
/// no parameters and return the result of
/// `ClosureSubsts::generator_return_ty`.
Generator(DefId, SubstsRef<'tcx>, hir::Movability),
/// `ClosureArgs::generator_return_ty`.
Generator(DefId, GenericArgsRef<'tcx>, hir::Movability),
/// The MIR is a fn item with the given `DefId` and substs. The signature
/// The MIR is a fn item with the given `DefId` and args. The signature
/// of the function can be bound then with the `fn_sig` query.
FnDef(DefId, SubstsRef<'tcx>),
FnDef(DefId, GenericArgsRef<'tcx>),
/// The MIR represents some form of constant. The signature then
/// is that it has no inputs and a single return value, which is
/// the value of the constant.
Const(DefId, SubstsRef<'tcx>),
Const(DefId, GenericArgsRef<'tcx>),
/// The MIR represents an inline const. The signature has no inputs and a
/// single return value found via `InlineConstSubsts::ty`.
InlineConst(DefId, SubstsRef<'tcx>),
/// single return value found via `InlineConstArgs::ty`.
InlineConst(DefId, GenericArgsRef<'tcx>),
}
impl<'tcx> DefiningTy<'tcx> {
@ -117,9 +117,9 @@ impl<'tcx> DefiningTy<'tcx> {
/// match up with the upvar order in the HIR, typesystem, and MIR.
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
match self {
DefiningTy::Closure(_, substs) => Either::Left(substs.as_closure().upvar_tys()),
DefiningTy::Generator(_, substs, _) => {
Either::Right(Either::Left(substs.as_generator().upvar_tys()))
DefiningTy::Closure(_, args) => Either::Left(args.as_closure().upvar_tys()),
DefiningTy::Generator(_, args, _) => {
Either::Right(Either::Left(args.as_generator().upvar_tys()))
}
DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => {
Either::Right(Either::Right(iter::empty()))
@ -164,9 +164,9 @@ struct UniversalRegionIndices<'tcx> {
/// used because trait matching and type-checking will feed us
/// region constraints that reference those regions and we need to
/// be able to map them to our internal `RegionVid`. This is
/// basically equivalent to an `InternalSubsts`, except that it also
/// basically equivalent to an `GenericArgs`, except that it also
/// contains an entry for `ReStatic` -- it might be nice to just
/// use a substs, and then handle `ReStatic` another way.
/// use a args, and then handle `ReStatic` another way.
indices: FxHashMap<ty::Region<'tcx>, RegionVid>,
/// The vid assigned to `'static`. Used only for diagnostics.
@ -243,13 +243,13 @@ impl<'tcx> UniversalRegions<'tcx> {
/// `V[1]: V[2]`.
pub fn closure_mapping(
tcx: TyCtxt<'tcx>,
closure_substs: SubstsRef<'tcx>,
closure_args: GenericArgsRef<'tcx>,
expected_num_vars: usize,
closure_def_id: LocalDefId,
) -> IndexVec<RegionVid, ty::Region<'tcx>> {
let mut region_mapping = IndexVec::with_capacity(expected_num_vars);
region_mapping.push(tcx.lifetimes.re_static);
tcx.for_each_free_region(&closure_substs, |fr| {
tcx.for_each_free_region(&closure_args, |fr| {
region_mapping.push(fr);
});
@ -334,11 +334,11 @@ impl<'tcx> UniversalRegions<'tcx> {
/// state.
pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) {
match self.defining_ty {
DefiningTy::Closure(def_id, substs) => {
DefiningTy::Closure(def_id, args) => {
err.note(format!(
"defining type: {} with closure substs {:#?}",
tcx.def_path_str_with_substs(def_id, substs),
&substs[tcx.generics_of(def_id).parent_count..],
"defining type: {} with closure args {:#?}",
tcx.def_path_str_with_args(def_id, args),
&args[tcx.generics_of(def_id).parent_count..],
));
// FIXME: It'd be nice to print the late-bound regions
@ -350,11 +350,11 @@ impl<'tcx> UniversalRegions<'tcx> {
err.note(format!("late-bound region is {:?}", self.to_region_vid(r)));
});
}
DefiningTy::Generator(def_id, substs, _) => {
DefiningTy::Generator(def_id, args, _) => {
err.note(format!(
"defining type: {} with generator substs {:#?}",
tcx.def_path_str_with_substs(def_id, substs),
&substs[tcx.generics_of(def_id).parent_count..],
"defining type: {} with generator args {:#?}",
tcx.def_path_str_with_args(def_id, args),
&args[tcx.generics_of(def_id).parent_count..],
));
// FIXME: As above, we'd like to print out the region
@ -364,22 +364,19 @@ impl<'tcx> UniversalRegions<'tcx> {
err.note(format!("late-bound region is {:?}", self.to_region_vid(r)));
});
}
DefiningTy::FnDef(def_id, substs) => {
err.note(format!(
"defining type: {}",
tcx.def_path_str_with_substs(def_id, substs),
));
DefiningTy::FnDef(def_id, args) => {
err.note(format!("defining type: {}", tcx.def_path_str_with_args(def_id, args),));
}
DefiningTy::Const(def_id, substs) => {
DefiningTy::Const(def_id, args) => {
err.note(format!(
"defining constant type: {}",
tcx.def_path_str_with_substs(def_id, substs),
tcx.def_path_str_with_args(def_id, args),
));
}
DefiningTy::InlineConst(def_id, substs) => {
DefiningTy::InlineConst(def_id, args) => {
err.note(format!(
"defining inline constant type: {}",
tcx.def_path_str_with_substs(def_id, substs),
tcx.def_path_str_with_args(def_id, args),
));
}
}
@ -501,8 +498,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
.as_var();
let region = ty::Region::new_var(self.infcx.tcx, reg_vid);
let va_list_ty =
self.infcx.tcx.type_of(va_list_did).subst(self.infcx.tcx, &[region.into()]);
let va_list_ty = self
.infcx
.tcx
.type_of(va_list_did)
.instantiate(self.infcx.tcx, &[region.into()]);
unnormalized_input_tys = self.infcx.tcx.mk_type_list_from_iter(
unnormalized_input_tys.iter().copied().chain(iter::once(va_list_ty)),
@ -522,7 +522,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
debug!("build: local regions = {}..{}", first_local_index, num_universals);
let yield_ty = match defining_ty {
DefiningTy::Generator(_, substs, _) => Some(substs.as_generator().yield_ty()),
DefiningTy::Generator(_, args, _) => Some(args.as_generator().yield_ty()),
_ => None,
};
@ -548,7 +548,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
match tcx.hir().body_owner_kind(self.mir_def) {
BodyOwnerKind::Closure | BodyOwnerKind::Fn => {
let defining_ty = tcx.type_of(self.mir_def).subst_identity();
let defining_ty = tcx.type_of(self.mir_def).instantiate_identity();
debug!("defining_ty (pre-replacement): {:?}", defining_ty);
@ -556,11 +556,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
self.infcx.replace_free_regions_with_nll_infer_vars(FR, defining_ty);
match *defining_ty.kind() {
ty::Closure(def_id, substs) => DefiningTy::Closure(def_id, substs),
ty::Generator(def_id, substs, movability) => {
DefiningTy::Generator(def_id, substs, movability)
ty::Closure(def_id, args) => DefiningTy::Closure(def_id, args),
ty::Generator(def_id, args, movability) => {
DefiningTy::Generator(def_id, args, movability)
}
ty::FnDef(def_id, substs) => DefiningTy::FnDef(def_id, substs),
ty::FnDef(def_id, args) => DefiningTy::FnDef(def_id, args),
_ => span_bug!(
tcx.def_span(self.mir_def),
"expected defining type for `{:?}`: `{:?}`",
@ -571,11 +571,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
}
BodyOwnerKind::Const | BodyOwnerKind::Static(..) => {
let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id);
if self.mir_def.to_def_id() == typeck_root_def_id {
let substs =
self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_substs);
DefiningTy::Const(self.mir_def.to_def_id(), substs)
let args =
self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_args);
DefiningTy::Const(self.mir_def.to_def_id(), args)
} else {
// FIXME this line creates a dependency between borrowck and typeck.
//
@ -584,18 +584,18 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
// into borrowck, which is ICE #78174.
//
// As a workaround, inline consts have an additional generic param (`ty`
// below), so that `type_of(inline_const_def_id).substs(substs)` uses the
// below), so that `type_of(inline_const_def_id).args(args)` uses the
// proper type with NLL infer vars.
let ty = tcx
.typeck(self.mir_def)
.node_type(tcx.local_def_id_to_hir_id(self.mir_def));
let substs = InlineConstSubsts::new(
let args = InlineConstArgs::new(
tcx,
InlineConstSubstsParts { parent_substs: identity_substs, ty },
InlineConstArgsParts { parent_args: identity_args, ty },
)
.substs;
let substs = self.infcx.replace_free_regions_with_nll_infer_vars(FR, substs);
DefiningTy::InlineConst(self.mir_def.to_def_id(), substs)
.args;
let args = self.infcx.replace_free_regions_with_nll_infer_vars(FR, args);
DefiningTy::InlineConst(self.mir_def.to_def_id(), args)
}
}
}
@ -612,29 +612,29 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
) -> UniversalRegionIndices<'tcx> {
let tcx = self.infcx.tcx;
let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id());
let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
let fr_substs = match defining_ty {
DefiningTy::Closure(_, substs)
| DefiningTy::Generator(_, substs, _)
| DefiningTy::InlineConst(_, substs) => {
let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id);
let fr_args = match defining_ty {
DefiningTy::Closure(_, args)
| DefiningTy::Generator(_, args, _)
| DefiningTy::InlineConst(_, args) => {
// In the case of closures, we rely on the fact that
// the first N elements in the ClosureSubsts are
// the first N elements in the ClosureArgs are
// inherited from the `typeck_root_def_id`.
// Therefore, when we zip together (below) with
// `identity_substs`, we will get only those regions
// `identity_args`, we will get only those regions
// that correspond to early-bound regions declared on
// the `typeck_root_def_id`.
assert!(substs.len() >= identity_substs.len());
assert_eq!(substs.regions().count(), identity_substs.regions().count());
substs
assert!(args.len() >= identity_args.len());
assert_eq!(args.regions().count(), identity_args.regions().count());
args
}
DefiningTy::FnDef(_, substs) | DefiningTy::Const(_, substs) => substs,
DefiningTy::FnDef(_, args) | DefiningTy::Const(_, args) => args,
};
let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static));
let subst_mapping =
iter::zip(identity_substs.regions(), fr_substs.regions().map(|r| r.as_var()));
iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));
UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect(), fr_static }
}
@ -646,9 +646,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
) -> ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>> {
let tcx = self.infcx.tcx;
match defining_ty {
DefiningTy::Closure(def_id, substs) => {
DefiningTy::Closure(def_id, args) => {
assert_eq!(self.mir_def.to_def_id(), def_id);
let closure_sig = substs.as_closure().sig();
let closure_sig = args.as_closure().sig();
let inputs_and_output = closure_sig.inputs_and_output();
let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
inputs_and_output
@ -661,7 +661,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
kind: ty::BrEnv,
};
let env_region = ty::Region::new_late_bound(tcx, ty::INNERMOST, br);
let closure_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap();
let closure_ty = tcx.closure_env_ty(def_id, args, env_region).unwrap();
// The "inputs" of the closure in the
// signature appear as a tuple. The MIR side
@ -681,18 +681,18 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
)
}
DefiningTy::Generator(def_id, substs, movability) => {
DefiningTy::Generator(def_id, args, movability) => {
assert_eq!(self.mir_def.to_def_id(), def_id);
let resume_ty = substs.as_generator().resume_ty();
let output = substs.as_generator().return_ty();
let generator_ty = Ty::new_generator(tcx, def_id, substs, movability);
let resume_ty = args.as_generator().resume_ty();
let output = args.as_generator().return_ty();
let generator_ty = Ty::new_generator(tcx, def_id, args, movability);
let inputs_and_output =
self.infcx.tcx.mk_type_list(&[generator_ty, resume_ty, output]);
ty::Binder::dummy(inputs_and_output)
}
DefiningTy::FnDef(def_id, _) => {
let sig = tcx.fn_sig(def_id).subst_identity();
let sig = tcx.fn_sig(def_id).instantiate_identity();
let sig = indices.fold_to_region_vids(tcx, sig);
sig.inputs_and_output()
}
@ -701,14 +701,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
// For a constant body, there are no inputs, and one
// "output" (the type of the constant).
assert_eq!(self.mir_def.to_def_id(), def_id);
let ty = tcx.type_of(self.mir_def).subst_identity();
let ty = tcx.type_of(self.mir_def).instantiate_identity();
let ty = indices.fold_to_region_vids(tcx, ty);
ty::Binder::dummy(tcx.mk_type_list(&[ty]))
}
DefiningTy::InlineConst(def_id, substs) => {
DefiningTy::InlineConst(def_id, args) => {
assert_eq!(self.mir_def.to_def_id(), def_id);
let ty = substs.as_inline_const().ty();
let ty = args.as_inline_const().ty();
ty::Binder::dummy(tcx.mk_type_list(&[ty]))
}
}
@ -929,7 +929,9 @@ fn for_each_late_bound_region_in_item<'tcx>(
}
for bound_var in tcx.late_bound_vars(tcx.hir().local_def_id_to_hir_id(mir_def_id)) {
let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; };
let ty::BoundVariableKind::Region(bound_region) = bound_var else {
continue;
};
let liberated_region = ty::Region::new_free(tcx, mir_def_id.to_def_id(), bound_region);
f(liberated_region);
}

View file

@ -157,8 +157,7 @@ pub fn parse_asm_args<'a>(
} else if p.eat_keyword(sym::sym) {
let expr = p.parse_expr()?;
let ast::ExprKind::Path(qself, path) = &expr.kind else {
let err = diag
.create_err(errors::AsmSymNoPath { span: expr.span });
let err = diag.create_err(errors::AsmSymNoPath { span: expr.span });
return Err(err);
};
let sym = ast::InlineAsmSym {

View file

@ -61,8 +61,8 @@ pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> Bl
|cx, fold| match fold {
CsFold::Single(field) => {
let [other_expr] = &field.other_selflike_exprs[..] else {
cx.span_bug(field.span, "not exactly 2 arguments in `derive(Ord)`");
};
cx.span_bug(field.span, "not exactly 2 arguments in `derive(Ord)`");
};
let args = thin_vec![field.self_expr.clone(), other_expr.clone()];
cx.expr_call_global(field.span, cmp_path.clone(), args)
}

View file

@ -94,8 +94,8 @@ fn cs_partial_cmp(
|cx, fold| match fold {
CsFold::Single(field) => {
let [other_expr] = &field.other_selflike_exprs[..] else {
cx.span_bug(field.span, "not exactly 2 arguments in `derive(Ord)`");
};
cx.span_bug(field.span, "not exactly 2 arguments in `derive(Ord)`");
};
let args = thin_vec![field.self_expr.clone(), other_expr.clone()];
cx.expr_call_global(field.span, partial_cmp_path.clone(), args)
}

View file

@ -83,7 +83,12 @@ pub fn expand_env<'cx>(
None => {
// Use the string literal in the code in the diagnostic to avoid confusing diagnostics,
// e.g. when the literal contains escape sequences.
let ast::ExprKind::Lit(ast::token::Lit { kind: ast::token::LitKind::Str, symbol: original_var, ..}) = &var_expr.kind else {
let ast::ExprKind::Lit(ast::token::Lit {
kind: ast::token::LitKind::Str,
symbol: original_var,
..
}) = &var_expr.kind
else {
unreachable!("`expr_to_string` ensures this is a string lit")
};
cx.emit_err(errors::EnvNotDefined {

View file

@ -89,7 +89,9 @@ impl<'a> CollectProcMacros<'a> {
}
fn collect_custom_derive(&mut self, item: &'a ast::Item, attr: &'a ast::Attribute) {
let Some((trait_name, proc_attrs)) = parse_macro_name_and_helper_attrs(self.handler, attr, "derive") else {
let Some((trait_name, proc_attrs)) =
parse_macro_name_and_helper_attrs(self.handler, attr, "derive")
else {
return;
};

View file

@ -80,14 +80,7 @@ pub(super) fn add_local_place_comments<'tcx>(
return;
}
let TyAndLayout { ty, layout } = place.layout();
let rustc_target::abi::LayoutS {
size,
align,
abi: _,
variants: _,
fields: _,
largest_niche: _,
} = layout.0.0;
let rustc_target::abi::LayoutS { size, align, .. } = layout.0.0;
let (kind, extra) = place.debug_comment();

View file

@ -70,7 +70,7 @@ pub(crate) fn get_function_sig<'tcx>(
default_call_conv: CallConv,
inst: Instance<'tcx>,
) -> Signature {
assert!(!inst.substs.has_infer());
assert!(!inst.args.has_infer());
clif_sig_from_fn_abi(
tcx,
default_call_conv,
@ -377,16 +377,16 @@ pub(crate) fn codegen_terminator_call<'tcx>(
let ret_place = codegen_place(fx, destination);
// Handle special calls like intrinsics and empty drop glue.
let instance = if let ty::FnDef(def_id, substs) = *func.layout().ty.kind() {
let instance = if let ty::FnDef(def_id, fn_args) = *func.layout().ty.kind() {
let instance =
ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, substs)
ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, fn_args)
.polymorphize(fx.tcx);
if fx.tcx.symbol_name(instance).name.starts_with("llvm.") {
crate::intrinsics::codegen_llvm_intrinsic_call(
fx,
&fx.tcx.symbol_name(instance).name,
substs,
fn_args,
args,
ret_place,
target,
@ -611,7 +611,7 @@ pub(crate) fn codegen_drop<'tcx>(
// `Instance::resolve_drop_in_place`?
let virtual_drop = Instance {
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
substs: drop_instance.substs,
args: drop_instance.args,
};
let fn_abi =
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());
@ -648,7 +648,7 @@ pub(crate) fn codegen_drop<'tcx>(
let virtual_drop = Instance {
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
substs: drop_instance.substs,
args: drop_instance.args,
};
let fn_abi =
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());

View file

@ -28,7 +28,7 @@ pub(crate) fn codegen_fn<'tcx>(
module: &mut dyn Module,
instance: Instance<'tcx>,
) -> CodegenedFunction {
debug_assert!(!instance.substs.has_infer());
debug_assert!(!instance.args.has_infer());
let symbol_name = tcx.symbol_name(instance).name.to_string();
let _timer = tcx.prof.generic_activity_with_arg("codegen fn", &*symbol_name);
@ -578,13 +578,13 @@ fn codegen_stmt<'tcx>(
let from_ty = fx.monomorphize(operand.ty(&fx.mir.local_decls, fx.tcx));
let to_layout = fx.layout_of(fx.monomorphize(to_ty));
match *from_ty.kind() {
ty::FnDef(def_id, substs) => {
ty::FnDef(def_id, args) => {
let func_ref = fx.get_function_ref(
Instance::resolve_for_fn_ptr(
fx.tcx,
ParamEnv::reveal_all(),
def_id,
substs,
args,
)
.unwrap()
.polymorphize(fx.tcx),
@ -668,11 +668,11 @@ fn codegen_stmt<'tcx>(
) => {
let operand = codegen_operand(fx, operand);
match *operand.layout().ty.kind() {
ty::Closure(def_id, substs) => {
ty::Closure(def_id, args) => {
let instance = Instance::resolve_closure(
fx.tcx,
def_id,
substs,
args,
ty::ClosureKind::FnOnce,
)
.expect("failed to normalize and resolve closure during codegen")

View file

@ -57,7 +57,7 @@ pub(crate) fn codegen_tls_ref<'tcx>(
let tls_ptr = if !def_id.is_local() && fx.tcx.needs_thread_local_shim(def_id) {
let instance = ty::Instance {
def: ty::InstanceDef::ThreadLocalShim(def_id),
substs: ty::InternalSubsts::empty(),
args: ty::GenericArgs::empty(),
};
let func_ref = fx.get_function_ref(instance);
let call = fx.bcx.ins().call(func_ref, &[]);

View file

@ -42,7 +42,7 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
InlineAsmOperand::SymFn { anon_const } => {
let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id);
let instance = match ty.kind() {
&ty::FnDef(def_id, substs) => Instance::new(def_id, substs),
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
_ => span_bug!(op_sp, "asm sym is not a function"),
};
let symbol = tcx.symbol_name(instance);

View file

@ -254,12 +254,12 @@ pub(crate) fn codegen_inline_asm<'tcx>(
}
InlineAsmOperand::SymFn { ref value } => {
let literal = fx.monomorphize(value.literal);
if let ty::FnDef(def_id, substs) = *literal.ty().kind() {
if let ty::FnDef(def_id, args) = *literal.ty().kind() {
let instance = ty::Instance::resolve_for_fn_ptr(
fx.tcx,
ty::ParamEnv::reveal_all(),
def_id,
substs,
args,
)
.unwrap();
let symbol = fx.tcx.symbol_name(instance);

View file

@ -3,23 +3,35 @@
use crate::intrinsics::*;
use crate::prelude::*;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::GenericArgsRef;
pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
intrinsic: &str,
substs: SubstsRef<'tcx>,
generic_args: GenericArgsRef<'tcx>,
args: &[mir::Operand<'tcx>],
ret: CPlace<'tcx>,
target: Option<BasicBlock>,
) {
if intrinsic.starts_with("llvm.aarch64") {
return llvm_aarch64::codegen_aarch64_llvm_intrinsic_call(
fx, intrinsic, substs, args, ret, target,
fx,
intrinsic,
generic_args,
args,
ret,
target,
);
}
if intrinsic.starts_with("llvm.x86") {
return llvm_x86::codegen_x86_llvm_intrinsic_call(fx, intrinsic, substs, args, ret, target);
return llvm_x86::codegen_x86_llvm_intrinsic_call(
fx,
intrinsic,
generic_args,
args,
ret,
target,
);
}
match intrinsic {

View file

@ -3,12 +3,12 @@
use crate::intrinsics::*;
use crate::prelude::*;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::GenericArgsRef;
pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
intrinsic: &str,
_substs: SubstsRef<'tcx>,
_args: GenericArgsRef<'tcx>,
args: &[mir::Operand<'tcx>],
ret: CPlace<'tcx>,
target: Option<BasicBlock>,

View file

@ -3,12 +3,12 @@
use crate::intrinsics::*;
use crate::prelude::*;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::GenericArgsRef;
pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
intrinsic: &str,
_substs: SubstsRef<'tcx>,
_args: GenericArgsRef<'tcx>,
args: &[mir::Operand<'tcx>],
ret: CPlace<'tcx>,
target: Option<BasicBlock>,

View file

@ -24,7 +24,7 @@ pub(crate) use llvm::codegen_llvm_intrinsic_call;
use rustc_middle::ty;
use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement};
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::GenericArgsRef;
use rustc_span::symbol::{kw, sym, Symbol};
use crate::prelude::*;
@ -213,13 +213,13 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
source_info: mir::SourceInfo,
) {
let intrinsic = fx.tcx.item_name(instance.def_id());
let substs = instance.substs;
let instance_args = instance.args;
if intrinsic.as_str().starts_with("simd_") {
self::simd::codegen_simd_intrinsic_call(
fx,
intrinsic,
substs,
instance_args,
args,
destination,
target.expect("target for simd intrinsic"),
@ -233,7 +233,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
fx,
instance,
intrinsic,
substs,
instance_args,
args,
destination,
target,
@ -365,7 +365,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
instance: Instance<'tcx>,
intrinsic: Symbol,
substs: SubstsRef<'tcx>,
generic_args: GenericArgsRef<'tcx>,
args: &[mir::Operand<'tcx>],
ret: CPlace<'tcx>,
destination: Option<BasicBlock>,
@ -394,7 +394,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
let dst = dst.load_scalar(fx);
let count = count.load_scalar(fx);
let elem_ty = substs.type_at(0);
let elem_ty = generic_args.type_at(0);
let elem_size: u64 = fx.layout_of(elem_ty).size.bytes();
assert_eq!(args.len(), 3);
let byte_amount =
@ -410,7 +410,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
let src = src.load_scalar(fx);
let count = count.load_scalar(fx);
let elem_ty = substs.type_at(0);
let elem_ty = generic_args.type_at(0);
let elem_size: u64 = fx.layout_of(elem_ty).size.bytes();
assert_eq!(args.len(), 3);
let byte_amount =
@ -428,7 +428,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
sym::size_of_val => {
intrinsic_args!(fx, args => (ptr); intrinsic);
let layout = fx.layout_of(substs.type_at(0));
let layout = fx.layout_of(generic_args.type_at(0));
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
// branch
let size = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
@ -443,7 +443,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
sym::min_align_of_val => {
intrinsic_args!(fx, args => (ptr); intrinsic);
let layout = fx.layout_of(substs.type_at(0));
let layout = fx.layout_of(generic_args.type_at(0));
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
// branch
let align = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
@ -602,7 +602,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
sym::assert_inhabited | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => {
intrinsic_args!(fx, args => (); intrinsic);
let ty = substs.type_at(0);
let ty = generic_args.type_at(0);
let requirement = ValidityRequirement::from_intrinsic(intrinsic);
@ -674,7 +674,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
intrinsic_args!(fx, args => (ptr, base); intrinsic);
let ptr = ptr.load_scalar(fx);
let base = base.load_scalar(fx);
let ty = substs.type_at(0);
let ty = generic_args.type_at(0);
let pointee_size: u64 = fx.layout_of(ty).size.bytes();
let diff_bytes = fx.bcx.ins().isub(ptr, base);
@ -720,7 +720,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
intrinsic_args!(fx, args => (ptr); intrinsic);
let ptr = ptr.load_scalar(fx);
let ty = substs.type_at(0);
let ty = generic_args.type_at(0);
match ty.kind() {
ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
// FIXME implement 128bit atomics
@ -751,7 +751,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
intrinsic_args!(fx, args => (ptr, val); intrinsic);
let ptr = ptr.load_scalar(fx);
let ty = substs.type_at(0);
let ty = generic_args.type_at(0);
match ty.kind() {
ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
// FIXME implement 128bit atomics
@ -1128,7 +1128,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
let lhs_ref = lhs_ref.load_scalar(fx);
let rhs_ref = rhs_ref.load_scalar(fx);
let size = fx.layout_of(substs.type_at(0)).layout.size();
let size = fx.layout_of(generic_args.type_at(0)).layout.size();
// FIXME add and use emit_small_memcmp
let is_eq_value = if size == Size::ZERO {
// No bytes means they're trivially equal

View file

@ -1,6 +1,6 @@
//! Codegen `extern "platform-intrinsic"` intrinsics.
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::GenericArgsRef;
use rustc_span::Symbol;
use rustc_target::abi::Endian;
@ -21,7 +21,7 @@ fn report_simd_type_validation_error(
pub(super) fn codegen_simd_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
intrinsic: Symbol,
_substs: SubstsRef<'tcx>,
_args: GenericArgsRef<'tcx>,
args: &[mir::Operand<'tcx>],
ret: CPlace<'tcx>,
target: BasicBlock,

View file

@ -1,6 +1,6 @@
use rustc_hir::LangItem;
use rustc_middle::ty::subst::GenericArg;
use rustc_middle::ty::AssocKind;
use rustc_middle::ty::GenericArg;
use rustc_session::config::{sigpipe, EntryFnType};
use rustc_span::symbol::Ident;
@ -119,7 +119,7 @@ pub(crate) fn maybe_create_entry_wrapper(
tcx,
ParamEnv::reveal_all(),
report.def_id,
tcx.mk_substs(&[GenericArg::from(main_ret_ty)]),
tcx.mk_args(&[GenericArg::from(main_ret_ty)]),
)
.unwrap()
.unwrap()
@ -146,7 +146,7 @@ pub(crate) fn maybe_create_entry_wrapper(
tcx,
ParamEnv::reveal_all(),
start_def_id,
tcx.mk_substs(&[main_ret_ty.into()]),
tcx.mk_args(&[main_ret_ty.into()]),
)
.unwrap()
.unwrap()

View file

@ -9,7 +9,7 @@
//!
//! function u0:22(i64) -> i8, i8 system_v {
//! ; symbol _ZN97_$LT$example..IsNotEmpty$u20$as$u20$mini_core..FnOnce$LT$$LP$$RF$$RF$$u5b$u16$u5d$$C$$RP$$GT$$GT$9call_once17hd517c453d67c0915E
//! ; instance Instance { def: Item(WithOptConstParam { did: DefId(0:42 ~ example[4e51]::{impl#0}::call_once), const_param_did: None }), substs: [ReErased, ReErased] }
//! ; instance Instance { def: Item(WithOptConstParam { did: DefId(0:42 ~ example[4e51]::{impl#0}::call_once), const_param_did: None }), args: [ReErased, ReErased] }
//! ; abi FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: IsNotEmpty, layout: Layout { size: Size(0 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, abi: Aggregate { sized: true }, fields: Arbitrary { offsets: [], memory_index: [] }, largest_niche: None, variants: Single { index: 0 } } }, mode: Ignore }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), variants: Single { index: 0 } } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], memory_index: [0, 1] }, largest_niche: None, variants: Single { index: 0 } } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false }
//!
//! ; kind loc.idx param pass mode ty
@ -25,7 +25,7 @@
//!
//! ss0 = explicit_slot 16
//! sig0 = (i64, i64) -> i8, i8 system_v
//! fn0 = colocated u0:23 sig0 ; Instance { def: Item(WithOptConstParam { did: DefId(0:46 ~ example[4e51]::{impl#1}::call_mut), const_param_did: None }), substs: [ReErased, ReErased] }
//! fn0 = colocated u0:23 sig0 ; Instance { def: Item(WithOptConstParam { did: DefId(0:46 ~ example[4e51]::{impl#1}::call_mut), const_param_did: None }), args: [ReErased, ReErased] }
//!
//! block0(v0: i64):
//! nop
@ -261,7 +261,7 @@ pub(crate) fn write_clif_file(
impl fmt::Debug for FunctionCx<'_, '_, '_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "{:?}", self.instance.substs)?;
writeln!(f, "{:?}", self.instance.args)?;
writeln!(f, "{:?}", self.local_map)?;
let mut clif = String::new();

View file

@ -850,11 +850,11 @@ pub(crate) fn assert_assignable<'tcx>(
}
}
}
(&ty::Adt(adt_def_a, substs_a), &ty::Adt(adt_def_b, substs_b))
(&ty::Adt(adt_def_a, args_a), &ty::Adt(adt_def_b, args_b))
if adt_def_a.did() == adt_def_b.did() =>
{
let mut types_a = substs_a.types();
let mut types_b = substs_b.types();
let mut types_a = args_a.types();
let mut types_b = args_b.types();
loop {
match (types_a.next(), types_b.next()) {
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
@ -864,11 +864,11 @@ pub(crate) fn assert_assignable<'tcx>(
}
}
(ty::Array(a, _), ty::Array(b, _)) => assert_assignable(fx, *a, *b, limit - 1),
(&ty::Closure(def_id_a, substs_a), &ty::Closure(def_id_b, substs_b))
(&ty::Closure(def_id_a, args_a), &ty::Closure(def_id_b, args_b))
if def_id_a == def_id_b =>
{
let mut types_a = substs_a.types();
let mut types_b = substs_b.types();
let mut types_a = args_a.types();
let mut types_b = args_b.types();
loop {
match (types_a.next(), types_b.next()) {
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),

View file

@ -17,8 +17,8 @@ use crate::context::CodegenCx;
pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>) -> Function<'gcc> {
let tcx = cx.tcx();
assert!(!instance.substs.has_infer());
assert!(!instance.substs.has_escaping_bound_vars());
assert!(!instance.args.has_infer());
assert!(!instance.args.has_escaping_bound_vars());
let sym = tcx.symbol_name(instance).name;
@ -100,7 +100,7 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>)
// whether we are sharing generics or not. The important thing here is
// that the visibility we apply to the declaration is the same one that
// has been applied to the definition (wherever that definition may be).
let is_generic = instance.substs.non_erasable_generics().next().is_some();
let is_generic = instance.args.non_erasable_generics().next().is_some();
if is_generic {
// This is a monomorphization. Its expected visibility depends

View file

@ -92,8 +92,8 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
let tcx = self.tcx;
let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
let (def_id, substs) = match *callee_ty.kind() {
ty::FnDef(def_id, substs) => (def_id, substs),
let (def_id, fn_args) = match *callee_ty.kind() {
ty::FnDef(def_id, fn_args) => (def_id, fn_args),
_ => bug!("expected fn item type, found {}", callee_ty),
};
@ -142,7 +142,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
}
sym::volatile_load | sym::unaligned_volatile_load => {
let tp_ty = substs.type_at(0);
let tp_ty = fn_args.type_at(0);
let mut ptr = args[0].immediate();
if let PassMode::Cast(ty, _) = &fn_abi.ret.mode {
ptr = self.pointercast(ptr, self.type_ptr_to(ty.gcc_type(self)));
@ -264,7 +264,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
sym::raw_eq => {
use rustc_target::abi::Abi::*;
let tp_ty = substs.type_at(0);
let tp_ty = fn_args.type_at(0);
let layout = self.layout_of(tp_ty).layout;
let _use_integer_compare = match layout.abi() {
Scalar(_) | ScalarPair(_, _) => true,

View file

@ -31,7 +31,7 @@ impl<'gcc, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
#[cfg_attr(not(feature="master"), allow(unused_variables))]
fn predefine_fn(&self, instance: Instance<'tcx>, linkage: Linkage, visibility: Visibility, symbol_name: &str) {
assert!(!instance.substs.has_infer());
assert!(!instance.args.has_infer());
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
self.linkage.set(base::linkage_to_gcc(linkage));

View file

@ -101,7 +101,7 @@ fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout
if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
(layout.ty.kind(), &layout.variants)
{
write!(&mut name, "::{}", ty::GeneratorSubsts::variant_name(index)).unwrap();
write!(&mut name, "::{}", ty::GeneratorArgs::variant_name(index)).unwrap();
}
Some(name)
}
@ -282,7 +282,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
}
// only wide pointer boxes are handled as pointers
// thin pointer boxes with scalar allocators are handled by the general logic below
ty::Adt(def, substs) if def.is_box() && cx.layout_of(substs.type_at(1)).is_zst() => {
ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
let ptr_ty = Ty::new_mut_ptr(cx.tcx,self.ty.boxed_ty());
return cx.layout_of(ptr_ty).scalar_pair_element_gcc_type(cx, index, immediate);
}

View file

@ -27,8 +27,8 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
debug!("get_fn(instance={:?})", instance);
assert!(!instance.substs.has_infer());
assert!(!instance.substs.has_escaping_bound_vars());
assert!(!instance.args.has_infer());
assert!(!instance.args.has_escaping_bound_vars());
if let Some(&llfn) = cx.instances.borrow().get(&instance) {
return llfn;
@ -129,7 +129,7 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
unsafe {
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
let is_generic = instance.substs.non_erasable_generics().next().is_some();
let is_generic = instance.args.non_erasable_generics().next().is_some();
if is_generic {
// This is a monomorphization. Its expected visibility depends

View file

@ -63,7 +63,7 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) {
let mut function_data = Vec::new();
for (instance, function_coverage) in function_coverage_map {
debug!("Generate function coverage for {}, {:?}", cx.codegen_unit.name(), instance);
let mangled_function_name = tcx.symbol_name(instance).to_string();
let mangled_function_name = tcx.symbol_name(instance).name;
let source_hash = function_coverage.source_hash();
let is_used = function_coverage.is_used();
let (expressions, counter_regions) =
@ -95,7 +95,7 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) {
let filenames_size = filenames_buffer.len();
let filenames_val = cx.const_bytes(&filenames_buffer);
let filenames_ref = coverageinfo::hash_bytes(filenames_buffer);
let filenames_ref = coverageinfo::hash_bytes(&filenames_buffer);
// Generate the LLVM IR representation of the coverage map and store it in a well-known global
let cov_data_val = mapgen.generate_coverage_map(cx, version, filenames_size, filenames_val);
@ -228,7 +228,7 @@ impl CoverageMapGenerator {
/// specific, well-known section and name.
fn save_function_record(
cx: &CodegenCx<'_, '_>,
mangled_function_name: String,
mangled_function_name: &str,
source_hash: u64,
filenames_ref: u64,
coverage_mapping_buffer: Vec<u8>,
@ -238,7 +238,7 @@ fn save_function_record(
let coverage_mapping_size = coverage_mapping_buffer.len();
let coverage_mapping_val = cx.const_bytes(&coverage_mapping_buffer);
let func_name_hash = coverageinfo::hash_str(&mangled_function_name);
let func_name_hash = coverageinfo::hash_bytes(mangled_function_name.as_bytes());
let func_name_hash_val = cx.const_u64(func_name_hash);
let coverage_mapping_size_val = cx.const_u32(coverage_mapping_size as u32);
let source_hash_val = cx.const_u64(source_hash);

View file

@ -22,7 +22,7 @@ use rustc_middle::mir::coverage::{
use rustc_middle::mir::Coverage;
use rustc_middle::ty;
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::GenericArgs;
use rustc_middle::ty::Instance;
use rustc_middle::ty::Ty;
@ -250,7 +250,7 @@ fn declare_unused_fn<'tcx>(cx: &CodegenCx<'_, 'tcx>, def_id: DefId) -> Instance<
let instance = Instance::new(
def_id,
InternalSubsts::for_item(tcx, def_id, |param, _| {
GenericArgs::for_item(tcx, def_id, |param, _| {
if let ty::GenericParamDefKind::Lifetime = param.kind {
tcx.lifetimes.re_erased.into()
} else {
@ -373,12 +373,7 @@ pub(crate) fn write_mapping_to_buffer(
}
}
pub(crate) fn hash_str(strval: &str) -> u64 {
let strval = CString::new(strval).expect("null error converting hashable str to C string");
unsafe { llvm::LLVMRustCoverageHashCString(strval.as_ptr()) }
}
pub(crate) fn hash_bytes(bytes: Vec<u8>) -> u64 {
pub(crate) fn hash_bytes(bytes: &[u8]) -> u64 {
unsafe { llvm::LLVMRustCoverageHashByteArray(bytes.as_ptr().cast(), bytes.len()) }
}

View file

@ -91,7 +91,7 @@ fn make_mir_scope<'ll, 'tcx>(
// FIXME(eddyb) this would be `self.monomorphize(&callee)`
// if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
let callee = cx.tcx.subst_and_normalize_erasing_regions(
instance.substs,
instance.args,
ty::ParamEnv::reveal_all(),
ty::EarlyBinder::bind(callee),
);

View file

@ -449,7 +449,7 @@ pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll D
}
// Box<T, A> may have a non-ZST allocator A. In that case, we
// cannot treat Box<T, A> as just an owned alias of `*mut T`.
ty::Adt(def, substs) if def.is_box() && cx.layout_of(substs.type_at(1)).is_zst() => {
ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
build_pointer_or_reference_di_node(cx, t, t.boxed_ty(), unique_type_id)
}
ty::FnDef(..) | ty::FnPtr(_) => build_subroutine_type_di_node(cx, unique_type_id),
@ -739,7 +739,10 @@ fn build_foreign_type_di_node<'ll, 'tcx>(
debug!("build_foreign_type_di_node: {:?}", t);
let &ty::Foreign(def_id) = unique_type_id.expect_ty().kind() else {
bug!("build_foreign_type_di_node() called with unexpected type: {:?}", unique_type_id.expect_ty());
bug!(
"build_foreign_type_di_node() called with unexpected type: {:?}",
unique_type_id.expect_ty()
);
};
build_type_with_children(
@ -1004,12 +1007,12 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
closure_or_generator_di_node: &'ll DIType,
) -> SmallVec<&'ll DIType> {
let (&def_id, up_var_tys) = match closure_or_generator_ty.kind() {
ty::Generator(def_id, substs, _) => {
let upvar_tys: SmallVec<_> = substs.as_generator().prefix_tys().collect();
ty::Generator(def_id, args, _) => {
let upvar_tys: SmallVec<_> = args.as_generator().prefix_tys().collect();
(def_id, upvar_tys)
}
ty::Closure(def_id, substs) => {
let upvar_tys: SmallVec<_> = substs.as_closure().upvar_tys().collect();
ty::Closure(def_id, args) => {
let upvar_tys: SmallVec<_> = args.as_closure().upvar_tys().collect();
(def_id, upvar_tys)
}
_ => {
@ -1099,7 +1102,7 @@ fn build_closure_env_di_node<'ll, 'tcx>(
unique_type_id: UniqueTypeId<'tcx>,
) -> DINodeCreationResult<'ll> {
let closure_env_type = unique_type_id.expect_ty();
let &ty::Closure(def_id, _substs) = closure_env_type.kind() else {
let &ty::Closure(def_id, _args) = closure_env_type.kind() else {
bug!("build_closure_env_di_node() called with non-closure-type: {:?}", closure_env_type)
};
let containing_scope = get_namespace_for_item(cx, def_id);
@ -1177,11 +1180,11 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
ty: Ty<'tcx>,
) -> SmallVec<&'ll DIType> {
if let ty::Adt(def, substs) = *ty.kind() {
if substs.types().next().is_some() {
if let ty::Adt(def, args) = *ty.kind() {
if args.types().next().is_some() {
let generics = cx.tcx.generics_of(def.did());
let names = get_parameter_names(cx, generics);
let template_params: SmallVec<_> = iter::zip(substs, names)
let template_params: SmallVec<_> = iter::zip(args, names)
.filter_map(|(kind, name)| {
kind.as_type().map(|ty| {
let actual_type =

View file

@ -12,7 +12,7 @@ use rustc_middle::{
ty::{
self,
layout::{LayoutOf, TyAndLayout},
AdtDef, GeneratorSubsts, Ty,
AdtDef, GeneratorArgs, Ty,
},
};
use rustc_target::abi::{Align, Endian, Size, TagEncoding, VariantIdx, Variants};
@ -199,7 +199,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
let enum_type = unique_type_id.expect_ty();
let &ty::Adt(enum_adt_def, _) = enum_type.kind() else {
bug!("build_enum_type_di_node() called with non-enum type: `{:?}`", enum_type)
};
};
let enum_type_and_layout = cx.layout_of(enum_type);
let enum_type_name = compute_debuginfo_type_name(cx.tcx, enum_type, false);
@ -667,19 +667,21 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
generator_type_and_layout: TyAndLayout<'tcx>,
generator_type_di_node: &'ll DIType,
) -> SmallVec<&'ll DIType> {
let Variants::Multiple { tag_encoding: TagEncoding::Direct, tag_field, .. } = generator_type_and_layout.variants else {
let Variants::Multiple { tag_encoding: TagEncoding::Direct, tag_field, .. } =
generator_type_and_layout.variants
else {
bug!("This function only supports layouts with directly encoded tags.")
};
let (generator_def_id, generator_substs) = match generator_type_and_layout.ty.kind() {
&ty::Generator(def_id, substs, _) => (def_id, substs.as_generator()),
let (generator_def_id, generator_args) = match generator_type_and_layout.ty.kind() {
&ty::Generator(def_id, args, _) => (def_id, args.as_generator()),
_ => unreachable!(),
};
let generator_layout = cx.tcx.optimized_mir(generator_def_id).generator_layout().unwrap();
let common_upvar_names = cx.tcx.closure_saved_names_of_captured_variables(generator_def_id);
let variant_range = generator_substs.variant_range(generator_def_id, cx.tcx);
let variant_range = generator_args.variant_range(generator_def_id, cx.tcx);
let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len();
let tag_base_type = tag_base_type(cx, generator_type_and_layout);
@ -689,11 +691,11 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
generator_type_di_node,
variant_range
.clone()
.map(|variant_index| (variant_index, GeneratorSubsts::variant_name(variant_index))),
.map(|variant_index| (variant_index, GeneratorArgs::variant_name(variant_index))),
);
let discriminants: IndexVec<VariantIdx, DiscrResult> = {
let discriminants_iter = generator_substs.discriminants(generator_def_id, cx.tcx);
let discriminants_iter = generator_args.discriminants(generator_def_id, cx.tcx);
let mut discriminants: IndexVec<VariantIdx, DiscrResult> =
IndexVec::with_capacity(variant_count);
for (variant_index, discr) in discriminants_iter {

View file

@ -10,7 +10,7 @@ use rustc_middle::{
ty::{
self,
layout::{IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout},
AdtDef, GeneratorSubsts, Ty, VariantDef,
AdtDef, GeneratorArgs, Ty, VariantDef,
},
};
use rustc_span::Symbol;
@ -51,7 +51,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
let enum_type = unique_type_id.expect_ty();
let &ty::Adt(enum_adt_def, _) = enum_type.kind() else {
bug!("build_enum_type_di_node() called with non-enum type: `{:?}`", enum_type)
};
};
let enum_type_and_layout = cx.layout_of(enum_type);
@ -325,7 +325,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
generator_layout: &GeneratorLayout<'tcx>,
common_upvar_names: &IndexSlice<FieldIdx, Symbol>,
) -> &'ll DIType {
let variant_name = GeneratorSubsts::variant_name(variant_index);
let variant_name = GeneratorArgs::variant_name(variant_index);
let unique_type_id = UniqueTypeId::for_enum_variant_struct_type(
cx.tcx,
generator_type_and_layout.ty,
@ -334,8 +334,8 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
let variant_layout = generator_type_and_layout.for_variant(cx, variant_index);
let generator_substs = match generator_type_and_layout.ty.kind() {
ty::Generator(_, substs, _) => substs.as_generator(),
let generator_args = match generator_type_and_layout.ty.kind() {
ty::Generator(_, args, _) => args.as_generator(),
_ => unreachable!(),
};
@ -377,7 +377,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
.collect();
// Fields that are common to all states
let common_fields: SmallVec<_> = generator_substs
let common_fields: SmallVec<_> = generator_args
.prefix_tys()
.zip(common_upvar_names)
.enumerate()

View file

@ -57,7 +57,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
let enum_type = unique_type_id.expect_ty();
let &ty::Adt(enum_adt_def, _) = enum_type.kind() else {
bug!("build_enum_type_di_node() called with non-enum type: `{:?}`", enum_type)
};
};
let containing_scope = get_namespace_for_item(cx, enum_adt_def.did());
let enum_type_and_layout = cx.layout_of(enum_type);
@ -132,9 +132,9 @@ pub(super) fn build_generator_di_node<'ll, 'tcx>(
unique_type_id: UniqueTypeId<'tcx>,
) -> DINodeCreationResult<'ll> {
let generator_type = unique_type_id.expect_ty();
let &ty::Generator(generator_def_id, _, _ ) = generator_type.kind() else {
let &ty::Generator(generator_def_id, _, _) = generator_type.kind() else {
bug!("build_generator_di_node() called with non-generator type: `{:?}`", generator_type)
};
};
let containing_scope = get_namespace_for_item(cx, generator_def_id);
let generator_type_and_layout = cx.layout_of(generator_type);
@ -158,7 +158,9 @@ pub(super) fn build_generator_di_node<'ll, 'tcx>(
let generator_layout =
cx.tcx.optimized_mir(generator_def_id).generator_layout().unwrap();
let Variants::Multiple { tag_encoding: TagEncoding::Direct, ref variants, .. } = generator_type_and_layout.variants else {
let Variants::Multiple { tag_encoding: TagEncoding::Direct, ref variants, .. } =
generator_type_and_layout.variants
else {
bug!(
"Encountered generator with non-direct-tag layout: {:?}",
generator_type_and_layout
@ -173,7 +175,7 @@ pub(super) fn build_generator_di_node<'ll, 'tcx>(
.indices()
.map(|variant_index| {
// FIXME: This is problematic because just a number is not a valid identifier.
// GeneratorSubsts::variant_name(variant_index), would be consistent
// GeneratorArgs::variant_name(variant_index), would be consistent
// with enums?
let variant_name = format!("{}", variant_index.as_usize()).into();

View file

@ -27,7 +27,7 @@ use rustc_hir::def_id::{DefId, DefIdMap};
use rustc_index::IndexVec;
use rustc_middle::mir;
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeVisitableExt};
use rustc_session::config::{self, DebugInfo};
use rustc_session::Session;
@ -338,19 +338,19 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
// Find the enclosing function, in case this is a closure.
let enclosing_fn_def_id = tcx.typeck_root_def_id(def_id);
// We look up the generics of the enclosing function and truncate the substs
// We look up the generics of the enclosing function and truncate the args
// to their length in order to cut off extra stuff that might be in there for
// closures or generators.
let generics = tcx.generics_of(enclosing_fn_def_id);
let substs = instance.substs.truncate_to(tcx, generics);
let args = instance.args.truncate_to(tcx, generics);
type_names::push_generic_params(
tcx,
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substs),
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args),
&mut name,
);
let template_parameters = get_template_parameters(self, generics, substs);
let template_parameters = get_template_parameters(self, generics, args);
let linkage_name = &mangled_name_of_instance(self, instance).name;
// Omit the linkage_name if it is the same as subprogram name.
@ -471,16 +471,16 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn get_template_parameters<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
generics: &ty::Generics,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
) -> &'ll DIArray {
if substs.types().next().is_none() {
if args.types().next().is_none() {
return create_DIArray(DIB(cx), &[]);
}
// Again, only create type information if full debuginfo is enabled
let template_params: Vec<_> = if cx.sess().opts.debuginfo == DebugInfo::Full {
let names = get_parameter_names(cx, generics);
iter::zip(substs, names)
iter::zip(args, names)
.filter_map(|(kind, name)| {
kind.as_type().map(|ty| {
let actual_type =
@ -527,7 +527,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
// If the method does *not* belong to a trait, proceed
if cx.tcx.trait_id_of_impl(impl_def_id).is_none() {
let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(
instance.substs,
instance.args,
ty::ParamEnv::reveal_all(),
cx.tcx.type_of(impl_def_id),
);

View file

@ -90,7 +90,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
let tcx = self.tcx;
let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
let ty::FnDef(def_id, substs) = *callee_ty.kind() else {
let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else {
bug!("expected fn item type, found {}", callee_ty);
};
@ -163,7 +163,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
}
sym::volatile_load | sym::unaligned_volatile_load => {
let tp_ty = substs.type_at(0);
let tp_ty = fn_args.type_at(0);
let ptr = args[0].immediate();
let load = if let PassMode::Cast(ty, _) = &fn_abi.ret.mode {
let llty = ty.llvm_type(self);
@ -298,7 +298,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
sym::raw_eq => {
use abi::Abi::*;
let tp_ty = substs.type_at(0);
let tp_ty = fn_args.type_at(0);
let layout = self.layout_of(tp_ty).layout;
let use_integer_compare = match layout.abi() {
Scalar(_) | ScalarPair(_, _) => true,

View file

@ -1916,7 +1916,6 @@ extern "C" {
);
pub fn LLVMRustCoverageCreatePGOFuncNameVar(F: &Value, FuncName: *const c_char) -> &Value;
pub fn LLVMRustCoverageHashCString(StrVal: *const c_char) -> u64;
pub fn LLVMRustCoverageHashByteArray(Bytes: *const c_char, NumBytes: size_t) -> u64;
#[allow(improper_ctypes)]

View file

@ -48,7 +48,7 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> {
visibility: Visibility,
symbol_name: &str,
) {
assert!(!instance.substs.has_infer());
assert!(!instance.args.has_infer());
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
let lldecl = self.declare_fn(symbol_name, fn_abi, Some(instance));

View file

@ -57,7 +57,7 @@ fn uncached_llvm_type<'a, 'tcx>(
if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
(layout.ty.kind(), &layout.variants)
{
write!(&mut name, "::{}", ty::GeneratorSubsts::variant_name(index)).unwrap();
write!(&mut name, "::{}", ty::GeneratorArgs::variant_name(index)).unwrap();
}
Some(name)
}
@ -336,7 +336,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
}
// only wide pointer boxes are handled as pointers
// thin pointer boxes with scalar allocators are handled by the general logic below
ty::Adt(def, substs) if def.is_box() && cx.layout_of(substs.type_at(1)).is_zst() => {
ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
let ptr_ty = Ty::new_mut_ptr(cx.tcx, self.ty.boxed_ty());
return cx.layout_of(ptr_ty).scalar_pair_element_llvm_type(cx, index, immediate);
}

View file

@ -2970,10 +2970,25 @@ fn add_lld_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
return;
}
let self_contained_linker = sess.opts.cg.link_self_contained.linker();
// FIXME: some targets default to using `lld`, but users can only override the linker on the CLI
// and cannot yet select the precise linker flavor to opt out of that. See for example issue
// #113597 for the `thumbv6m-none-eabi` target: a driver is used, and its default linker
// conflicts with the target's flavor, causing unexpected arguments being passed.
//
// Until the new `LinkerFlavor`-like CLI options are stabilized, we only adopt MCP510's behavior
// if its dedicated unstable CLI flags are used, to keep the current sub-optimal stable
// behavior.
let using_mcp510 =
self_contained_linker || sess.opts.cg.linker_flavor.is_some_and(|f| f.is_unstable());
if !using_mcp510 && !unstable_use_lld {
return;
}
// 1. Implement the "self-contained" part of this feature by adding rustc distribution
// directories to the tool's search path.
let self_contained_linker = sess.opts.cg.link_self_contained.linker() || unstable_use_lld;
if self_contained_linker {
if self_contained_linker || unstable_use_lld {
for path in sess.get_tools_search_paths(false) {
cmd.arg({
let mut arg = OsString::from("-B");

View file

@ -12,9 +12,9 @@ use rustc_middle::middle::exported_symbols::{
};
use rustc_middle::query::LocalCrate;
use rustc_middle::query::{ExternProviders, Providers};
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::Instance;
use rustc_middle::ty::{self, SymbolName, TyCtxt};
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
use rustc_session::config::{CrateType, OomStrategy};
use rustc_target::spec::SanitizerSet;
@ -342,9 +342,9 @@ fn exported_symbols_provider_local(
}
match *mono_item {
MonoItem::Fn(Instance { def: InstanceDef::Item(def), substs }) => {
if substs.non_erasable_generics().next().is_some() {
let symbol = ExportedSymbol::Generic(def, substs);
MonoItem::Fn(Instance { def: InstanceDef::Item(def), args }) => {
if args.non_erasable_generics().next().is_some() {
let symbol = ExportedSymbol::Generic(def, args);
symbols.push((
symbol,
SymbolExportInfo {
@ -355,10 +355,10 @@ fn exported_symbols_provider_local(
));
}
}
MonoItem::Fn(Instance { def: InstanceDef::DropGlue(_, Some(ty)), substs }) => {
MonoItem::Fn(Instance { def: InstanceDef::DropGlue(_, Some(ty)), args }) => {
// A little sanity-check
debug_assert_eq!(
substs.non_erasable_generics().next(),
args.non_erasable_generics().next(),
Some(GenericArgKind::Type(ty))
);
symbols.push((
@ -386,7 +386,7 @@ fn exported_symbols_provider_local(
fn upstream_monomorphizations_provider(
tcx: TyCtxt<'_>,
(): (),
) -> DefIdMap<FxHashMap<SubstsRef<'_>, CrateNum>> {
) -> DefIdMap<FxHashMap<GenericArgsRef<'_>, CrateNum>> {
let cnums = tcx.crates(());
let mut instances: DefIdMap<FxHashMap<_, _>> = Default::default();
@ -395,11 +395,11 @@ fn upstream_monomorphizations_provider(
for &cnum in cnums.iter() {
for (exported_symbol, _) in tcx.exported_symbols(cnum).iter() {
let (def_id, substs) = match *exported_symbol {
ExportedSymbol::Generic(def_id, substs) => (def_id, substs),
let (def_id, args) = match *exported_symbol {
ExportedSymbol::Generic(def_id, args) => (def_id, args),
ExportedSymbol::DropGlue(ty) => {
if let Some(drop_in_place_fn_def_id) = drop_in_place_fn_def_id {
(drop_in_place_fn_def_id, tcx.mk_substs(&[ty.into()]))
(drop_in_place_fn_def_id, tcx.mk_args(&[ty.into()]))
} else {
// `drop_in_place` in place does not exist, don't try
// to use it.
@ -414,9 +414,9 @@ fn upstream_monomorphizations_provider(
}
};
let substs_map = instances.entry(def_id).or_default();
let args_map = instances.entry(def_id).or_default();
match substs_map.entry(substs) {
match args_map.entry(args) {
Occupied(mut e) => {
// If there are multiple monomorphizations available,
// we select one deterministically.
@ -438,17 +438,17 @@ fn upstream_monomorphizations_provider(
fn upstream_monomorphizations_for_provider(
tcx: TyCtxt<'_>,
def_id: DefId,
) -> Option<&FxHashMap<SubstsRef<'_>, CrateNum>> {
) -> Option<&FxHashMap<GenericArgsRef<'_>, CrateNum>> {
debug_assert!(!def_id.is_local());
tcx.upstream_monomorphizations(()).get(&def_id)
}
fn upstream_drop_glue_for_provider<'tcx>(
tcx: TyCtxt<'tcx>,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
) -> Option<CrateNum> {
if let Some(def_id) = tcx.lang_items().drop_in_place_fn() {
tcx.upstream_monomorphizations_for(def_id).and_then(|monos| monos.get(&substs).cloned())
tcx.upstream_monomorphizations_for(def_id).and_then(|monos| monos.get(&args).cloned())
} else {
None
}
@ -521,10 +521,10 @@ pub fn symbol_name_for_instance_in_crate<'tcx>(
instantiating_crate,
)
}
ExportedSymbol::Generic(def_id, substs) => {
ExportedSymbol::Generic(def_id, args) => {
rustc_symbol_mangling::symbol_name_for_instance_in_crate(
tcx,
Instance::new(def_id, substs),
Instance::new(def_id, args),
instantiating_crate,
)
}
@ -533,7 +533,7 @@ pub fn symbol_name_for_instance_in_crate<'tcx>(
tcx,
ty::Instance {
def: ty::InstanceDef::ThreadLocalShim(def_id),
substs: ty::InternalSubsts::empty(),
args: ty::GenericArgs::empty(),
},
instantiating_crate,
)
@ -580,7 +580,7 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
None
}
ExportedSymbol::NonGeneric(def_id) => Some(Instance::mono(tcx, def_id)),
ExportedSymbol::Generic(def_id, substs) => Some(Instance::new(def_id, substs)),
ExportedSymbol::Generic(def_id, args) => Some(Instance::new(def_id, args)),
// DropGlue always use the Rust calling convention and thus follow the target's default
// symbol decoration scheme.
ExportedSymbol::DropGlue(..) => None,

View file

@ -499,7 +499,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
cx.tcx(),
ty::ParamEnv::reveal_all(),
start_def_id,
cx.tcx().mk_substs(&[main_ret_ty.into()]),
cx.tcx().mk_args(&[main_ret_ty.into()]),
)
.unwrap()
.unwrap(),

View file

@ -17,8 +17,8 @@ use rustc_hir::def_id::DefId;
use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Mutability};
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::{self, ExistentialProjection, ParamEnv, Ty, TyCtxt};
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
use rustc_target::abi::Integer;
use smallvec::SmallVec;
@ -77,7 +77,7 @@ fn push_debuginfo_type_name<'tcx>(
ty::Uint(uint_ty) => output.push_str(uint_ty.name_str()),
ty::Float(float_ty) => output.push_str(float_ty.name_str()),
ty::Foreign(def_id) => push_item_name(tcx, def_id, qualified, output),
ty::Adt(def, substs) => {
ty::Adt(def, args) => {
// `layout_for_cpp_like_fallback` will be `Some` if we want to use the fallback encoding.
let layout_for_cpp_like_fallback = if cpp_like_debuginfo && def.is_enum() {
match tcx.layout_of(ParamEnv::reveal_all().and(t)) {
@ -106,14 +106,14 @@ fn push_debuginfo_type_name<'tcx>(
ty_and_layout,
&|output, visited| {
push_item_name(tcx, def.did(), true, output);
push_generic_params_internal(tcx, substs, output, visited);
push_generic_params_internal(tcx, args, output, visited);
},
output,
visited,
);
} else {
push_item_name(tcx, def.did(), qualified, output);
push_generic_params_internal(tcx, substs, output, visited);
push_generic_params_internal(tcx, args, output, visited);
}
}
ty::Tuple(component_types) => {
@ -238,7 +238,7 @@ fn push_debuginfo_type_name<'tcx>(
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), principal);
push_item_name(tcx, principal.def_id, qualified, output);
let principal_has_generic_params =
push_generic_params_internal(tcx, principal.substs, output, visited);
push_generic_params_internal(tcx, principal.args, output, visited);
let projection_bounds: SmallVec<[_; 4]> = trait_data
.projection_bounds()
@ -393,7 +393,7 @@ fn push_debuginfo_type_name<'tcx>(
// processing
visited.remove(&t);
}
ty::Closure(def_id, substs) | ty::Generator(def_id, substs, ..) => {
ty::Closure(def_id, args) | ty::Generator(def_id, args, ..) => {
// Name will be "{closure_env#0}<T1, T2, ...>", "{generator_env#0}<T1, T2, ...>", or
// "{async_fn_env#0}<T1, T2, ...>", etc.
// In the case of cpp-like debuginfo, the name additionally gets wrapped inside of
@ -403,13 +403,13 @@ fn push_debuginfo_type_name<'tcx>(
msvc_enum_fallback(
ty_and_layout,
&|output, visited| {
push_closure_or_generator_name(tcx, def_id, substs, true, output, visited);
push_closure_or_generator_name(tcx, def_id, args, true, output, visited);
},
output,
visited,
);
} else {
push_closure_or_generator_name(tcx, def_id, substs, qualified, output, visited);
push_closure_or_generator_name(tcx, def_id, args, qualified, output, visited);
}
}
// Type parameters from polymorphized functions.
@ -516,7 +516,7 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), trait_ref);
push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name);
visited.clear();
push_generic_params_internal(tcx, trait_ref.substs, &mut vtable_name, &mut visited);
push_generic_params_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited);
} else {
vtable_name.push('_');
}
@ -609,21 +609,21 @@ fn push_unqualified_item_name(
fn push_generic_params_internal<'tcx>(
tcx: TyCtxt<'tcx>,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
output: &mut String,
visited: &mut FxHashSet<Ty<'tcx>>,
) -> bool {
if substs.non_erasable_generics().next().is_none() {
if args.non_erasable_generics().next().is_none() {
return false;
}
debug_assert_eq!(substs, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substs));
debug_assert_eq!(args, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args));
let cpp_like_debuginfo = cpp_like_debuginfo(tcx);
output.push('<');
for type_parameter in substs.non_erasable_generics() {
for type_parameter in args.non_erasable_generics() {
match type_parameter {
GenericArgKind::Type(type_parameter) => {
push_debuginfo_type_name(tcx, type_parameter, true, output, visited);
@ -688,16 +688,20 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
.unwrap();
}
pub fn push_generic_params<'tcx>(tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>, output: &mut String) {
pub fn push_generic_params<'tcx>(
tcx: TyCtxt<'tcx>,
args: GenericArgsRef<'tcx>,
output: &mut String,
) {
let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name");
let mut visited = FxHashSet::default();
push_generic_params_internal(tcx, substs, output, &mut visited);
push_generic_params_internal(tcx, args, output, &mut visited);
}
fn push_closure_or_generator_name<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: DefId,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
qualified: bool,
output: &mut String,
visited: &mut FxHashSet<Ty<'tcx>>,
@ -731,10 +735,10 @@ fn push_closure_or_generator_name<'tcx>(
let enclosing_fn_def_id = tcx.typeck_root_def_id(def_id);
let generics = tcx.generics_of(enclosing_fn_def_id);
// Truncate the substs to the length of the above generics. This will cut off
// Truncate the args to the length of the above generics. This will cut off
// anything closure- or generator-specific.
let substs = substs.truncate_to(tcx, generics);
push_generic_params_internal(tcx, substs, output, visited);
let args = args.truncate_to(tcx, generics);
push_generic_params_internal(tcx, args, output, visited);
}
fn push_close_angle_bracket(cpp_like_debuginfo: bool, output: &mut String) {

View file

@ -1,6 +1,6 @@
use crate::traits::*;
use rustc_middle::ty::{self, subst::GenericArgKind, Ty};
use rustc_middle::ty::{self, GenericArgKind, Ty};
use rustc_session::config::Lto;
use rustc_symbol_mangling::typeid_for_trait_ref;
use rustc_target::abi::call::FnAbi;

View file

@ -23,6 +23,8 @@ use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode, Reg};
use rustc_target::abi::{self, HasDataLayout, WrappingRange};
use rustc_target::spec::abi::Abi;
use std::cmp;
// Indicates if we are in the middle of merging a BB's successor into it. This
// can happen when BB jumps directly to its successor and the successor has no
// other predecessors.
@ -491,7 +493,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
//
let virtual_drop = Instance {
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
substs: drop_fn.substs,
args: drop_fn.args,
};
debug!("ty = {:?}", ty);
debug!("drop_fn = {:?}", drop_fn);
@ -531,7 +533,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// SO THEN WE CAN USE THE ABOVE CODE.
let virtual_drop = Instance {
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
substs: drop_fn.substs,
args: drop_fn.args,
};
debug!("ty = {:?}", ty);
debug!("drop_fn = {:?}", drop_fn);
@ -687,7 +689,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// which mentions the offending type, even from a const context.
let panic_intrinsic = intrinsic.and_then(|s| ValidityRequirement::from_intrinsic(s));
if let Some(requirement) = panic_intrinsic {
let ty = instance.unwrap().substs.type_at(0);
let ty = instance.unwrap().args.type_at(0);
let do_panic = !bx
.tcx()
@ -760,13 +762,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let callee = self.codegen_operand(bx, func);
let (instance, mut llfn) = match *callee.layout.ty.kind() {
ty::FnDef(def_id, substs) => (
ty::FnDef(def_id, args) => (
Some(
ty::Instance::expect_resolve(
bx.tcx(),
ty::ParamEnv::reveal_all(),
def_id,
substs,
args,
)
.polymorphize(bx.tcx()),
),
@ -1125,12 +1127,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
mir::InlineAsmOperand::SymFn { ref value } => {
let literal = self.monomorphize(value.literal);
if let ty::FnDef(def_id, substs) = *literal.ty().kind() {
if let ty::FnDef(def_id, args) = *literal.ty().kind() {
let instance = ty::Instance::resolve_for_fn_ptr(
bx.tcx(),
ty::ParamEnv::reveal_all(),
def_id,
substs,
args,
)
.unwrap();
InlineAsmOperandRef::SymFn { instance }
@ -1360,36 +1362,58 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// Force by-ref if we have to load through a cast pointer.
let (mut llval, align, by_ref) = match op.val {
Immediate(_) | Pair(..) => match arg.mode {
PassMode::Indirect { .. } | PassMode::Cast(..) => {
PassMode::Indirect { attrs, .. } => {
// Indirect argument may have higher alignment requirements than the type's alignment.
// This can happen, e.g. when passing types with <4 byte alignment on the stack on x86.
let required_align = match attrs.pointee_align {
Some(pointee_align) => cmp::max(pointee_align, arg.layout.align.abi),
None => arg.layout.align.abi,
};
let scratch = PlaceRef::alloca_aligned(bx, arg.layout, required_align);
op.val.store(bx, scratch);
(scratch.llval, scratch.align, true)
}
PassMode::Cast(..) => {
let scratch = PlaceRef::alloca(bx, arg.layout);
op.val.store(bx, scratch);
(scratch.llval, scratch.align, true)
}
_ => (op.immediate_or_packed_pair(bx), arg.layout.align.abi, false),
},
Ref(llval, _, align) => {
if arg.is_indirect() && align < arg.layout.align.abi {
// `foo(packed.large_field)`. We can't pass the (unaligned) field directly. I
// think that ATM (Rust 1.16) we only pass temporaries, but we shouldn't
// have scary latent bugs around.
let scratch = PlaceRef::alloca(bx, arg.layout);
base::memcpy_ty(
bx,
scratch.llval,
scratch.align,
llval,
align,
op.layout,
MemFlags::empty(),
);
(scratch.llval, scratch.align, true)
} else {
(llval, align, true)
Ref(llval, _, align) => match arg.mode {
PassMode::Indirect { attrs, .. } => {
let required_align = match attrs.pointee_align {
Some(pointee_align) => cmp::max(pointee_align, arg.layout.align.abi),
None => arg.layout.align.abi,
};
if align < required_align {
// For `foo(packed.large_field)`, and types with <4 byte alignment on x86,
// alignment requirements may be higher than the type's alignment, so copy
// to a higher-aligned alloca.
let scratch = PlaceRef::alloca_aligned(bx, arg.layout, required_align);
base::memcpy_ty(
bx,
scratch.llval,
scratch.align,
llval,
align,
op.layout,
MemFlags::empty(),
);
(scratch.llval, scratch.align, true)
} else {
(llval, align, true)
}
}
}
_ => (llval, align, true),
},
ZeroSized => match arg.mode {
PassMode::Indirect { .. } => {
PassMode::Indirect { on_stack, .. } => {
if on_stack {
// It doesn't seem like any target can have `byval` ZSTs, so this assert
// is here to replace a would-be untested codepath.
bug!("ZST {op:?} passed on stack with abi {arg:?}");
}
// Though `extern "Rust"` doesn't pass ZSTs, some ABIs pass
// a pointer for `repr(C)` structs even when empty, so get
// one from an `alloca` (which can be left uninitialized).

View file

@ -186,7 +186,11 @@ fn calculate_debuginfo_offset<
} => {
let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset);
let FieldsShape::Array { stride, count: _ } = place.layout().fields else {
span_bug!(var.source_info.span, "ConstantIndex on non-array type {:?}", place.layout())
span_bug!(
var.source_info.span,
"ConstantIndex on non-array type {:?}",
place.layout()
)
};
*offset += stride * index;
place = place.project_constant_index(bx, index);

View file

@ -64,7 +64,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
) {
let callee_ty = instance.ty(bx.tcx(), ty::ParamEnv::reveal_all());
let ty::FnDef(def_id, substs) = *callee_ty.kind() else {
let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else {
bug!("expected fn item type, found {}", callee_ty);
};
@ -87,7 +87,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
sym::va_start => bx.va_start(args[0].immediate()),
sym::va_end => bx.va_end(args[0].immediate()),
sym::size_of_val => {
let tp_ty = substs.type_at(0);
let tp_ty = fn_args.type_at(0);
if let OperandValue::Pair(_, meta) = args[0].val {
let (llsize, _) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
llsize
@ -96,7 +96,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
sym::min_align_of_val => {
let tp_ty = substs.type_at(0);
let tp_ty = fn_args.type_at(0);
if let OperandValue::Pair(_, meta) = args[0].val {
let (_, llalign) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
llalign
@ -136,7 +136,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
OperandRef::from_const(bx, value, ret_ty).immediate_or_packed_pair(bx)
}
sym::arith_offset => {
let ty = substs.type_at(0);
let ty = fn_args.type_at(0);
let layout = bx.layout_of(ty);
let ptr = args[0].immediate();
let offset = args[1].immediate();
@ -147,7 +147,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx,
true,
false,
substs.type_at(0),
fn_args.type_at(0),
args[1].immediate(),
args[0].immediate(),
args[2].immediate(),
@ -158,7 +158,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
memset_intrinsic(
bx,
false,
substs.type_at(0),
fn_args.type_at(0),
args[0].immediate(),
args[1].immediate(),
args[2].immediate(),
@ -171,7 +171,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx,
false,
true,
substs.type_at(0),
fn_args.type_at(0),
args[0].immediate(),
args[1].immediate(),
args[2].immediate(),
@ -183,7 +183,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx,
true,
true,
substs.type_at(0),
fn_args.type_at(0),
args[0].immediate(),
args[1].immediate(),
args[2].immediate(),
@ -194,7 +194,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
memset_intrinsic(
bx,
true,
substs.type_at(0),
fn_args.type_at(0),
args[0].immediate(),
args[1].immediate(),
args[2].immediate(),
@ -307,7 +307,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let Some((success, failure)) = ordering.split_once('_') else {
bx.sess().emit_fatal(errors::AtomicCompareExchange);
};
let ty = substs.type_at(0);
let ty = fn_args.type_at(0);
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
let weak = instruction == "cxchgweak";
let mut dst = args[0].immediate();
@ -338,7 +338,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
"load" => {
let ty = substs.type_at(0);
let ty = fn_args.type_at(0);
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
let layout = bx.layout_of(ty);
let size = layout.size;
@ -361,7 +361,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
"store" => {
let ty = substs.type_at(0);
let ty = fn_args.type_at(0);
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
let size = bx.layout_of(ty).size;
let mut val = args[1].immediate();
@ -407,7 +407,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
_ => bx.sess().emit_fatal(errors::UnknownAtomicOperation),
};
let ty = substs.type_at(0);
let ty = fn_args.type_at(0);
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
let mut ptr = args[0].immediate();
let mut val = args[1].immediate();
@ -439,7 +439,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
sym::ptr_offset_from | sym::ptr_offset_from_unsigned => {
let ty = substs.type_at(0);
let ty = fn_args.type_at(0);
let pointee_size = bx.layout_of(ty).size;
let a = args[0].immediate();

View file

@ -159,7 +159,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
cx: &'a Bx::CodegenCx,
instance: Instance<'tcx>,
) {
assert!(!instance.substs.has_infer());
assert!(!instance.args.has_infer());
let llfn = cx.get_fn(instance);

View file

@ -47,10 +47,18 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
pub fn alloca<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
bx: &mut Bx,
layout: TyAndLayout<'tcx>,
) -> Self {
Self::alloca_aligned(bx, layout, layout.align.abi)
}
pub fn alloca_aligned<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
bx: &mut Bx,
layout: TyAndLayout<'tcx>,
align: Align,
) -> Self {
assert!(layout.is_sized(), "tried to statically allocate unsized place");
let tmp = bx.alloca(bx.cx().backend_type(layout), layout.align.abi);
Self::new_sized(tmp, layout)
let tmp = bx.alloca(bx.cx().backend_type(layout), align);
Self::new_sized_aligned(tmp, layout, align)
}
/// Returns a place for an indirect reference to an unsized place.

View file

@ -417,12 +417,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
match *operand.layout.ty.kind() {
ty::FnDef(def_id, substs) => {
ty::FnDef(def_id, args) => {
let instance = ty::Instance::resolve_for_fn_ptr(
bx.tcx(),
ty::ParamEnv::reveal_all(),
def_id,
substs,
args,
)
.unwrap()
.polymorphize(bx.cx().tcx());
@ -433,11 +433,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => {
match *operand.layout.ty.kind() {
ty::Closure(def_id, substs) => {
ty::Closure(def_id, args) => {
let instance = Instance::resolve_closure(
bx.cx().tcx(),
def_id,
substs,
args,
ty::ClosureKind::FnOnce,
)
.expect("failed to normalize and resolve closure during codegen")
@ -711,7 +711,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
{
let instance = ty::Instance {
def: ty::InstanceDef::ThreadLocalShim(def_id),
substs: ty::InternalSubsts::empty(),
args: ty::GenericArgs::empty(),
};
let fn_ptr = bx.get_fn_addr(instance);
let fn_abi = bx.fn_abi_of_instance(instance, ty::List::empty());

View file

@ -64,7 +64,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
.typeck_body(anon_const.body)
.node_type(anon_const.hir_id);
let instance = match ty.kind() {
&ty::FnDef(def_id, substs) => Instance::new(def_id, substs),
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
_ => span_bug!(*op_sp, "asm sym is not a function"),
};
@ -138,7 +138,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
fn to_raw_string(&self) -> String {
match *self {
MonoItem::Fn(instance) => {
format!("Fn({:?}, {})", instance.def, instance.substs.as_ptr().addr())
format!("Fn({:?}, {})", instance.def, instance.args.as_ptr().addr())
}
MonoItem::Static(id) => format!("Static({:?})", id),
MonoItem::GlobalAsm(id) => format!("GlobalAsm({:?})", id),

View file

@ -369,13 +369,9 @@ pub fn from_target_feature(
// We allow comma separation to enable multiple features.
target_features.extend(value.as_str().split(',').filter_map(|feature| {
let Some(feature_gate) = supported_target_features.get(feature) else {
let msg =
format!("the feature named `{}` is not valid for this target", feature);
let msg = format!("the feature named `{}` is not valid for this target", feature);
let mut err = tcx.sess.struct_span_err(item.span(), msg);
err.span_label(
item.span(),
format!("`{}` is not valid for this target", feature),
);
err.span_label(item.span(), format!("`{}` is not valid for this target", feature));
if let Some(stripped) = feature.strip_prefix('+') {
let valid = supported_target_features.contains_key(stripped);
if valid {

View file

@ -150,8 +150,8 @@ where
tcx.sess.create_err(Spanned { span, node: layout_error.into_diagnostic() });
err.code(rustc_errors::error_code!(E0080));
let Some((mut err, handler)) = err.into_diagnostic() else {
panic!("did not emit diag");
};
panic!("did not emit diag");
};
for frame in frames {
err.eager_subdiagnostic(handler, frame);
}

View file

@ -45,7 +45,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
"Unexpected DefKind: {:?}",
ecx.tcx.def_kind(cid.instance.def_id())
);
let layout = ecx.layout_of(body.bound_return_ty().subst(tcx, cid.instance.substs))?;
let layout = ecx.layout_of(body.bound_return_ty().instantiate(tcx, cid.instance.args))?;
assert!(layout.is_sized());
let ret = ecx.allocate(layout, MemoryKind::Stack)?;
@ -245,10 +245,10 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
// Catch such calls and evaluate them instead of trying to load a constant's MIR.
if let ty::InstanceDef::Intrinsic(def_id) = key.value.instance.def {
let ty = key.value.instance.ty(tcx, key.param_env);
let ty::FnDef(_, substs) = ty.kind() else {
let ty::FnDef(_, args) = ty.kind() else {
bug!("intrinsic with type {:?}", ty);
};
return eval_nullary_intrinsic(tcx, key.param_env, def_id, substs).map_err(|error| {
return eval_nullary_intrinsic(tcx, key.param_env, def_id, args).map_err(|error| {
let span = tcx.def_span(def_id);
super::report(
@ -328,10 +328,10 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
("static", String::new())
} else {
// If the current item has generics, we'd like to enrich the message with the
// instance and its substs: to show the actual compile-time values, in addition to
// instance and its args: to show the actual compile-time values, in addition to
// the expression, leading to the const eval error.
let instance = &key.value.instance;
if !instance.substs.is_empty() {
if !instance.args.is_empty() {
let instance = with_no_trimmed_paths!(instance.to_string());
("const_with_path", instance)
} else {

View file

@ -230,7 +230,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
*self.tcx,
ty::ParamEnv::reveal_all(),
const_def_id,
instance.substs,
instance.args,
)
.unwrap()
.unwrap();

View file

@ -105,7 +105,7 @@ pub(crate) fn try_destructure_mir_constant_for_diagnostics<'tcx>(
let down = ecx.operand_downcast(&op, variant).ok()?;
(def.variants()[variant].fields.len(), Some(variant), down)
}
ty::Tuple(substs) => (substs.len(), None, op),
ty::Tuple(args) => (args.len(), None, op),
_ => bug!("cannot destructure mir constant {:?}", val),
};

View file

@ -416,9 +416,9 @@ fn valtree_into_mplace<'tcx>(
debug!(?unsized_inner_ty);
let inner_ty = match ty.kind() {
ty::Adt(def, substs) => {
ty::Adt(def, args) => {
let i = FieldIdx::from_usize(i);
def.variant(FIRST_VARIANT).fields[i].ty(tcx, substs)
def.variant(FIRST_VARIANT).fields[i].ty(tcx, args)
}
ty::Tuple(inner_tys) => inner_tys[i],
_ => bug!("unexpected unsized type {:?}", ty),

View file

@ -75,12 +75,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// The src operand does not matter, just its type
match *src.layout.ty.kind() {
ty::FnDef(def_id, substs) => {
ty::FnDef(def_id, args) => {
let instance = ty::Instance::resolve_for_fn_ptr(
*self.tcx,
self.param_env,
def_id,
substs,
args,
)
.ok_or_else(|| err_inval!(TooGeneric))?;
@ -108,11 +108,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// The src operand does not matter, just its type
match *src.layout.ty.kind() {
ty::Closure(def_id, substs) => {
ty::Closure(def_id, args) => {
let instance = ty::Instance::resolve_closure(
*self.tcx,
def_id,
substs,
args,
ty::ClosureKind::FnOnce,
)
.ok_or_else(|| err_inval!(TooGeneric))?;

View file

@ -164,11 +164,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
ty::Adt(adt, _) => {
adt.discriminants(*self.tcx).find(|(_, var)| var.val == discr_bits)
}
ty::Generator(def_id, substs, _) => {
let substs = substs.as_generator();
substs
.discriminants(def_id, *self.tcx)
.find(|(_, var)| var.val == discr_bits)
ty::Generator(def_id, args, _) => {
let args = args.as_generator();
args.discriminants(def_id, *self.tcx).find(|(_, var)| var.val == discr_bits)
}
_ => span_bug!(self.cur_span(), "tagged layout for non-adt non-generator"),
}

View file

@ -13,7 +13,7 @@ use rustc_middle::ty::layout::{
self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers,
TyAndLayout,
};
use rustc_middle::ty::{self, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable};
use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable};
use rustc_mir_dataflow::storage::always_storage_live_locals;
use rustc_session::Limit;
use rustc_span::Span;
@ -91,7 +91,7 @@ pub struct Frame<'mir, 'tcx, Prov: Provenance = AllocId, Extra = ()> {
/// The MIR for the function called on this frame.
pub body: &'mir mir::Body<'tcx>,
/// The def_id and substs of the current function.
/// The def_id and args of the current function.
pub instance: ty::Instance<'tcx>,
/// Extra data for the machine.
@ -529,16 +529,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
.map_err(|_| err_inval!(TooGeneric))
}
/// The `substs` are assumed to already be in our interpreter "universe" (param_env).
/// The `args` are assumed to already be in our interpreter "universe" (param_env).
pub(super) fn resolve(
&self,
def: DefId,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
) -> InterpResult<'tcx, ty::Instance<'tcx>> {
trace!("resolve: {:?}, {:#?}", def, substs);
trace!("resolve: {:?}, {:#?}", def, args);
trace!("param_env: {:#?}", self.param_env);
trace!("substs: {:#?}", substs);
match ty::Instance::resolve(*self.tcx, self.param_env, def, substs) {
trace!("args: {:#?}", args);
match ty::Instance::resolve(*self.tcx, self.param_env, def, args) {
Ok(Some(instance)) => Ok(instance),
Ok(None) => throw_inval!(TooGeneric),
@ -604,7 +604,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// the last field). Can't have foreign types here, how would we
// adjust alignment and size for them?
let field = layout.field(self, layout.fields.count() - 1);
let Some((unsized_size, mut unsized_align)) = self.size_and_align_of(metadata, &field)? else {
let Some((unsized_size, mut unsized_align)) =
self.size_and_align_of(metadata, &field)?
else {
// A field with an extern type. We don't know the actual dynamic size
// or the alignment.
return Ok(None);
@ -682,7 +684,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
return_to_block: StackPopCleanup,
) -> InterpResult<'tcx> {
trace!("body: {:#?}", body);
// First push a stack frame so we have access to the local substs
// First push a stack frame so we have access to the local args
let pre_frame = Frame {
body,
loc: Right(body.span), // Span used for errors caused during preamble.

View file

@ -12,7 +12,7 @@ use rustc_middle::mir::{
};
use rustc_middle::ty;
use rustc_middle::ty::layout::{LayoutOf as _, ValidityRequirement};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{Ty, TyCtxt};
use rustc_span::symbol::{sym, Symbol};
use rustc_target::abi::{Abi, Align, Primitive, Size};
@ -56,9 +56,9 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
def_id: DefId,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
) -> InterpResult<'tcx, ConstValue<'tcx>> {
let tp_ty = substs.type_at(0);
let tp_ty = args.type_at(0);
let name = tcx.item_name(def_id);
Ok(match name {
sym::type_name => {
@ -123,7 +123,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
dest: &PlaceTy<'tcx, M::Provenance>,
ret: Option<mir::BasicBlock>,
) -> InterpResult<'tcx, bool> {
let substs = instance.substs;
let instance_args = instance.args;
let intrinsic_name = self.tcx.item_name(instance.def_id());
// First handle intrinsics without return place.
@ -187,7 +187,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
| sym::ctlz_nonzero
| sym::bswap
| sym::bitreverse => {
let ty = substs.type_at(0);
let ty = instance_args.type_at(0);
let layout_of = self.layout_of(ty)?;
let val = self.read_scalar(&args[0])?;
let bits = val.to_bits(layout_of.size)?;
@ -237,7 +237,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
sym::rotate_left | sym::rotate_right => {
// rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
// rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
let layout = self.layout_of(substs.type_at(0))?;
let layout = self.layout_of(instance_args.type_at(0))?;
let val = self.read_scalar(&args[0])?;
let val_bits = val.to_bits(layout.size)?;
let raw_shift = self.read_scalar(&args[1])?;
@ -263,7 +263,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
sym::arith_offset => {
let ptr = self.read_pointer(&args[0])?;
let offset_count = self.read_target_isize(&args[1])?;
let pointee_ty = substs.type_at(0);
let pointee_ty = instance_args.type_at(0);
let pointee_size = i64::try_from(self.layout_of(pointee_ty)?.size.bytes()).unwrap();
let offset_bytes = offset_count.wrapping_mul(pointee_size);
@ -368,7 +368,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
assert!(self.target_isize_min() <= dist && dist <= self.target_isize_max());
isize_layout
};
let pointee_layout = self.layout_of(substs.type_at(0))?;
let pointee_layout = self.layout_of(instance_args.type_at(0))?;
// If ret_layout is unsigned, we checked that so is the distance, so we are good.
let val = ImmTy::from_int(dist, ret_layout);
let size = ImmTy::from_int(pointee_layout.size.bytes(), ret_layout);
@ -378,7 +378,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
sym::assert_inhabited
| sym::assert_zero_valid
| sym::assert_mem_uninitialized_valid => {
let ty = instance.substs.type_at(0);
let ty = instance.args.type_at(0);
let requirement = ValidityRequirement::from_intrinsic(intrinsic_name).unwrap();
let should_panic = !self

View file

@ -96,7 +96,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let loc_ty = self
.tcx
.type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None))
.subst(*self.tcx, self.tcx.mk_substs(&[self.tcx.lifetimes.re_erased.into()]));
.instantiate(*self.tcx, self.tcx.mk_args(&[self.tcx.lifetimes.re_erased.into()]));
let loc_layout = self.layout_of(loc_ty).unwrap();
let location = self.allocate(loc_layout, MemoryKind::CallerLocation).unwrap();

View file

@ -1060,11 +1060,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let size = Size::from_bytes(len);
let Some(alloc_ref) = self.get_ptr_alloc_mut(ptr, size, Align::ONE)? else {
// zero-sized access
assert_matches!(
src.next(),
None,
"iterator said it was empty but returned an element"
);
assert_matches!(src.next(), None, "iterator said it was empty but returned an element");
return Ok(());
};

View file

@ -590,7 +590,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
throw_inval!(AlreadyReported(reported.into()))
}
ty::ConstKind::Unevaluated(uv) => {
let instance = self.resolve(uv.def, uv.substs)?;
let instance = self.resolve(uv.def, uv.args)?;
let cid = GlobalId { instance, promoted: None };
self.ctfe_query(span, |tcx| {
tcx.eval_to_valtree(self.param_env.with_const().and(cid))
@ -619,7 +619,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
mir::ConstantKind::Val(val, ty) => self.const_val_to_op(val, ty, layout),
mir::ConstantKind::Unevaluated(uv, _) => {
let instance = self.resolve(uv.def, uv.substs)?;
let instance = self.resolve(uv.def, uv.args)?;
Ok(self.eval_global(GlobalId { instance, promoted: uv.promoted }, span)?.into())
}
}

View file

@ -545,14 +545,17 @@ where
// wrong type.
let tcx = *self.tcx;
let Some(mut alloc) = self.get_place_alloc_mut(&MPlaceTy { mplace: dest, layout, align })? else {
let Some(mut alloc) =
self.get_place_alloc_mut(&MPlaceTy { mplace: dest, layout, align })?
else {
// zero-sized access
return Ok(());
};
match value {
Immediate::Scalar(scalar) => {
let Abi::Scalar(s) = layout.abi else { span_bug!(
let Abi::Scalar(s) = layout.abi else {
span_bug!(
self.cur_span(),
"write_immediate_to_mplace: invalid Scalar layout: {layout:#?}",
)
@ -565,7 +568,8 @@ where
// We checked `ptr_align` above, so all fields will have the alignment they need.
// We would anyway check against `ptr_align.restrict_for_offset(b_offset)`,
// which `ptr.offset(b_offset)` cannot possibly fail to satisfy.
let Abi::ScalarPair(a, b) = layout.abi else { span_bug!(
let Abi::ScalarPair(a, b) = layout.abi else {
span_bug!(
self.cur_span(),
"write_immediate_to_mplace: invalid ScalarPair layout: {:#?}",
layout

View file

@ -135,8 +135,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let fn_val = self.get_ptr_fn(fn_ptr)?;
(fn_val, self.fn_abi_of_fn_ptr(fn_sig_binder, extra_args)?, false)
}
ty::FnDef(def_id, substs) => {
let instance = self.resolve(def_id, substs)?;
ty::FnDef(def_id, args) => {
let instance = self.resolve(def_id, args)?;
(
FnVal::Instance(instance),
self.fn_abi_of_instance(instance, extra_args)?,
@ -390,7 +390,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
));
// Allocate enough memory to hold `src`.
let Some((size, align)) = self.size_and_align_of_mplace(&src)? else {
span_bug!(self.cur_span(), "unsized fn arg with `extern` type tail should not be allowed")
span_bug!(
self.cur_span(),
"unsized fn arg with `extern` type tail should not be allowed"
)
};
let ptr = self.allocate_ptr(size, align, MemoryKind::Stack)?;
let dest_place =
@ -468,10 +471,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
| ty::InstanceDef::ThreadLocalShim(..)
| ty::InstanceDef::Item(_) => {
// We need MIR for this fn
let Some((body, instance)) =
M::find_mir_or_eval_fn(self, instance, caller_abi, args, destination, target, unwind)? else {
return Ok(());
};
let Some((body, instance)) = M::find_mir_or_eval_fn(
self,
instance,
caller_abi,
args,
destination,
target,
unwind,
)?
else {
return Ok(());
};
// Compute callee information using the `instance` returned by
// `find_mir_or_eval_fn`.
@ -702,8 +713,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
.tcx
.struct_tail_erasing_lifetimes(receiver_place.layout.ty, self.param_env);
let ty::Dynamic(data, _, ty::Dyn) = receiver_tail.kind() else {
span_bug!(self.cur_span(), "dynamic call on non-`dyn` type {}", receiver_tail)
};
span_bug!(
self.cur_span(),
"dynamic call on non-`dyn` type {}",
receiver_tail
)
};
assert!(receiver_place.layout.is_unsized());
// Get the required information from the vtable.
@ -721,7 +736,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Now determine the actual method to call. We can do that in two different ways and
// compare them to ensure everything fits.
let Some(ty::VtblEntry::Method(fn_inst)) = self.get_vtable_entries(vptr)?.get(idx).copied() else {
let Some(ty::VtblEntry::Method(fn_inst)) =
self.get_vtable_entries(vptr)?.get(idx).copied()
else {
// FIXME(fee1-dead) these could be variants of the UB info enum instead of this
throw_ub_custom!(fluent::const_eval_dyn_call_not_a_method);
};
@ -731,7 +748,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let trait_def_id = tcx.trait_of_item(def_id).unwrap();
let virtual_trait_ref =
ty::TraitRef::from_method(tcx, trait_def_id, instance.substs);
ty::TraitRef::from_method(tcx, trait_def_id, instance.args);
let existential_trait_ref =
ty::ExistentialTraitRef::erase_self_ty(tcx, virtual_trait_ref);
let concrete_trait_ref = existential_trait_ref.with_self_ty(tcx, dyn_ty);
@ -740,7 +757,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
tcx,
self.param_env,
def_id,
instance.substs.rebase_onto(tcx, trait_def_id, concrete_trait_ref.substs),
instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args),
)
.unwrap();
assert_eq!(fn_inst, concrete_method);

View file

@ -33,12 +33,12 @@ where
match *ty.kind() {
ty::Param(_) => ControlFlow::Break(FoundParam),
ty::Closure(def_id, substs)
| ty::Generator(def_id, substs, ..)
| ty::FnDef(def_id, substs) => {
ty::Closure(def_id, args)
| ty::Generator(def_id, args, ..)
| ty::FnDef(def_id, args) => {
let instance = ty::InstanceDef::Item(def_id);
let unused_params = self.tcx.unused_generic_params(instance);
for (index, subst) in substs.into_iter().enumerate() {
for (index, subst) in args.into_iter().enumerate() {
let index = index
.try_into()
.expect("more generic parameters than can fit into a `u32`");

View file

@ -8,8 +8,8 @@ use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, InstanceDef, Ty, TyCtxt};
use rustc_middle::ty::{GenericArgKind, GenericArgs};
use rustc_middle::ty::{TraitRef, TypeVisitableExt};
use rustc_mir_dataflow::{self, Analysis};
use rustc_span::{sym, Span, Symbol};
@ -701,8 +701,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
let fn_ty = func.ty(body, tcx);
let (mut callee, mut substs) = match *fn_ty.kind() {
ty::FnDef(def_id, substs) => (def_id, substs),
let (mut callee, mut fn_args) = match *fn_ty.kind() {
ty::FnDef(def_id, fn_args) => (def_id, fn_args),
ty::FnPtr(_) => {
self.check_op(ops::FnCallIndirect);
@ -721,7 +721,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
let predicates = tcx.predicates_of(callee).instantiate(tcx, substs);
let predicates = tcx.predicates_of(callee).instantiate(tcx, fn_args);
let cause = ObligationCause::new(
terminator.source_info.span,
self.body.source.def_id().expect_local(),
@ -746,7 +746,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
self.check_op(ops::FnCallNonConst {
caller,
callee,
substs,
args: fn_args,
span: *fn_span,
call_source: *call_source,
feature: Some(sym::const_trait_impl),
@ -754,7 +754,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
return;
}
let trait_ref = TraitRef::from_method(tcx, trait_id, substs);
let trait_ref = TraitRef::from_method(tcx, trait_id, fn_args);
let trait_ref = trait_ref.with_constness(ty::BoundConstness::ConstIfConst);
let obligation =
Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
@ -778,8 +778,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
if trait_ref.self_ty().is_closure()
&& tcx.fn_trait_kind_from_def_id(trait_id).is_some() =>
{
let ty::Closure(closure_def_id, substs) =
*trait_ref.self_ty().kind()
let ty::Closure(closure_def_id, fn_args) = *trait_ref.self_ty().kind()
else {
unreachable!()
};
@ -787,7 +786,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
self.check_op(ops::FnCallNonConst {
caller,
callee,
substs,
args: fn_args,
span: *fn_span,
call_source: *call_source,
feature: None,
@ -803,9 +802,9 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
.iter()
.find(|did| tcx.item_name(**did) == callee_name)
{
// using internal substs is ok here, since this is only
// using internal args is ok here, since this is only
// used for the `resolve` call below
substs = InternalSubsts::identity_for_item(tcx, did);
fn_args = GenericArgs::identity_for_item(tcx, did);
callee = did;
}
@ -813,7 +812,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
self.check_op(ops::FnCallNonConst {
caller,
callee,
substs,
args: fn_args,
span: *fn_span,
call_source: *call_source,
feature: None,
@ -829,7 +828,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
&& tcx.has_attr(callee_trait, sym::const_trait)
&& Some(callee_trait) == tcx.trait_of_item(caller.to_def_id())
// Can only call methods when it's `<Self as TheTrait>::f`.
&& tcx.types.self_param == substs.type_at(0)
&& tcx.types.self_param == fn_args.type_at(0)
{
nonconst_call_permission = true;
}
@ -856,7 +855,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
self.check_op(ops::FnCallNonConst {
caller,
callee,
substs,
args: fn_args,
span: *fn_span,
call_source: *call_source,
feature: None,
@ -869,7 +868,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
// Resolve a trait method call to its concrete implementation, which may be in a
// `const` trait impl.
let instance = Instance::resolve(tcx, param_env, callee, substs);
let instance = Instance::resolve(tcx, param_env, callee, fn_args);
debug!("Resolving ({:?}) -> {:?}", callee, instance);
if let Ok(Some(func)) = instance {
if let InstanceDef::Item(def) = func.def {
@ -916,7 +915,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
self.check_op(ops::FnCallNonConst {
caller,
callee,
substs,
args: fn_args,
span: *fn_span,
call_source: *call_source,
feature: None,

View file

@ -68,11 +68,11 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
pub fn fn_sig(&self) -> PolyFnSig<'tcx> {
let did = self.def_id().to_def_id();
if self.tcx.is_closure(did) {
let ty = self.tcx.type_of(did).subst_identity();
let ty::Closure(_, substs) = ty.kind() else { bug!("type_of closure not ty::Closure") };
substs.as_closure().sig()
let ty = self.tcx.type_of(did).instantiate_identity();
let ty::Closure(_, args) = ty.kind() else { bug!("type_of closure not ty::Closure") };
args.as_closure().sig()
} else {
self.tcx.fn_sig(did).subst_identity()
self.tcx.fn_sig(did).instantiate_identity()
}
}
}

View file

@ -9,9 +9,9 @@ use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
use rustc_middle::mir::{self, CallSource};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::TraitRef;
use rustc_middle::ty::{suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, Ty};
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
use rustc_middle::util::{call_kind, CallDesugaringKind, CallKind};
use rustc_session::parse::feature_err;
use rustc_span::symbol::sym;
@ -98,7 +98,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallIndirect {
pub struct FnCallNonConst<'tcx> {
pub caller: LocalDefId,
pub callee: DefId,
pub substs: SubstsRef<'tcx>,
pub args: GenericArgsRef<'tcx>,
pub span: Span,
pub call_source: CallSource,
pub feature: Option<Symbol>,
@ -110,11 +110,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
ccx: &ConstCx<'_, 'tcx>,
_: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let FnCallNonConst { caller, callee, substs, span, call_source, feature } = *self;
let FnCallNonConst { caller, callee, args, span, call_source, feature } = *self;
let ConstCx { tcx, param_env, .. } = *ccx;
let diag_trait = |err, self_ty: Ty<'_>, trait_id| {
let trait_ref = TraitRef::from_method(tcx, trait_id, substs);
let trait_ref = TraitRef::from_method(tcx, trait_id, args);
match self_ty.kind() {
Param(param_ty) => {
@ -154,7 +154,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
};
let call_kind =
call_kind(tcx, ccx.param_env, callee, substs, span, call_source.from_hir_call(), None);
call_kind(tcx, ccx.param_env, callee, args, span, call_source.from_hir_call(), None);
debug!(?call_kind);
@ -226,7 +226,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
let mut sugg = None;
if Some(trait_id) == ccx.tcx.lang_items().eq_trait() {
match (substs[0].unpack(), substs[1].unpack()) {
match (args[0].unpack(), args[1].unpack()) {
(GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty))
if self_ty == rhs_ty
&& self_ty.is_ref()
@ -297,7 +297,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
.create_err(errors::NonConstFmtMacroCall { span, kind: ccx.const_kind() }),
_ => ccx.tcx.sess.create_err(errors::NonConstFnCall {
span,
def_path_str: ccx.tcx.def_path_str_with_substs(callee, substs),
def_path_str: ccx.tcx.def_path_str_with_args(callee, args),
kind: ccx.const_kind(),
}),
};

View file

@ -7,7 +7,7 @@ use rustc_hir::LangItem;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::mir;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, subst::SubstsRef, AdtDef, Ty};
use rustc_middle::ty::{self, AdtDef, GenericArgsRef, Ty};
use rustc_trait_selection::traits::{
self, ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext,
};
@ -72,7 +72,7 @@ pub trait Qualif {
fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>,
adt: AdtDef<'tcx>,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
) -> bool;
}
@ -97,7 +97,7 @@ impl Qualif for HasMutInterior {
fn in_adt_inherently<'tcx>(
_cx: &ConstCx<'_, 'tcx>,
adt: AdtDef<'tcx>,
_: SubstsRef<'tcx>,
_: GenericArgsRef<'tcx>,
) -> bool {
// Exactly one type, `UnsafeCell`, has the `HasMutInterior` qualif inherently.
// It arises structurally for all other types.
@ -127,7 +127,7 @@ impl Qualif for NeedsDrop {
fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>,
adt: AdtDef<'tcx>,
_: SubstsRef<'tcx>,
_: GenericArgsRef<'tcx>,
) -> bool {
adt.has_dtor(cx.tcx)
}
@ -193,7 +193,7 @@ impl Qualif for NeedsNonConstDrop {
fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>,
adt: AdtDef<'tcx>,
_: SubstsRef<'tcx>,
_: GenericArgsRef<'tcx>,
) -> bool {
adt.has_non_const_dtor(cx.tcx)
}
@ -221,9 +221,9 @@ impl Qualif for CustomEq {
fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>,
def: AdtDef<'tcx>,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
) -> bool {
let ty = Ty::new_adt(cx.tcx, def, substs);
let ty = Ty::new_adt(cx.tcx, def, args);
!ty.is_structural_eq_shallow(cx.tcx)
}
}
@ -276,9 +276,9 @@ where
Rvalue::Aggregate(kind, operands) => {
// Return early if we know that the struct or enum being constructed is always
// qualified.
if let AggregateKind::Adt(adt_did, _, substs, ..) = **kind {
if let AggregateKind::Adt(adt_did, _, args, ..) = **kind {
let def = cx.tcx.adt_def(adt_did);
if Q::in_adt_inherently(cx, def, substs) {
if Q::in_adt_inherently(cx, def, args) {
return true;
}
if def.is_union() && Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx)) {
@ -360,7 +360,7 @@ where
ConstantKind::Val(..) => None,
};
if let Some(mir::UnevaluatedConst { def, substs: _, promoted }) = uneval {
if let Some(mir::UnevaluatedConst { def, args: _, promoted }) = uneval {
// Use qualifs of the type for the promoted. Promoteds in MIR body should be possible
// only for `NeedsNonConstDrop` with precise drop checking. This is the only const
// check performed after the promotion. Verify that with an assertion.

View file

@ -16,7 +16,7 @@ use rustc_hir as hir;
use rustc_middle::mir;
use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::GenericArgs;
use rustc_middle::ty::{self, List, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::Span;
@ -759,11 +759,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
let (mut rvalue, source_info) = {
let statement = &mut self.source[loc.block].statements[loc.statement_index];
let StatementKind::Assign(box (_, rhs)) = &mut statement.kind else {
span_bug!(
statement.source_info.span,
"{:?} is not an assignment",
statement
);
span_bug!(statement.source_info.span, "{:?} is not an assignment", statement);
};
(
@ -845,8 +841,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
let mut promoted_operand = |ty, span| {
promoted.span = span;
promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def));
let uneval = mir::UnevaluatedConst { def, substs, promoted: Some(promoted_id) };
let args = tcx.erase_regions(GenericArgs::identity_for_item(tcx, def));
let uneval = mir::UnevaluatedConst { def, args, promoted: Some(promoted_id) };
Operand::Constant(Box::new(Constant {
span,
@ -859,7 +855,9 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
let local_decls = &mut self.source.local_decls;
let loc = candidate.location;
let statement = &mut blocks[loc.block].statements[loc.statement_index];
let StatementKind::Assign(box (_, Rvalue::Ref(region, borrow_kind, place))) = &mut statement.kind else {
let StatementKind::Assign(box (_, Rvalue::Ref(region, borrow_kind, place))) =
&mut statement.kind
else {
bug!()
};

View file

@ -214,9 +214,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
stack.clear();
stack.insert(bb);
loop {
let Some(parent)= parent[bb].take() else {
break
};
let Some(parent) = parent[bb].take() else { break };
let no_cycle = stack.insert(parent);
if !no_cycle {
self.fail(
@ -360,8 +358,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
};
let kind = match parent_ty.ty.kind() {
&ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
self.tcx.type_of(def_id).subst(self.tcx, substs).kind()
&ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
self.tcx.type_of(def_id).instantiate(self.tcx, args).kind()
}
kind => kind,
};
@ -374,23 +372,23 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
};
check_equal(self, location, *f_ty);
}
ty::Adt(adt_def, substs) => {
ty::Adt(adt_def, args) => {
let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT);
let Some(field) = adt_def.variant(var).fields.get(f) else {
fail_out_of_bounds(self, location);
return;
};
check_equal(self, location, field.ty(self.tcx, substs));
check_equal(self, location, field.ty(self.tcx, args));
}
ty::Closure(_, substs) => {
let substs = substs.as_closure();
let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else {
ty::Closure(_, args) => {
let args = args.as_closure();
let Some(f_ty) = args.upvar_tys().nth(f.as_usize()) else {
fail_out_of_bounds(self, location);
return;
};
check_equal(self, location, f_ty);
}
&ty::Generator(def_id, substs, _) => {
&ty::Generator(def_id, args, _) => {
let f_ty = if let Some(var) = parent_ty.variant_index {
let gen_body = if def_id == self.body.source.def_id() {
self.body
@ -399,7 +397,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
};
let Some(layout) = gen_body.generator_layout() else {
self.fail(location, format!("No generator layout for {:?}", parent_ty));
self.fail(
location,
format!("No generator layout for {:?}", parent_ty),
);
return;
};
@ -409,13 +410,16 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
};
let Some(f_ty) = layout.field_tys.get(local) else {
self.fail(location, format!("Out of bounds local {:?} for {:?}", local, parent_ty));
self.fail(
location,
format!("Out of bounds local {:?} for {:?}", local, parent_ty),
);
return;
};
f_ty.ty
} else {
let Some(f_ty) = substs.as_generator().prefix_tys().nth(f.index()) else {
let Some(f_ty) = args.as_generator().prefix_tys().nth(f.index()) else {
fail_out_of_bounds(self, location);
return;
};
@ -730,7 +734,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty);
}
ty::Adt(adt_def, substs) => {
ty::Adt(adt_def, args) => {
if adt_def.is_enum() {
self.fail(
location,
@ -744,7 +748,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
return;
};
let f_ty = field.ty(self.tcx, substs);
let f_ty = field.ty(self.tcx, args);
current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty);
}
_ => {

View file

@ -4,8 +4,7 @@ use rustc_hir::definitions::DisambiguatedDefPathData;
use rustc_middle::ty::{
self,
print::{PrettyPrinter, Print, Printer},
subst::{GenericArg, GenericArgKind},
Ty, TyCtxt,
GenericArg, GenericArgKind, Ty, TyCtxt,
};
use std::fmt::Write;
@ -56,11 +55,11 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
}
// Types with identity (print the module path).
ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs)
| ty::FnDef(def_id, substs)
| ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, substs, .. })
| ty::Closure(def_id, substs)
| ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs),
ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), args)
| ty::FnDef(def_id, args)
| ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. })
| ty::Closure(def_id, args)
| ty::Generator(def_id, args, _) => self.print_def_path(def_id, args),
ty::Foreign(def_id) => self.print_def_path(def_id, &[]),
ty::Alias(ty::Weak, _) => bug!("type_name: unexpected weak projection"),

View file

@ -176,9 +176,7 @@ pub fn dominators<G: ControlFlowGraph>(graph: &G) -> Dominators<G::Node> {
//
// ...this may be the case if a MirPass modifies the CFG to remove
// or rearrange certain blocks/edges.
let Some(v) = real_to_pre_order[v] else {
continue
};
let Some(v) = real_to_pre_order[v] else { continue };
// eval returns a vertex x from which semi[x] is minimum among
// vertices semi[v] +> x *> v.

View file

@ -31,6 +31,7 @@ use crate::{
///
/// It's still possible to do the same thing with an `Fn` by using interior mutability,
/// but the chance of doing it accidentally is reduced.
#[derive(Clone)]
pub struct UnordItems<T, I: Iterator<Item = T>>(I);
impl<T, I: Iterator<Item = T>> UnordItems<T, I> {
@ -167,6 +168,14 @@ impl<T: Ord, I: Iterator<Item = T>> UnordItems<T, I> {
}
}
/// A marker trait specifying that `Self` can consume `UnordItems<_>` without
/// exposing any internal ordering.
///
/// Note: right now this is just a marker trait. It could be extended to contain
/// some useful, common methods though, like `len`, `clear`, or the various
/// kinds of `to_sorted`.
trait UnordCollection {}
/// This is a set collection type that tries very hard to not expose
/// any internal iteration. This is a useful property when trying to
/// uphold the determinism invariants imposed by the query system.
@ -181,6 +190,8 @@ pub struct UnordSet<V: Eq + Hash> {
inner: FxHashSet<V>,
}
impl<V: Eq + Hash> UnordCollection for UnordSet<V> {}
impl<V: Eq + Hash> Default for UnordSet<V> {
#[inline]
fn default() -> Self {
@ -194,6 +205,11 @@ impl<V: Eq + Hash> UnordSet<V> {
Self { inner: Default::default() }
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
Self { inner: FxHashSet::with_capacity_and_hasher(capacity, Default::default()) }
}
#[inline]
pub fn len(&self) -> usize {
self.inner.len()
@ -258,9 +274,9 @@ impl<V: Eq + Hash> UnordSet<V> {
#[inline]
pub fn to_sorted_stable_ord(&self) -> Vec<V>
where
V: Ord + StableOrd + Copy,
V: Ord + StableOrd + Clone,
{
let mut items: Vec<V> = self.inner.iter().copied().collect();
let mut items: Vec<V> = self.inner.iter().cloned().collect();
items.sort_unstable();
items
}
@ -279,19 +295,31 @@ impl<V: Eq + Hash> UnordSet<V> {
to_sorted_vec(hcx, self.inner.into_iter(), cache_sort_key, |x| x)
}
// We can safely extend this UnordSet from a set of unordered values because that
// won't expose the internal ordering anywhere.
#[inline]
pub fn extend_unord<I: Iterator<Item = V>>(&mut self, items: UnordItems<V, I>) {
self.inner.extend(items.0)
}
#[inline]
pub fn clear(&mut self) {
self.inner.clear();
}
}
pub trait ExtendUnord<T> {
/// Extend this unord collection with the given `UnordItems`.
/// This method is called `extend_unord` instead of just `extend` so it
/// does not conflict with `Extend::extend`. Otherwise there would be many
/// places where the two methods would have to be explicitly disambiguated
/// via UFCS.
fn extend_unord<I: Iterator<Item = T>>(&mut self, items: UnordItems<T, I>);
}
// Note: it is important that `C` implements `UnordCollection` in addition to
// `Extend`, otherwise this impl would leak the internal iteration order of
// `items`, e.g. when calling `some_vec.extend_unord(some_unord_items)`.
impl<C: Extend<T> + UnordCollection, T> ExtendUnord<T> for C {
#[inline]
fn extend_unord<I: Iterator<Item = T>>(&mut self, items: UnordItems<T, I>) {
self.extend(items.0)
}
}
impl<V: Hash + Eq> Extend<V> for UnordSet<V> {
#[inline]
fn extend<T: IntoIterator<Item = V>>(&mut self, iter: T) {
@ -312,6 +340,12 @@ impl<V: Hash + Eq> From<FxHashSet<V>> for UnordSet<V> {
}
}
impl<V: Hash + Eq, I: Iterator<Item = V>> From<UnordItems<V, I>> for UnordSet<V> {
fn from(value: UnordItems<V, I>) -> Self {
UnordSet { inner: FxHashSet::from_iter(value.0) }
}
}
impl<HCX, V: Hash + Eq + HashStable<HCX>> HashStable<HCX> for UnordSet<V> {
#[inline]
fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
@ -333,6 +367,8 @@ pub struct UnordMap<K: Eq + Hash, V> {
inner: FxHashMap<K, V>,
}
impl<K: Eq + Hash, V> UnordCollection for UnordMap<K, V> {}
impl<K: Eq + Hash, V> Default for UnordMap<K, V> {
#[inline]
fn default() -> Self {
@ -362,6 +398,11 @@ impl<K: Hash + Eq, V, I: Iterator<Item = (K, V)>> From<UnordItems<(K, V), I>> fo
}
impl<K: Eq + Hash, V> UnordMap<K, V> {
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
Self { inner: FxHashMap::with_capacity_and_hasher(capacity, Default::default()) }
}
#[inline]
pub fn len(&self) -> usize {
self.inner.len()
@ -428,13 +469,6 @@ impl<K: Eq + Hash, V> UnordMap<K, V> {
UnordItems(self.inner.into_iter())
}
// We can safely extend this UnordMap from a set of unordered values because that
// won't expose the internal ordering anywhere.
#[inline]
pub fn extend<I: Iterator<Item = (K, V)>>(&mut self, items: UnordItems<(K, V), I>) {
self.inner.extend(items.0)
}
/// Returns the entries of this map in stable sort order (as defined by `ToStableHashKey`).
///
/// The `cache_sort_key` parameter controls if [slice::sort_by_cached_key] or
@ -554,15 +588,10 @@ impl<V> UnordBag<V> {
pub fn into_items(self) -> UnordItems<V, impl Iterator<Item = V>> {
UnordItems(self.inner.into_iter())
}
// We can safely extend this UnordSet from a set of unordered values because that
// won't expose the internal ordering anywhere.
#[inline]
pub fn extend<I: Iterator<Item = V>>(&mut self, items: UnordItems<V, I>) {
self.inner.extend(items.0)
}
}
impl<T> UnordCollection for UnordBag<T> {}
impl<T> Extend<T> for UnordBag<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.inner.extend(iter)

View file

@ -279,9 +279,6 @@ fn run_compiler(
let sopts = config::build_session_options(&mut early_error_handler, &matches);
// Set parallel mode before thread pool creation, which will create `Lock`s.
interface::set_thread_safe_mode(&sopts.unstable_opts);
if let Some(ref code) = matches.opt_str("explain") {
handle_explain(&early_error_handler, diagnostics_registry(), code, sopts.color);
return Ok(());

Some files were not shown because too many files have changed in this diff Show more