Merge pull request #4381 from rust-lang/rustup-2025-06-07
Automatic Rustup
This commit is contained in:
commit
31e9806777
199 changed files with 3582 additions and 3673 deletions
|
|
@ -50,18 +50,10 @@ pub enum CanonAbi {
|
|||
|
||||
impl fmt::Display for CanonAbi {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.to_erased_extern_abi().as_str().fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl CanonAbi {
|
||||
/// convert to the ExternAbi that *shares a string* with this CanonAbi
|
||||
///
|
||||
/// A target-insensitive mapping of CanonAbi to ExternAbi, convenient for "forwarding" impls.
|
||||
/// Importantly, the set of CanonAbi values is a logical *subset* of ExternAbi values,
|
||||
/// so this is injective: if you take an ExternAbi to a CanonAbi and back, you have lost data.
|
||||
const fn to_erased_extern_abi(self) -> ExternAbi {
|
||||
match self {
|
||||
// convert to the ExternAbi that *shares a string* with this CanonAbi.
|
||||
// FIXME: ideally we'd avoid printing `CanonAbi`, and preserve `ExternAbi` everywhere
|
||||
// that we need to generate error messages.
|
||||
let erased_abi = match self {
|
||||
CanonAbi::C => ExternAbi::C { unwind: false },
|
||||
CanonAbi::Rust => ExternAbi::Rust,
|
||||
CanonAbi::RustCold => ExternAbi::RustCold,
|
||||
|
|
@ -87,7 +79,8 @@ impl CanonAbi {
|
|||
X86Call::Vectorcall => ExternAbi::Vectorcall { unwind: false },
|
||||
X86Call::Win64 => ExternAbi::Win64 { unwind: false },
|
||||
},
|
||||
}
|
||||
};
|
||||
erased_abi.as_str().fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,13 @@ rustc_index::newtype_index! {
|
|||
pub struct FieldIdx {}
|
||||
}
|
||||
|
||||
impl FieldIdx {
|
||||
/// The second field, at index 1.
|
||||
///
|
||||
/// For use alongside [`FieldIdx::ZERO`], particularly with scalar pairs.
|
||||
pub const ONE: FieldIdx = FieldIdx::from_u32(1);
|
||||
}
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
/// The *source-order* index of a variant in a type.
|
||||
///
|
||||
|
|
@ -274,7 +281,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
|
|||
|
||||
/// Finds the one field that is not a 1-ZST.
|
||||
/// Returns `None` if there are multiple non-1-ZST fields or only 1-ZST-fields.
|
||||
pub fn non_1zst_field<C>(&self, cx: &C) -> Option<(usize, Self)>
|
||||
pub fn non_1zst_field<C>(&self, cx: &C) -> Option<(FieldIdx, Self)>
|
||||
where
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
{
|
||||
|
|
@ -288,7 +295,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
|
|||
// More than one non-1-ZST field.
|
||||
return None;
|
||||
}
|
||||
found = Some((field_idx, field));
|
||||
found = Some((FieldIdx::from_usize(field_idx), field));
|
||||
}
|
||||
found
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1119,10 +1119,9 @@ impl Stmt {
|
|||
pub fn add_trailing_semicolon(mut self) -> Self {
|
||||
self.kind = match self.kind {
|
||||
StmtKind::Expr(expr) => StmtKind::Semi(expr),
|
||||
StmtKind::MacCall(mac) => {
|
||||
StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs, tokens }| {
|
||||
MacCallStmt { mac, style: MacStmtStyle::Semicolon, attrs, tokens }
|
||||
}))
|
||||
StmtKind::MacCall(mut mac) => {
|
||||
mac.style = MacStmtStyle::Semicolon;
|
||||
StmtKind::MacCall(mac)
|
||||
}
|
||||
kind => kind,
|
||||
};
|
||||
|
|
@ -1724,7 +1723,7 @@ pub enum ExprKind {
|
|||
///
|
||||
/// Usually not written directly in user code but
|
||||
/// indirectly via the macro `core::mem::offset_of!(...)`.
|
||||
OffsetOf(P<Ty>, P<[Ident]>),
|
||||
OffsetOf(P<Ty>, Vec<Ident>),
|
||||
|
||||
/// A macro invocation; pre-expansion.
|
||||
MacCall(P<MacCall>),
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ impl Attribute {
|
|||
|
||||
pub fn unwrap_normal_item(self) -> AttrItem {
|
||||
match self.kind {
|
||||
AttrKind::Normal(normal) => normal.into_inner().item,
|
||||
AttrKind::Normal(normal) => normal.item,
|
||||
AttrKind::DocComment(..) => panic!("unexpected doc comment"),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,11 +208,7 @@ pub trait MutVisitor: Sized {
|
|||
}
|
||||
|
||||
fn visit_ident(&mut self, i: &mut Ident) {
|
||||
walk_ident(self, i);
|
||||
}
|
||||
|
||||
fn visit_modifiers(&mut self, m: &mut TraitBoundModifiers) {
|
||||
walk_modifiers(self, m);
|
||||
self.visit_span(&mut i.span);
|
||||
}
|
||||
|
||||
fn visit_path(&mut self, p: &mut Path) {
|
||||
|
|
@ -367,6 +363,33 @@ pub trait MutVisitor: Sized {
|
|||
|
||||
super::common_visitor_and_walkers!((mut) MutVisitor);
|
||||
|
||||
macro_rules! generate_flat_map_visitor_fns {
|
||||
($($name:ident, $Ty:ty, $flat_map_fn:ident$(, $param:ident: $ParamTy:ty)*;)+) => {
|
||||
$(
|
||||
fn $name<V: MutVisitor>(
|
||||
vis: &mut V,
|
||||
values: &mut ThinVec<$Ty>,
|
||||
$(
|
||||
$param: $ParamTy,
|
||||
)*
|
||||
) {
|
||||
values.flat_map_in_place(|value| vis.$flat_map_fn(value$(,$param)*));
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
generate_flat_map_visitor_fns! {
|
||||
visit_items, P<Item>, flat_map_item;
|
||||
visit_foreign_items, P<ForeignItem>, flat_map_foreign_item;
|
||||
visit_generic_params, GenericParam, flat_map_generic_param;
|
||||
visit_stmts, Stmt, flat_map_stmt;
|
||||
visit_exprs, P<Expr>, filter_map_expr;
|
||||
visit_pat_fields, PatField, flat_map_pat_field;
|
||||
visit_variants, Variant, flat_map_variant;
|
||||
visit_assoc_items, P<AssocItem>, flat_map_assoc_item, ctxt: AssocCtxt;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_vec<T, F>(elems: &mut Vec<T>, mut visit_elem: F)
|
||||
where
|
||||
|
|
@ -403,15 +426,6 @@ fn visit_attrs<T: MutVisitor>(vis: &mut T, attrs: &mut AttrVec) {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn visit_exprs<T: MutVisitor>(vis: &mut T, exprs: &mut Vec<P<Expr>>) {
|
||||
exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr))
|
||||
}
|
||||
|
||||
fn visit_thin_exprs<T: MutVisitor>(vis: &mut T, exprs: &mut ThinVec<P<Expr>>) {
|
||||
exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr))
|
||||
}
|
||||
|
||||
fn visit_attr_args<T: MutVisitor>(vis: &mut T, args: &mut AttrArgs) {
|
||||
match args {
|
||||
AttrArgs::Empty => {}
|
||||
|
|
@ -430,15 +444,6 @@ fn visit_delim_args<T: MutVisitor>(vis: &mut T, args: &mut DelimArgs) {
|
|||
vis.visit_span(close);
|
||||
}
|
||||
|
||||
pub fn walk_pat_field<T: MutVisitor>(vis: &mut T, fp: &mut PatField) {
|
||||
let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = fp;
|
||||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
vis.visit_ident(ident);
|
||||
vis.visit_pat(pat);
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_pat_field<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut fp: PatField,
|
||||
|
|
@ -447,21 +452,13 @@ pub fn walk_flat_map_pat_field<T: MutVisitor>(
|
|||
smallvec![fp]
|
||||
}
|
||||
|
||||
fn walk_use_tree<T: MutVisitor>(vis: &mut T, use_tree: &mut UseTree) {
|
||||
let UseTree { prefix, kind, span } = use_tree;
|
||||
vis.visit_path(prefix);
|
||||
match kind {
|
||||
UseTreeKind::Simple(rename) => visit_opt(rename, |rename| vis.visit_ident(rename)),
|
||||
UseTreeKind::Nested { items, span } => {
|
||||
for (tree, id) in items {
|
||||
vis.visit_id(id);
|
||||
vis.visit_use_tree(tree);
|
||||
}
|
||||
vis.visit_span(span);
|
||||
}
|
||||
UseTreeKind::Glob => {}
|
||||
}
|
||||
vis.visit_span(span);
|
||||
fn visit_nested_use_tree<V: MutVisitor>(
|
||||
vis: &mut V,
|
||||
nested_tree: &mut UseTree,
|
||||
nested_id: &mut NodeId,
|
||||
) {
|
||||
vis.visit_id(nested_id);
|
||||
vis.visit_use_tree(nested_tree);
|
||||
}
|
||||
|
||||
pub fn walk_arm<T: MutVisitor>(vis: &mut T, arm: &mut Arm) {
|
||||
|
|
@ -498,31 +495,6 @@ fn walk_assoc_item_constraint<T: MutVisitor>(
|
|||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_ty_pat<T: MutVisitor>(vis: &mut T, ty: &mut TyPat) {
|
||||
let TyPat { id, kind, span, tokens: _ } = ty;
|
||||
vis.visit_id(id);
|
||||
match kind {
|
||||
TyPatKind::Range(start, end, _include_end) => {
|
||||
visit_opt(start, |c| vis.visit_anon_const(c));
|
||||
visit_opt(end, |c| vis.visit_anon_const(c));
|
||||
}
|
||||
TyPatKind::Or(variants) => visit_thin_vec(variants, |p| vis.visit_ty_pat(p)),
|
||||
TyPatKind::Err(_) => {}
|
||||
}
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_variant<T: MutVisitor>(visitor: &mut T, variant: &mut Variant) {
|
||||
let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = variant;
|
||||
visitor.visit_id(id);
|
||||
visit_attrs(visitor, attrs);
|
||||
visitor.visit_vis(vis);
|
||||
visitor.visit_ident(ident);
|
||||
visitor.visit_variant_data(data);
|
||||
visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr));
|
||||
visitor.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_variant<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut variant: Variant,
|
||||
|
|
@ -531,25 +503,6 @@ pub fn walk_flat_map_variant<T: MutVisitor>(
|
|||
smallvec![variant]
|
||||
}
|
||||
|
||||
fn walk_ident<T: MutVisitor>(vis: &mut T, Ident { name: _, span }: &mut Ident) {
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
fn walk_path<T: MutVisitor>(vis: &mut T, Path { segments, span, tokens: _ }: &mut Path) {
|
||||
for segment in segments {
|
||||
vis.visit_path_segment(segment);
|
||||
}
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
fn walk_qself<T: MutVisitor>(vis: &mut T, qself: &mut Option<P<QSelf>>) {
|
||||
visit_opt(qself, |qself| {
|
||||
let QSelf { ty, path_span, position: _ } = &mut **qself;
|
||||
vis.visit_ty(ty);
|
||||
vis.visit_span(path_span);
|
||||
})
|
||||
}
|
||||
|
||||
fn walk_generic_args<T: MutVisitor>(vis: &mut T, generic_args: &mut GenericArgs) {
|
||||
match generic_args {
|
||||
GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data),
|
||||
|
|
@ -583,27 +536,6 @@ fn walk_parenthesized_parameter_data<T: MutVisitor>(vis: &mut T, args: &mut Pare
|
|||
vis.visit_span(inputs_span);
|
||||
}
|
||||
|
||||
fn walk_local<T: MutVisitor>(vis: &mut T, local: &mut Local) {
|
||||
let Local { id, super_, pat, ty, kind, span, colon_sp, attrs, tokens: _ } = local;
|
||||
visit_opt(super_, |sp| vis.visit_span(sp));
|
||||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
vis.visit_pat(pat);
|
||||
visit_opt(ty, |ty| vis.visit_ty(ty));
|
||||
match kind {
|
||||
LocalKind::Decl => {}
|
||||
LocalKind::Init(init) => {
|
||||
vis.visit_expr(init);
|
||||
}
|
||||
LocalKind::InitElse(init, els) => {
|
||||
vis.visit_expr(init);
|
||||
vis.visit_block(els);
|
||||
}
|
||||
}
|
||||
visit_opt(colon_sp, |sp| vis.visit_span(sp));
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
fn walk_attribute<T: MutVisitor>(vis: &mut T, attr: &mut Attribute) {
|
||||
let Attribute { kind, id: _, style: _, span } = attr;
|
||||
match kind {
|
||||
|
|
@ -853,35 +785,6 @@ fn walk_variant_data<T: MutVisitor>(vis: &mut T, vdata: &mut VariantData) {
|
|||
}
|
||||
}
|
||||
|
||||
fn walk_trait_ref<T: MutVisitor>(vis: &mut T, TraitRef { path, ref_id }: &mut TraitRef) {
|
||||
vis.visit_id(ref_id);
|
||||
vis.visit_path(path);
|
||||
}
|
||||
|
||||
fn walk_poly_trait_ref<T: MutVisitor>(vis: &mut T, p: &mut PolyTraitRef) {
|
||||
let PolyTraitRef { bound_generic_params, modifiers, trait_ref, span } = p;
|
||||
vis.visit_modifiers(modifiers);
|
||||
bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
|
||||
vis.visit_trait_ref(trait_ref);
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
fn walk_modifiers<V: MutVisitor>(vis: &mut V, m: &mut TraitBoundModifiers) {
|
||||
let TraitBoundModifiers { constness, asyncness, polarity } = m;
|
||||
match constness {
|
||||
BoundConstness::Never => {}
|
||||
BoundConstness::Always(span) | BoundConstness::Maybe(span) => vis.visit_span(span),
|
||||
}
|
||||
match asyncness {
|
||||
BoundAsyncness::Normal => {}
|
||||
BoundAsyncness::Async(span) => vis.visit_span(span),
|
||||
}
|
||||
match polarity {
|
||||
BoundPolarity::Positive => {}
|
||||
BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => vis.visit_span(span),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_field_def<T: MutVisitor>(visitor: &mut T, fd: &mut FieldDef) {
|
||||
let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _, safety, default } = fd;
|
||||
visitor.visit_id(id);
|
||||
|
|
@ -902,15 +805,6 @@ pub fn walk_flat_map_field_def<T: MutVisitor>(
|
|||
smallvec![fd]
|
||||
}
|
||||
|
||||
pub fn walk_expr_field<T: MutVisitor>(vis: &mut T, f: &mut ExprField) {
|
||||
let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = f;
|
||||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
vis.visit_ident(ident);
|
||||
vis.visit_expr(expr);
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_expr_field<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut f: ExprField,
|
||||
|
|
@ -930,16 +824,6 @@ pub fn walk_item_kind<K: WalkItemKind>(
|
|||
kind.walk(span, id, visibility, ctxt, vis)
|
||||
}
|
||||
|
||||
pub fn walk_crate<T: MutVisitor>(vis: &mut T, krate: &mut Crate) {
|
||||
let Crate { attrs, items, spans, id, is_placeholder: _ } = krate;
|
||||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
items.flat_map_in_place(|item| vis.flat_map_item(item));
|
||||
let ModSpans { inner_span, inject_use_span } = spans;
|
||||
vis.visit_span(inner_span);
|
||||
vis.visit_span(inject_use_span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_item(vis: &mut impl MutVisitor, mut item: P<Item>) -> SmallVec<[P<Item>; 1]> {
|
||||
vis.visit_item(&mut item);
|
||||
smallvec![item]
|
||||
|
|
@ -1021,7 +905,7 @@ pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, token
|
|||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
match kind {
|
||||
ExprKind::Array(exprs) => visit_thin_exprs(vis, exprs),
|
||||
ExprKind::Array(exprs) => visit_exprs(vis, exprs),
|
||||
ExprKind::ConstBlock(anon_const) => {
|
||||
vis.visit_anon_const(anon_const);
|
||||
}
|
||||
|
|
@ -1029,10 +913,10 @@ pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, token
|
|||
vis.visit_expr(expr);
|
||||
vis.visit_anon_const(count);
|
||||
}
|
||||
ExprKind::Tup(exprs) => visit_thin_exprs(vis, exprs),
|
||||
ExprKind::Tup(exprs) => visit_exprs(vis, exprs),
|
||||
ExprKind::Call(f, args) => {
|
||||
vis.visit_expr(f);
|
||||
visit_thin_exprs(vis, args);
|
||||
visit_exprs(vis, args);
|
||||
}
|
||||
ExprKind::MethodCall(box MethodCall {
|
||||
seg: PathSegment { ident, id, args: seg_args },
|
||||
|
|
@ -1044,7 +928,7 @@ pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, token
|
|||
vis.visit_id(id);
|
||||
vis.visit_ident(ident);
|
||||
visit_opt(seg_args, |args| vis.visit_generic_args(args));
|
||||
visit_thin_exprs(vis, call_args);
|
||||
visit_exprs(vis, call_args);
|
||||
vis.visit_span(span);
|
||||
}
|
||||
ExprKind::Binary(binop, lhs, rhs) => {
|
||||
|
|
|
|||
|
|
@ -1,209 +1,11 @@
|
|||
//! The AST pointer.
|
||||
//!
|
||||
//! Provides [`P<T>`][struct@P], an owned smart pointer.
|
||||
//!
|
||||
//! # Motivations and benefits
|
||||
//!
|
||||
//! * **Identity**: sharing AST nodes is problematic for the various analysis
|
||||
//! passes (e.g., one may be able to bypass the borrow checker with a shared
|
||||
//! `ExprKind::AddrOf` node taking a mutable borrow).
|
||||
//!
|
||||
//! * **Efficiency**: folding can reuse allocation space for `P<T>` and `Vec<T>`,
|
||||
//! the latter even when the input and output types differ (as it would be the
|
||||
//! case with arenas or a GADT AST using type parameters to toggle features).
|
||||
//!
|
||||
//! * **Maintainability**: `P<T>` provides an interface, which can remain fully
|
||||
//! functional even if the implementation changes (using a special thread-local
|
||||
//! heap, for example). Moreover, a switch to, e.g., `P<'a, T>` would be easy
|
||||
//! and mostly automated.
|
||||
|
||||
use std::fmt::{self, Debug, Display};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::{slice, vec};
|
||||
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
|
||||
/// An owned smart pointer.
|
||||
/// A pointer type that uniquely owns a heap allocation of type T.
|
||||
///
|
||||
/// See the [module level documentation][crate::ptr] for details.
|
||||
pub struct P<T: ?Sized> {
|
||||
ptr: Box<T>,
|
||||
}
|
||||
/// This used to be its own type, but now it's just a typedef for `Box` and we are planning to
|
||||
/// remove it soon.
|
||||
pub type P<T> = Box<T>;
|
||||
|
||||
/// Construct a `P<T>` from a `T` value.
|
||||
#[allow(non_snake_case)]
|
||||
pub fn P<T: 'static>(value: T) -> P<T> {
|
||||
P { ptr: Box::new(value) }
|
||||
}
|
||||
|
||||
impl<T: 'static> P<T> {
|
||||
/// Move out of the pointer.
|
||||
/// Intended for chaining transformations not covered by `map`.
|
||||
pub fn and_then<U, F>(self, f: F) -> U
|
||||
where
|
||||
F: FnOnce(T) -> U,
|
||||
{
|
||||
f(*self.ptr)
|
||||
}
|
||||
|
||||
/// Equivalent to `and_then(|x| x)`.
|
||||
pub fn into_inner(self) -> T {
|
||||
*self.ptr
|
||||
}
|
||||
|
||||
/// Produce a new `P<T>` from `self` without reallocating.
|
||||
pub fn map<F>(mut self, f: F) -> P<T>
|
||||
where
|
||||
F: FnOnce(T) -> T,
|
||||
{
|
||||
let x = f(*self.ptr);
|
||||
*self.ptr = x;
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Optionally produce a new `P<T>` from `self` without reallocating.
|
||||
pub fn filter_map<F>(mut self, f: F) -> Option<P<T>>
|
||||
where
|
||||
F: FnOnce(T) -> Option<T>,
|
||||
{
|
||||
*self.ptr = f(*self.ptr)?;
|
||||
Some(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Deref for P<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &T {
|
||||
&self.ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> DerefMut for P<T> {
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
&mut self.ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: 'static + Clone> Clone for P<T> {
|
||||
fn clone(&self) -> P<T> {
|
||||
P((**self).clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Debug> Debug for P<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
Debug::fmt(&self.ptr, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Display> Display for P<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
Display::fmt(&**self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> fmt::Pointer for P<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Pointer::fmt(&self.ptr, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Decoder, T: 'static + Decodable<D>> Decodable<D> for P<T> {
|
||||
fn decode(d: &mut D) -> P<T> {
|
||||
P(Decodable::decode(d))
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Encoder, T: Encodable<S>> Encodable<S> for P<T> {
|
||||
fn encode(&self, s: &mut S) {
|
||||
(**self).encode(s);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> P<[T]> {
|
||||
// FIXME(const-hack) make this const again
|
||||
pub fn new() -> P<[T]> {
|
||||
P { ptr: Box::default() }
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn from_vec(v: Vec<T>) -> P<[T]> {
|
||||
P { ptr: v.into_boxed_slice() }
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn into_vec(self) -> Vec<T> {
|
||||
self.ptr.into_vec()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Default for P<[T]> {
|
||||
/// Creates an empty `P<[T]>`.
|
||||
fn default() -> P<[T]> {
|
||||
P::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> Clone for P<[T]> {
|
||||
fn clone(&self) -> P<[T]> {
|
||||
P::from_vec(self.to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Vec<T>> for P<[T]> {
|
||||
fn from(v: Vec<T>) -> Self {
|
||||
P::from_vec(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<P<[T]>> for Vec<T> {
|
||||
fn from(val: P<[T]>) -> Self {
|
||||
val.into_vec()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FromIterator<T> for P<[T]> {
|
||||
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> P<[T]> {
|
||||
P::from_vec(iter.into_iter().collect())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoIterator for P<[T]> {
|
||||
type Item = T;
|
||||
type IntoIter = vec::IntoIter<T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.into_vec().into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> IntoIterator for &'a P<[T]> {
|
||||
type Item = &'a T;
|
||||
type IntoIter = slice::Iter<'a, T>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.ptr.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Encoder, T: Encodable<S>> Encodable<S> for P<[T]> {
|
||||
fn encode(&self, s: &mut S) {
|
||||
Encodable::encode(&**self, s);
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Decoder, T: Decodable<D>> Decodable<D> for P<[T]> {
|
||||
fn decode(d: &mut D) -> P<[T]> {
|
||||
P::from_vec(Decodable::decode(d))
|
||||
}
|
||||
}
|
||||
|
||||
impl<CTX, T> HashStable<CTX> for P<T>
|
||||
where
|
||||
T: ?Sized + HashStable<CTX>,
|
||||
{
|
||||
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
|
||||
(**self).hash_stable(hcx, hasher);
|
||||
}
|
||||
pub fn P<T>(value: T) -> P<T> {
|
||||
Box::new(value)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,9 +219,6 @@ pub trait Visitor<'ast>: Sized {
|
|||
fn visit_field_def(&mut self, s: &'ast FieldDef) -> Self::Result {
|
||||
walk_field_def(self, s)
|
||||
}
|
||||
fn visit_enum_def(&mut self, enum_definition: &'ast EnumDef) -> Self::Result {
|
||||
walk_enum_def(self, enum_definition)
|
||||
}
|
||||
fn visit_variant(&mut self, v: &'ast Variant) -> Self::Result {
|
||||
walk_variant(self, v)
|
||||
}
|
||||
|
|
@ -246,13 +243,12 @@ pub trait Visitor<'ast>: Sized {
|
|||
fn visit_path(&mut self, path: &'ast Path) -> Self::Result {
|
||||
walk_path(self, path)
|
||||
}
|
||||
fn visit_use_tree(
|
||||
&mut self,
|
||||
use_tree: &'ast UseTree,
|
||||
id: NodeId,
|
||||
_nested: bool,
|
||||
) -> Self::Result {
|
||||
walk_use_tree(self, use_tree, id)
|
||||
fn visit_use_tree(&mut self, use_tree: &'ast UseTree) -> Self::Result {
|
||||
walk_use_tree(self, use_tree)
|
||||
}
|
||||
fn visit_nested_use_tree(&mut self, use_tree: &'ast UseTree, id: NodeId) -> Self::Result {
|
||||
try_visit!(self.visit_id(id));
|
||||
self.visit_use_tree(use_tree)
|
||||
}
|
||||
fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) -> Self::Result {
|
||||
walk_path_segment(self, path_segment)
|
||||
|
|
@ -378,13 +374,39 @@ macro_rules! common_visitor_and_walkers {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_polarity<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, polarity: &$($lt)? $($mut)? ImplPolarity) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
fn visit_polarity<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
vis: &mut V,
|
||||
polarity: &$($lt)? $($mut)? ImplPolarity,
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
match polarity {
|
||||
ImplPolarity::Positive => { $(<V as Visitor<$lt>>::Result::output())? }
|
||||
ImplPolarity::Negative(span) => visit_span(vis, span),
|
||||
}
|
||||
}
|
||||
|
||||
$(${ignore($lt)}
|
||||
#[inline]
|
||||
)?
|
||||
fn visit_modifiers<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
vis: &mut V,
|
||||
m: &$($lt)? $($mut)? TraitBoundModifiers
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
let TraitBoundModifiers { constness, asyncness, polarity } = m;
|
||||
match constness {
|
||||
BoundConstness::Never => {}
|
||||
BoundConstness::Always(span) | BoundConstness::Maybe(span) => try_visit!(visit_span(vis, span)),
|
||||
}
|
||||
match asyncness {
|
||||
BoundAsyncness::Normal => {}
|
||||
BoundAsyncness::Async(span) => try_visit!(visit_span(vis, span)),
|
||||
}
|
||||
match polarity {
|
||||
BoundPolarity::Positive => {}
|
||||
BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => try_visit!(visit_span(vis, span)),
|
||||
}
|
||||
$(<V as Visitor<$lt>>::Result::output())?
|
||||
}
|
||||
|
||||
fn visit_bounds<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, bounds: &$($lt)? $($mut)? GenericBounds, ctxt: BoundKind) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
walk_list!(visitor, visit_param_bound, bounds, ctxt);
|
||||
$(<V as Visitor<$lt>>::Result::output())?
|
||||
|
|
@ -446,8 +468,7 @@ macro_rules! common_visitor_and_walkers {
|
|||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
match self {
|
||||
ItemKind::ExternCrate(_orig_name, ident) => vis.visit_ident(ident),
|
||||
// FIXME(fee1-dead): look into this weird assymetry
|
||||
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree$(${ignore($lt)}, id, false)?),
|
||||
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
|
||||
ItemKind::Static(box StaticItem {
|
||||
ident,
|
||||
ty,
|
||||
|
|
@ -478,12 +499,7 @@ macro_rules! common_visitor_and_walkers {
|
|||
ModSpans { inner_span, inject_use_span },
|
||||
_,
|
||||
) => {
|
||||
$(${ignore($mut)}
|
||||
items.flat_map_in_place(|item| vis.flat_map_item(item));
|
||||
)?
|
||||
$(${ignore($lt)}
|
||||
walk_list!(vis, visit_item, items);
|
||||
)?
|
||||
try_visit!(visit_items(vis, items));
|
||||
try_visit!(visit_span(vis, inner_span));
|
||||
try_visit!(visit_span(vis, inject_use_span));
|
||||
}
|
||||
|
|
@ -515,10 +531,7 @@ macro_rules! common_visitor_and_walkers {
|
|||
ItemKind::Enum(ident, generics, enum_definition) => {
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
try_visit!(vis.visit_generics(generics));
|
||||
$(${ignore($mut)}
|
||||
enum_definition.variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
|
||||
)?
|
||||
$(${ignore($lt)}vis.visit_enum_def(enum_definition))?
|
||||
visit_variants(vis, &$($mut)? enum_definition.variants)
|
||||
}
|
||||
ItemKind::Struct(ident, generics, variant_data)
|
||||
| ItemKind::Union(ident, generics, variant_data) => {
|
||||
|
|
@ -543,35 +556,14 @@ macro_rules! common_visitor_and_walkers {
|
|||
try_visit!(visit_polarity(vis, polarity));
|
||||
visit_opt!(vis, visit_trait_ref, of_trait);
|
||||
try_visit!(vis.visit_ty(self_ty));
|
||||
$(${ignore($mut)}
|
||||
items.flat_map_in_place(|item| {
|
||||
vis.flat_map_assoc_item(item, AssocCtxt::Impl { of_trait: of_trait.is_some() })
|
||||
});
|
||||
)?
|
||||
$(${ignore($lt)}
|
||||
walk_list!(
|
||||
vis,
|
||||
visit_assoc_item,
|
||||
items,
|
||||
AssocCtxt::Impl { of_trait: of_trait.is_some() }
|
||||
);
|
||||
<V as Visitor<$lt>>::Result::output()
|
||||
)?
|
||||
visit_assoc_items(vis, items, AssocCtxt::Impl { of_trait: of_trait.is_some() })
|
||||
}
|
||||
ItemKind::Trait(box Trait { safety, is_auto: _, ident, generics, bounds, items }) => {
|
||||
try_visit!(visit_safety(vis, safety));
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
try_visit!(vis.visit_generics(generics));
|
||||
try_visit!(visit_bounds(vis, bounds, BoundKind::Bound));
|
||||
$(${ignore($mut)}
|
||||
items.flat_map_in_place(|item| {
|
||||
vis.flat_map_assoc_item(item, AssocCtxt::Trait)
|
||||
});
|
||||
)?
|
||||
$(${ignore($lt)}
|
||||
walk_list!(vis, visit_assoc_item, items, AssocCtxt::Trait);
|
||||
<V as Visitor<$lt>>::Result::output()
|
||||
)?
|
||||
visit_assoc_items(vis, items, AssocCtxt::Trait)
|
||||
}
|
||||
ItemKind::TraitAlias(ident, generics, bounds) => {
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
|
|
@ -616,7 +608,10 @@ macro_rules! common_visitor_and_walkers {
|
|||
}
|
||||
}
|
||||
|
||||
fn walk_const_item<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, item: &$($lt)? $($mut)? ConstItem) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
fn walk_const_item<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
vis: &mut V,
|
||||
item: &$($lt)? $($mut)? ConstItem,
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
let ConstItem { defaultness, ident, generics, ty, expr, define_opaque } = item;
|
||||
try_visit!(visit_defaultness(vis, defaultness));
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
|
|
@ -629,13 +624,7 @@ macro_rules! common_visitor_and_walkers {
|
|||
fn walk_foreign_mod<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, foreign_mod: &$($lt)? $($mut)? ForeignMod) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod;
|
||||
try_visit!(visit_safety(vis, safety));
|
||||
$(${ignore($mut)}
|
||||
items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
|
||||
)?
|
||||
$(
|
||||
walk_list!(vis, visit_foreign_item, items);
|
||||
<V as Visitor<$lt>>::Result::output()
|
||||
)?
|
||||
visit_foreign_items(vis, items)
|
||||
}
|
||||
|
||||
fn walk_define_opaques<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
|
|
@ -780,15 +769,13 @@ macro_rules! common_visitor_and_walkers {
|
|||
vis: &mut V,
|
||||
coroutine_kind: &$($lt)? $($mut)? CoroutineKind,
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
match coroutine_kind {
|
||||
CoroutineKind::Async { span, closure_id, return_impl_trait_id }
|
||||
let (CoroutineKind::Async { span, closure_id, return_impl_trait_id }
|
||||
| CoroutineKind::Gen { span, closure_id, return_impl_trait_id }
|
||||
| CoroutineKind::AsyncGen { span, closure_id, return_impl_trait_id } => {
|
||||
try_visit!(visit_id(vis, closure_id));
|
||||
try_visit!(visit_id(vis, return_impl_trait_id));
|
||||
visit_span(vis, span)
|
||||
}
|
||||
}
|
||||
| CoroutineKind::AsyncGen { span, closure_id, return_impl_trait_id })
|
||||
= coroutine_kind;
|
||||
try_visit!(visit_id(vis, closure_id));
|
||||
try_visit!(visit_id(vis, return_impl_trait_id));
|
||||
visit_span(vis, span)
|
||||
}
|
||||
|
||||
pub fn walk_pat<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
|
|
@ -817,15 +804,7 @@ macro_rules! common_visitor_and_walkers {
|
|||
PatKind::Struct(opt_qself, path, fields, _rest) => {
|
||||
try_visit!(vis.visit_qself(opt_qself));
|
||||
try_visit!(vis.visit_path(path));
|
||||
|
||||
$(
|
||||
${ignore($lt)}
|
||||
walk_list!(vis, visit_pat_field, fields);
|
||||
)?
|
||||
$(
|
||||
${ignore($mut)}
|
||||
fields.flat_map_in_place(|field| vis.flat_map_pat_field(field));
|
||||
)?
|
||||
try_visit!(visit_pat_fields(vis, fields));
|
||||
}
|
||||
PatKind::Box(subpattern) | PatKind::Deref(subpattern) | PatKind::Paren(subpattern) => {
|
||||
try_visit!(vis.visit_pat(subpattern));
|
||||
|
|
@ -876,14 +855,7 @@ macro_rules! common_visitor_and_walkers {
|
|||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
let Block { stmts, id, rules: _, span, tokens: _ } = block;
|
||||
try_visit!(visit_id(vis, id));
|
||||
$(
|
||||
${ignore($lt)}
|
||||
walk_list!(vis, visit_stmt, stmts);
|
||||
)?
|
||||
$(
|
||||
${ignore($mut)}
|
||||
stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt));
|
||||
)?
|
||||
try_visit!(visit_stmts(vis, stmts));
|
||||
visit_span(vis, span)
|
||||
}
|
||||
|
||||
|
|
@ -911,28 +883,13 @@ macro_rules! common_visitor_and_walkers {
|
|||
let BareFnTy { safety, ext: _, generic_params, decl, decl_span } =
|
||||
&$($mut)? **function_declaration;
|
||||
visit_safety(vis, safety);
|
||||
$(
|
||||
${ignore($lt)}
|
||||
walk_list!(vis, visit_generic_param, generic_params);
|
||||
)?
|
||||
$(
|
||||
${ignore($mut)}
|
||||
generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
|
||||
)?
|
||||
|
||||
try_visit!(visit_generic_params(vis, generic_params));
|
||||
try_visit!(vis.visit_fn_decl(decl));
|
||||
try_visit!(visit_span(vis, decl_span));
|
||||
}
|
||||
TyKind::UnsafeBinder(binder) => {
|
||||
$(
|
||||
${ignore($lt)}
|
||||
walk_list!(vis, visit_generic_param, &binder.generic_params);
|
||||
)?
|
||||
$(
|
||||
${ignore($mut)}
|
||||
binder.generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
|
||||
)?
|
||||
try_visit!(vis.visit_ty(&$($mut)?binder.inner_ty));
|
||||
try_visit!(visit_generic_params(vis, &$($mut)? binder.generic_params));
|
||||
try_visit!(vis.visit_ty(&$($mut)? binder.inner_ty));
|
||||
}
|
||||
TyKind::Path(maybe_qself, path) => {
|
||||
try_visit!(vis.visit_qself(maybe_qself));
|
||||
|
|
@ -959,130 +916,204 @@ macro_rules! common_visitor_and_walkers {
|
|||
}
|
||||
visit_span(vis, span)
|
||||
}
|
||||
|
||||
pub fn walk_crate<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
vis: &mut V,
|
||||
krate: &$($lt)? $($mut)? Crate,
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
let Crate { attrs, items, spans, id, is_placeholder: _ } = krate;
|
||||
try_visit!(visit_id(vis, id));
|
||||
walk_list!(vis, visit_attribute, attrs);
|
||||
try_visit!(visit_items(vis, items));
|
||||
let ModSpans { inner_span, inject_use_span } = spans;
|
||||
try_visit!(visit_span(vis, inner_span));
|
||||
visit_span(vis, inject_use_span)
|
||||
}
|
||||
|
||||
pub fn walk_local<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
vis: &mut V,
|
||||
local: &$($lt)? $($mut)? Local,
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
let Local { id, super_, pat, ty, kind, span, colon_sp, attrs, tokens: _ } = local;
|
||||
if let Some(sp) = super_ {
|
||||
try_visit!(visit_span(vis, sp));
|
||||
}
|
||||
try_visit!(visit_id(vis, id));
|
||||
walk_list!(vis, visit_attribute, attrs);
|
||||
try_visit!(vis.visit_pat(pat));
|
||||
visit_opt!(vis, visit_ty, ty);
|
||||
match kind {
|
||||
LocalKind::Decl => {}
|
||||
LocalKind::Init(init) => {
|
||||
try_visit!(vis.visit_expr(init))
|
||||
}
|
||||
LocalKind::InitElse(init, els) => {
|
||||
try_visit!(vis.visit_expr(init));
|
||||
try_visit!(vis.visit_block(els));
|
||||
}
|
||||
}
|
||||
if let Some(sp) = colon_sp {
|
||||
try_visit!(visit_span(vis, sp));
|
||||
}
|
||||
visit_span(vis, span)
|
||||
}
|
||||
|
||||
pub fn walk_poly_trait_ref<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
vis: &mut V,
|
||||
p: &$($lt)? $($mut)? PolyTraitRef,
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
let PolyTraitRef { bound_generic_params, modifiers, trait_ref, span } = p;
|
||||
try_visit!(visit_modifiers(vis, modifiers));
|
||||
try_visit!(visit_generic_params(vis, bound_generic_params));
|
||||
try_visit!(vis.visit_trait_ref(trait_ref));
|
||||
visit_span(vis, span)
|
||||
}
|
||||
|
||||
pub fn walk_trait_ref<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
vis: &mut V,
|
||||
TraitRef { path, ref_id }: &$($lt)? $($mut)? TraitRef,
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
try_visit!(vis.visit_path(path));
|
||||
visit_id(vis, ref_id)
|
||||
}
|
||||
|
||||
pub fn walk_variant<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
vis: &mut V,
|
||||
variant: &$($lt)? $($mut)? Variant,
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
let Variant { attrs, id, span, vis: visibility, ident, data, disr_expr, is_placeholder: _ } = variant;
|
||||
try_visit!(visit_id(vis, id));
|
||||
walk_list!(vis, visit_attribute, attrs);
|
||||
try_visit!(vis.visit_vis(visibility));
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
try_visit!(vis.visit_variant_data(data));
|
||||
$(${ignore($lt)} visit_opt!(vis, visit_variant_discr, disr_expr); )?
|
||||
$(${ignore($mut)} visit_opt!(vis, visit_anon_const, disr_expr); )?
|
||||
visit_span(vis, span)
|
||||
}
|
||||
|
||||
pub fn walk_expr_field<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
vis: &mut V,
|
||||
f: &$($lt)? $($mut)? ExprField,
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
let ExprField { attrs, id, span, ident, expr, is_shorthand: _, is_placeholder: _ } = f;
|
||||
try_visit!(visit_id(vis, id));
|
||||
walk_list!(vis, visit_attribute, attrs);
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
try_visit!(vis.visit_expr(expr));
|
||||
visit_span(vis, span)
|
||||
}
|
||||
|
||||
pub fn walk_pat_field<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
vis: &mut V,
|
||||
fp: &$($lt)? $($mut)? PatField,
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
let PatField { ident, pat, is_shorthand: _, attrs, id, span, is_placeholder: _ } = fp;
|
||||
try_visit!(visit_id(vis, id));
|
||||
walk_list!(vis, visit_attribute, attrs);
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
try_visit!(vis.visit_pat(pat));
|
||||
visit_span(vis, span)
|
||||
}
|
||||
|
||||
pub fn walk_ty_pat<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
vis: &mut V,
|
||||
tp: &$($lt)? $($mut)? TyPat,
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
let TyPat { id, kind, span, tokens: _ } = tp;
|
||||
try_visit!(visit_id(vis, id));
|
||||
match kind {
|
||||
TyPatKind::Range(start, end, _include_end) => {
|
||||
visit_opt!(vis, visit_anon_const, start);
|
||||
visit_opt!(vis, visit_anon_const, end);
|
||||
}
|
||||
TyPatKind::Or(variants) => walk_list!(vis, visit_ty_pat, variants),
|
||||
TyPatKind::Err(_) => {}
|
||||
}
|
||||
visit_span(vis, span)
|
||||
}
|
||||
|
||||
fn walk_qself<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
vis: &mut V,
|
||||
qself: &$($lt)? $($mut)? Option<P<QSelf>>,
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
if let Some(qself) = qself {
|
||||
let QSelf { ty, path_span, position: _ } = &$($mut)? **qself;
|
||||
try_visit!(vis.visit_ty(ty));
|
||||
try_visit!(visit_span(vis, path_span));
|
||||
}
|
||||
$(<V as Visitor<$lt>>::Result::output())?
|
||||
}
|
||||
|
||||
pub fn walk_path<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
vis: &mut V,
|
||||
path: &$($lt)? $($mut)? Path,
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
let Path { span, segments, tokens: _ } = path;
|
||||
walk_list!(vis, visit_path_segment, segments);
|
||||
visit_span(vis, span)
|
||||
}
|
||||
|
||||
pub fn walk_use_tree<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
vis: &mut V,
|
||||
use_tree: &$($lt)? $($mut)? UseTree,
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
let UseTree { prefix, kind, span } = use_tree;
|
||||
try_visit!(vis.visit_path(prefix));
|
||||
match kind {
|
||||
UseTreeKind::Simple(rename) => {
|
||||
// The extra IDs are handled during AST lowering.
|
||||
visit_opt!(vis, visit_ident, rename);
|
||||
}
|
||||
UseTreeKind::Glob => {}
|
||||
UseTreeKind::Nested { items, span } => {
|
||||
for (nested_tree, nested_id) in items {
|
||||
try_visit!(visit_nested_use_tree(vis, nested_tree, nested_id));
|
||||
}
|
||||
try_visit!(visit_span(vis, span));
|
||||
}
|
||||
}
|
||||
visit_span(vis, span)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
common_visitor_and_walkers!(Visitor<'a>);
|
||||
|
||||
pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) -> V::Result {
|
||||
let Crate { attrs, items, spans: _, id: _, is_placeholder: _ } = krate;
|
||||
walk_list!(visitor, visit_attribute, attrs);
|
||||
walk_list!(visitor, visit_item, items);
|
||||
V::Result::output()
|
||||
}
|
||||
|
||||
pub fn walk_local<'a, V: Visitor<'a>>(visitor: &mut V, local: &'a Local) -> V::Result {
|
||||
let Local { id: _, super_: _, pat, ty, kind, span: _, colon_sp: _, attrs, tokens: _ } = local;
|
||||
walk_list!(visitor, visit_attribute, attrs);
|
||||
try_visit!(visitor.visit_pat(pat));
|
||||
visit_opt!(visitor, visit_ty, ty);
|
||||
if let Some((init, els)) = kind.init_else_opt() {
|
||||
try_visit!(visitor.visit_expr(init));
|
||||
visit_opt!(visitor, visit_block, els);
|
||||
}
|
||||
V::Result::output()
|
||||
}
|
||||
|
||||
pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef) -> V::Result
|
||||
where
|
||||
V: Visitor<'a>,
|
||||
{
|
||||
let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span: _ } = trait_ref;
|
||||
walk_list!(visitor, visit_generic_param, bound_generic_params);
|
||||
visitor.visit_trait_ref(trait_ref)
|
||||
}
|
||||
|
||||
pub fn walk_trait_ref<'a, V: Visitor<'a>>(visitor: &mut V, trait_ref: &'a TraitRef) -> V::Result {
|
||||
let TraitRef { path, ref_id } = trait_ref;
|
||||
try_visit!(visitor.visit_path(path));
|
||||
visitor.visit_id(*ref_id)
|
||||
}
|
||||
|
||||
pub fn walk_enum_def<'a, V: Visitor<'a>>(
|
||||
visitor: &mut V,
|
||||
EnumDef { variants }: &'a EnumDef,
|
||||
) -> V::Result {
|
||||
walk_list!(visitor, visit_variant, variants);
|
||||
V::Result::output()
|
||||
}
|
||||
|
||||
pub fn walk_variant<'a, V: Visitor<'a>>(visitor: &mut V, variant: &'a Variant) -> V::Result
|
||||
where
|
||||
V: Visitor<'a>,
|
||||
{
|
||||
let Variant { attrs, id: _, span: _, vis, ident, data, disr_expr, is_placeholder: _ } = variant;
|
||||
walk_list!(visitor, visit_attribute, attrs);
|
||||
try_visit!(visitor.visit_vis(vis));
|
||||
try_visit!(visitor.visit_ident(ident));
|
||||
try_visit!(visitor.visit_variant_data(data));
|
||||
visit_opt!(visitor, visit_variant_discr, disr_expr);
|
||||
V::Result::output()
|
||||
}
|
||||
|
||||
pub fn walk_expr_field<'a, V: Visitor<'a>>(visitor: &mut V, f: &'a ExprField) -> V::Result {
|
||||
let ExprField { attrs, id: _, span: _, ident, expr, is_shorthand: _, is_placeholder: _ } = f;
|
||||
walk_list!(visitor, visit_attribute, attrs);
|
||||
try_visit!(visitor.visit_ident(ident));
|
||||
try_visit!(visitor.visit_expr(expr));
|
||||
V::Result::output()
|
||||
}
|
||||
|
||||
pub fn walk_pat_field<'a, V: Visitor<'a>>(visitor: &mut V, fp: &'a PatField) -> V::Result {
|
||||
let PatField { ident, pat, is_shorthand: _, attrs, id: _, span: _, is_placeholder: _ } = fp;
|
||||
walk_list!(visitor, visit_attribute, attrs);
|
||||
try_visit!(visitor.visit_ident(ident));
|
||||
try_visit!(visitor.visit_pat(pat));
|
||||
V::Result::output()
|
||||
}
|
||||
|
||||
pub fn walk_ty_pat<'a, V: Visitor<'a>>(visitor: &mut V, tp: &'a TyPat) -> V::Result {
|
||||
let TyPat { id: _, kind, span: _, tokens: _ } = tp;
|
||||
match kind {
|
||||
TyPatKind::Range(start, end, _include_end) => {
|
||||
visit_opt!(visitor, visit_anon_const, start);
|
||||
visit_opt!(visitor, visit_anon_const, end);
|
||||
}
|
||||
TyPatKind::Or(variants) => walk_list!(visitor, visit_ty_pat, variants),
|
||||
TyPatKind::Err(_) => {}
|
||||
}
|
||||
V::Result::output()
|
||||
}
|
||||
|
||||
fn walk_qself<'a, V: Visitor<'a>>(visitor: &mut V, qself: &'a Option<P<QSelf>>) -> V::Result {
|
||||
if let Some(qself) = qself {
|
||||
let QSelf { ty, path_span: _, position: _ } = &**qself;
|
||||
try_visit!(visitor.visit_ty(ty));
|
||||
}
|
||||
V::Result::output()
|
||||
}
|
||||
|
||||
pub fn walk_path<'a, V: Visitor<'a>>(visitor: &mut V, path: &'a Path) -> V::Result {
|
||||
let Path { span: _, segments, tokens: _ } = path;
|
||||
walk_list!(visitor, visit_path_segment, segments);
|
||||
V::Result::output()
|
||||
}
|
||||
|
||||
pub fn walk_use_tree<'a, V: Visitor<'a>>(
|
||||
visitor: &mut V,
|
||||
use_tree: &'a UseTree,
|
||||
id: NodeId,
|
||||
) -> V::Result {
|
||||
let UseTree { prefix, kind, span: _ } = use_tree;
|
||||
try_visit!(visitor.visit_id(id));
|
||||
try_visit!(visitor.visit_path(prefix));
|
||||
match kind {
|
||||
UseTreeKind::Simple(rename) => {
|
||||
// The extra IDs are handled during AST lowering.
|
||||
visit_opt!(visitor, visit_ident, rename);
|
||||
}
|
||||
UseTreeKind::Glob => {}
|
||||
UseTreeKind::Nested { items, span: _ } => {
|
||||
for &(ref nested_tree, nested_id) in items {
|
||||
try_visit!(visitor.visit_use_tree(nested_tree, nested_id, true));
|
||||
macro_rules! generate_list_visit_fns {
|
||||
($($name:ident, $Ty:ty, $visit_fn:ident$(, $param:ident: $ParamTy:ty)*;)+) => {
|
||||
$(
|
||||
fn $name<'a, V: Visitor<'a>>(
|
||||
vis: &mut V,
|
||||
values: &'a ThinVec<$Ty>,
|
||||
$(
|
||||
$param: $ParamTy,
|
||||
)*
|
||||
) -> V::Result {
|
||||
walk_list!(vis, $visit_fn, values$(,$param)*);
|
||||
V::Result::output()
|
||||
}
|
||||
}
|
||||
)+
|
||||
}
|
||||
V::Result::output()
|
||||
}
|
||||
|
||||
generate_list_visit_fns! {
|
||||
visit_items, P<Item>, visit_item;
|
||||
visit_foreign_items, P<ForeignItem>, visit_foreign_item;
|
||||
visit_generic_params, GenericParam, visit_generic_param;
|
||||
visit_stmts, Stmt, visit_stmt;
|
||||
visit_pat_fields, PatField, visit_pat_field;
|
||||
visit_variants, Variant, visit_variant;
|
||||
visit_assoc_items, P<AssocItem>, visit_assoc_item, ctxt: AssocCtxt;
|
||||
}
|
||||
|
||||
#[expect(rustc::pass_by_value)] // needed for symmetry with mut_visit
|
||||
fn visit_nested_use_tree<'a, V: Visitor<'a>>(
|
||||
vis: &mut V,
|
||||
nested_tree: &'a UseTree,
|
||||
&nested_id: &NodeId,
|
||||
) -> V::Result {
|
||||
vis.visit_nested_use_tree(nested_tree, nested_id)
|
||||
}
|
||||
|
||||
pub fn walk_generic_args<'a, V>(visitor: &mut V, generic_args: &'a GenericArgs) -> V::Result
|
||||
|
|
|
|||
|
|
@ -732,7 +732,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
span: Span,
|
||||
args: Option<&'hir hir::GenericArgs<'hir>>,
|
||||
) -> &'hir hir::Path<'hir> {
|
||||
let def_id = self.tcx.require_lang_item(lang_item, Some(span));
|
||||
let def_id = self.tcx.require_lang_item(lang_item, span);
|
||||
let def_kind = self.tcx.def_kind(def_id);
|
||||
let res = Res::Def(def_kind, def_id);
|
||||
self.arena.alloc(hir::Path {
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ pub(crate) trait AttributeParser: Default + 'static {
|
|||
pub(crate) trait SingleAttributeParser: 'static {
|
||||
const PATH: &'static [Symbol];
|
||||
|
||||
/// Caled when a duplicate attribute is found.
|
||||
/// Called when a duplicate attribute is found.
|
||||
///
|
||||
/// `first_span` is the span of the first occurrence of this attribute.
|
||||
// FIXME(jdonszelmann): default error
|
||||
|
|
|
|||
|
|
@ -1,31 +1,38 @@
|
|||
//! Centralized logic for parsing and attributes.
|
||||
//!
|
||||
//! Part of a series of crates:
|
||||
//! - rustc_attr_data_structures: contains types that the parsers parse into
|
||||
//! - rustc_attr_parsing: this crate
|
||||
//! - (in the future): rustc_attr_validation
|
||||
//! ## Architecture
|
||||
//! This crate is part of a series of crates that handle attribute processing.
|
||||
//! - [rustc_attr_data_structures](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_data_structures/index.html): Defines the data structures that store parsed attributes
|
||||
//! - [rustc_attr_parsing](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html): This crate, handles the parsing of attributes
|
||||
//! - (planned) rustc_attr_validation: Will handle attribute validation
|
||||
//!
|
||||
//! History: Check out [#131229](https://github.com/rust-lang/rust/issues/131229).
|
||||
//! There used to be only one definition of attributes in the compiler: `ast::Attribute`.
|
||||
//! These were then parsed or validated or both in places distributed all over the compiler.
|
||||
//! This was a mess...
|
||||
//! The separation between data structures and parsing follows the principle of separation of concerns.
|
||||
//! Data structures (`rustc_attr_data_structures`) define what attributes look like after parsing.
|
||||
//! This crate (`rustc_attr_parsing`) handles how to convert raw tokens into those structures.
|
||||
//! This split allows other parts of the compiler to use the data structures without needing
|
||||
//! the parsing logic, making the codebase more modular and maintainable.
|
||||
//!
|
||||
//! Attributes are markers on items.
|
||||
//! Many of them are actually attribute-like proc-macros, and are expanded to some other rust syntax.
|
||||
//! This could either be a user provided proc macro, or something compiler provided.
|
||||
//! `derive` is an example of one that the compiler provides.
|
||||
//! These are built-in, but they have a valid expansion to Rust tokens and are thus called "active".
|
||||
//! I personally like calling these *active* compiler-provided attributes, built-in *macros*,
|
||||
//! because they still expand, and this helps to differentiate them from built-in *attributes*.
|
||||
//! However, I'll be the first to admit that the naming here can be confusing.
|
||||
//! ## Background
|
||||
//! Previously, the compiler had a single attribute definition (`ast::Attribute`) with parsing and
|
||||
//! validation scattered throughout the codebase. This was reorganized for better maintainability
|
||||
//! (see [#131229](https://github.com/rust-lang/rust/issues/131229)).
|
||||
//!
|
||||
//! The alternative to active attributes, are inert attributes.
|
||||
//! These can occur in user code (proc-macro helper attributes).
|
||||
//! But what's important is, many built-in attributes are inert like this.
|
||||
//! There is nothing they expand to during the macro expansion process,
|
||||
//! sometimes because they literally cannot expand to something that is valid Rust.
|
||||
//! They are really just markers to guide the compilation process.
|
||||
//! An example is `#[inline(...)]` which changes how code for functions is generated.
|
||||
//! ## Types of Attributes
|
||||
//! In Rust, attributes are markers that can be attached to items. They come in two main categories.
|
||||
//!
|
||||
//! ### 1. Active Attributes
|
||||
//! These are attribute-like proc-macros that expand into other Rust code.
|
||||
//! They can be either user-defined or compiler-provided. Examples of compiler-provided active attributes:
|
||||
//! - `#[derive(...)]`: Expands into trait implementations
|
||||
//! - `#[cfg()]`: Expands based on configuration
|
||||
//! - `#[cfg_attr()]`: Conditional attribute application
|
||||
//!
|
||||
//! ### 2. Inert Attributes
|
||||
//! These are pure markers that don't expand into other code. They guide the compilation process.
|
||||
//! They can be user-defined (in proc-macro helpers) or built-in. Examples of built-in inert attributes:
|
||||
//! - `#[stable()]`: Marks stable API items
|
||||
//! - `#[inline()]`: Suggests function inlining
|
||||
//! - `#[repr()]`: Controls type representation
|
||||
//!
|
||||
//! ```text
|
||||
//! Active Inert
|
||||
|
|
@ -33,27 +40,21 @@
|
|||
//! │ (mostly in) │ these are parsed │
|
||||
//! │ rustc_builtin_macros │ here! │
|
||||
//! │ │ │
|
||||
//! │ │ │
|
||||
//! │ #[derive(...)] │ #[stable()] │
|
||||
//! Built-in │ #[cfg()] │ #[inline()] │
|
||||
//! │ #[cfg_attr()] │ #[repr()] │
|
||||
//! │ │ │
|
||||
//! │ │ │
|
||||
//! │ │ │
|
||||
//! ├──────────────────────┼──────────────────────┤
|
||||
//! │ │ │
|
||||
//! │ │ │
|
||||
//! │ │ `b` in │
|
||||
//! │ │ #[proc_macro_derive( │
|
||||
//! User created │ #[proc_macro_attr()] │ a, │
|
||||
//! │ │ attributes(b) │
|
||||
//! │ │ ] │
|
||||
//! │ │ │
|
||||
//! │ │ │
|
||||
//! │ │ │
|
||||
//! └──────────────────────┴──────────────────────┘
|
||||
//! ```
|
||||
//!
|
||||
//! ## How This Crate Works
|
||||
//! In this crate, syntactical attributes (sequences of tokens that look like
|
||||
//! `#[something(something else)]`) are parsed into more semantic attributes, markers on items.
|
||||
//! Multiple syntactic attributes might influence a single semantic attribute. For example,
|
||||
|
|
@ -63,18 +64,17 @@
|
|||
//! and `#[unstable()]` syntactic attributes, and at the end produce a single
|
||||
//! [`AttributeKind::Stability`](rustc_attr_data_structures::AttributeKind::Stability).
|
||||
//!
|
||||
//! As a rule of thumb, when a syntactical attribute can be applied more than once, they should be
|
||||
//! combined into a single semantic attribute. For example:
|
||||
//! When multiple instances of the same attribute are allowed, they're combined into a single
|
||||
//! semantic attribute. For example:
|
||||
//!
|
||||
//! ```
|
||||
//! ```rust
|
||||
//! #[repr(C)]
|
||||
//! #[repr(packed)]
|
||||
//! struct Meow {}
|
||||
//! ```
|
||||
//!
|
||||
//! should result in a single `AttributeKind::Repr` containing a list of repr annotations, in this
|
||||
//! case `C` and `packed`. This is equivalent to writing `#[repr(C, packed)]` in a single
|
||||
//! syntactical annotation.
|
||||
//! This is equivalent to `#[repr(C, packed)]` and results in a single `AttributeKind::Repr`
|
||||
//! containing both `C` and `packed` annotations.
|
||||
|
||||
// tidy-alphabetical-start
|
||||
#![allow(internal_features)]
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
|||
// something that already has `Fn`-like bounds (or is a closure), so we can't
|
||||
// restrict anyways.
|
||||
} else {
|
||||
let copy_did = self.infcx.tcx.require_lang_item(LangItem::Copy, Some(span));
|
||||
let copy_did = self.infcx.tcx.require_lang_item(LangItem::Copy, span);
|
||||
self.suggest_adding_bounds(&mut err, ty, copy_did, span);
|
||||
}
|
||||
|
||||
|
|
@ -1915,7 +1915,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
|||
|
||||
let local_ty = self.body.local_decls[place.local].ty;
|
||||
let typeck_results = tcx.typeck(self.mir_def_id());
|
||||
let clone = tcx.require_lang_item(LangItem::Clone, Some(body.span));
|
||||
let clone = tcx.require_lang_item(LangItem::Clone, body.span);
|
||||
for expr in expr_finder.clones {
|
||||
if let hir::ExprKind::MethodCall(_, rcvr, _, span) = expr.kind
|
||||
&& let Some(rcvr_ty) = typeck_results.node_type_opt(rcvr.hir_id)
|
||||
|
|
|
|||
|
|
@ -688,7 +688,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
if !self.unsized_feature_enabled() {
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
|
||||
tcx.require_lang_item(LangItem::Sized, self.last_span),
|
||||
[place_ty],
|
||||
);
|
||||
self.prove_trait_ref(
|
||||
|
|
@ -1010,7 +1010,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
let ty = place.ty(self.body, tcx).ty;
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::Copy, Some(span)),
|
||||
tcx.require_lang_item(LangItem::Copy, span),
|
||||
[ty],
|
||||
);
|
||||
|
||||
|
|
@ -1025,11 +1025,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
}
|
||||
|
||||
&Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => {
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::Sized, Some(span)),
|
||||
[ty],
|
||||
);
|
||||
let trait_ref =
|
||||
ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, span), [ty]);
|
||||
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
|
|
@ -1041,11 +1038,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
&Rvalue::NullaryOp(NullOp::UbChecks, _) => {}
|
||||
|
||||
Rvalue::ShallowInitBox(_operand, ty) => {
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::Sized, Some(span)),
|
||||
[*ty],
|
||||
);
|
||||
let trait_ref =
|
||||
ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, span), [*ty]);
|
||||
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
|
|
@ -1222,7 +1216,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
let &ty = ty;
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)),
|
||||
tcx.require_lang_item(LangItem::CoerceUnsized, span),
|
||||
[op.ty(self.body, tcx), ty],
|
||||
);
|
||||
|
||||
|
|
@ -1811,7 +1805,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::Copy, Some(self.last_span)),
|
||||
tcx.require_lang_item(LangItem::Copy, self.last_span),
|
||||
[place_ty.ty],
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -544,10 +544,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
// (as it's created inside the body itself, not passed in from outside).
|
||||
if let DefiningTy::FnDef(def_id, _) = defining_ty {
|
||||
if self.infcx.tcx.fn_sig(def_id).skip_binder().c_variadic() {
|
||||
let va_list_did = self.infcx.tcx.require_lang_item(
|
||||
LangItem::VaList,
|
||||
Some(self.infcx.tcx.def_span(self.mir_def)),
|
||||
);
|
||||
let va_list_did = self
|
||||
.infcx
|
||||
.tcx
|
||||
.require_lang_item(LangItem::VaList, self.infcx.tcx.def_span(self.mir_def));
|
||||
|
||||
let reg_vid = self
|
||||
.infcx
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ impl MultiItemModifier for BuiltinDerive {
|
|||
let mut items = Vec::new();
|
||||
match item {
|
||||
Annotatable::Stmt(stmt) => {
|
||||
if let ast::StmtKind::Item(item) = stmt.into_inner().kind {
|
||||
if let ast::StmtKind::Item(item) = stmt.kind {
|
||||
(self.0)(
|
||||
ecx,
|
||||
span,
|
||||
|
|
|
|||
|
|
@ -30,14 +30,12 @@ fn parse_pat_ty<'a>(cx: &mut ExtCtxt<'a>, stream: TokenStream) -> PResult<'a, (P
|
|||
|
||||
let pat = pat_to_ty_pat(
|
||||
cx,
|
||||
parser
|
||||
.parse_pat_no_top_guard(
|
||||
None,
|
||||
RecoverComma::No,
|
||||
RecoverColon::No,
|
||||
CommaRecoveryMode::EitherTupleOrPipe,
|
||||
)?
|
||||
.into_inner(),
|
||||
*parser.parse_pat_no_top_guard(
|
||||
None,
|
||||
RecoverComma::No,
|
||||
RecoverColon::No,
|
||||
CommaRecoveryMode::EitherTupleOrPipe,
|
||||
)?,
|
||||
);
|
||||
|
||||
if parser.token != token::Eof {
|
||||
|
|
@ -58,9 +56,9 @@ fn pat_to_ty_pat(cx: &mut ExtCtxt<'_>, pat: ast::Pat) -> P<TyPat> {
|
|||
end.map(|value| P(AnonConst { id: DUMMY_NODE_ID, value })),
|
||||
include_end,
|
||||
),
|
||||
ast::PatKind::Or(variants) => TyPatKind::Or(
|
||||
variants.into_iter().map(|pat| pat_to_ty_pat(cx, pat.into_inner())).collect(),
|
||||
),
|
||||
ast::PatKind::Or(variants) => {
|
||||
TyPatKind::Or(variants.into_iter().map(|pat| pat_to_ty_pat(cx, *pat)).collect())
|
||||
}
|
||||
ast::PatKind::Err(guar) => TyPatKind::Err(guar),
|
||||
_ => TyPatKind::Err(cx.dcx().span_err(pat.span, "pattern not supported in pattern types")),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -354,30 +354,28 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
|
|||
})
|
||||
.collect();
|
||||
|
||||
let decls_static = cx
|
||||
.item_static(
|
||||
let mut decls_static = cx.item_static(
|
||||
span,
|
||||
Ident::new(sym::_DECLS, span),
|
||||
cx.ty_ref(
|
||||
span,
|
||||
Ident::new(sym::_DECLS, span),
|
||||
cx.ty_ref(
|
||||
cx.ty(
|
||||
span,
|
||||
cx.ty(
|
||||
span,
|
||||
ast::TyKind::Slice(
|
||||
cx.ty_path(cx.path(span, vec![proc_macro, bridge, client, proc_macro_ty])),
|
||||
),
|
||||
ast::TyKind::Slice(
|
||||
cx.ty_path(cx.path(span, vec![proc_macro, bridge, client, proc_macro_ty])),
|
||||
),
|
||||
None,
|
||||
ast::Mutability::Not,
|
||||
),
|
||||
None,
|
||||
ast::Mutability::Not,
|
||||
cx.expr_array_ref(span, decls),
|
||||
)
|
||||
.map(|mut i| {
|
||||
i.attrs.push(cx.attr_word(sym::rustc_proc_macro_decls, span));
|
||||
i.attrs.push(cx.attr_word(sym::used, span));
|
||||
i.attrs.push(cx.attr_nested_word(sym::allow, sym::deprecated, span));
|
||||
i
|
||||
});
|
||||
),
|
||||
ast::Mutability::Not,
|
||||
cx.expr_array_ref(span, decls),
|
||||
);
|
||||
decls_static.attrs.extend([
|
||||
cx.attr_word(sym::rustc_proc_macro_decls, span),
|
||||
cx.attr_word(sym::used, span),
|
||||
cx.attr_nested_word(sym::allow, sym::deprecated, span),
|
||||
]);
|
||||
|
||||
let block = cx.expr_block(
|
||||
cx.block(span, thin_vec![cx.stmt_item(span, krate), cx.stmt_item(span, decls_static)]),
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ pub(crate) fn expand_test_case(
|
|||
let (mut item, is_stmt) = match anno_item {
|
||||
Annotatable::Item(item) => (item, false),
|
||||
Annotatable::Stmt(stmt) if let ast::StmtKind::Item(_) = stmt.kind => {
|
||||
if let ast::StmtKind::Item(i) = stmt.into_inner().kind {
|
||||
if let ast::StmtKind::Item(i) = stmt.kind {
|
||||
(i, true)
|
||||
} else {
|
||||
unreachable!()
|
||||
|
|
@ -120,11 +120,7 @@ pub(crate) fn expand_test_or_bench(
|
|||
Annotatable::Item(i) => (i, false),
|
||||
Annotatable::Stmt(stmt) if matches!(stmt.kind, ast::StmtKind::Item(_)) => {
|
||||
// FIXME: Use an 'if let' guard once they are implemented
|
||||
if let ast::StmtKind::Item(i) = stmt.into_inner().kind {
|
||||
(i, true)
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
if let ast::StmtKind::Item(i) = stmt.kind { (i, true) } else { unreachable!() }
|
||||
}
|
||||
other => {
|
||||
not_testable_error(cx, attr_sp, None);
|
||||
|
|
@ -381,10 +377,7 @@ pub(crate) fn expand_test_or_bench(
|
|||
.into(),
|
||||
),
|
||||
);
|
||||
test_const = test_const.map(|mut tc| {
|
||||
tc.vis.kind = ast::VisibilityKind::Public;
|
||||
tc
|
||||
});
|
||||
test_const.vis.kind = ast::VisibilityKind::Public;
|
||||
|
||||
// extern crate test
|
||||
let test_extern =
|
||||
|
|
|
|||
|
|
@ -380,7 +380,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
|
|||
rustc_hir::LangItem::PanicBoundsCheck,
|
||||
&[index, len, location],
|
||||
*unwind,
|
||||
Some(source_info.span),
|
||||
source_info.span,
|
||||
);
|
||||
}
|
||||
AssertKind::MisalignedPointerDereference { ref required, ref found } => {
|
||||
|
|
@ -393,7 +393,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
|
|||
rustc_hir::LangItem::PanicMisalignedPointerDereference,
|
||||
&[required, found, location],
|
||||
*unwind,
|
||||
Some(source_info.span),
|
||||
source_info.span,
|
||||
);
|
||||
}
|
||||
AssertKind::NullPointerDereference => {
|
||||
|
|
@ -404,7 +404,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
|
|||
rustc_hir::LangItem::PanicNullPointerDereference,
|
||||
&[location],
|
||||
*unwind,
|
||||
Some(source_info.span),
|
||||
source_info.span,
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
|
|
@ -415,7 +415,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
|
|||
msg.panic_function(),
|
||||
&[location],
|
||||
*unwind,
|
||||
Some(source_info.span),
|
||||
source_info.span,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -531,7 +531,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
|
|||
);
|
||||
}
|
||||
TerminatorKind::UnwindTerminate(reason) => {
|
||||
codegen_unwind_terminate(fx, Some(source_info.span), *reason);
|
||||
codegen_unwind_terminate(fx, source_info.span, *reason);
|
||||
}
|
||||
TerminatorKind::UnwindResume => {
|
||||
// FIXME implement unwinding
|
||||
|
|
@ -1074,7 +1074,7 @@ pub(crate) fn codegen_operand<'tcx>(
|
|||
pub(crate) fn codegen_panic_nounwind<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
msg_str: &str,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
) {
|
||||
let msg_ptr = fx.anonymous_str(msg_str);
|
||||
let msg_len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap());
|
||||
|
|
@ -1091,7 +1091,7 @@ pub(crate) fn codegen_panic_nounwind<'tcx>(
|
|||
|
||||
pub(crate) fn codegen_unwind_terminate<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
reason: UnwindTerminateReason,
|
||||
) {
|
||||
codegen_panic_inner(fx, reason.lang_item(), &[], UnwindAction::Unreachable, span);
|
||||
|
|
@ -1102,7 +1102,7 @@ fn codegen_panic_inner<'tcx>(
|
|||
lang_item: rustc_hir::LangItem,
|
||||
args: &[Value],
|
||||
_unwind: UnwindAction,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
) {
|
||||
fx.bcx.set_cold_block(fx.bcx.current_block().unwrap());
|
||||
|
||||
|
|
|
|||
|
|
@ -850,7 +850,7 @@ fn asm_clif_type<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option<ty
|
|||
// Adapted from https://github.com/rust-lang/rust/blob/f3c66088610c1b80110297c2d9a8b5f9265b013f/compiler/rustc_hir_analysis/src/check/intrinsicck.rs#L136-L151
|
||||
ty::Adt(adt, args) if fx.tcx.is_lang_item(adt.did(), LangItem::MaybeUninit) => {
|
||||
let fields = &adt.non_enum_variant().fields;
|
||||
let ty = fields[FieldIdx::from_u32(1)].ty(fx.tcx, args);
|
||||
let ty = fields[FieldIdx::ONE].ty(fx.tcx, args);
|
||||
let ty::Adt(ty, args) = ty.kind() else {
|
||||
unreachable!("expected first field of `MaybeUninit` to be an ADT")
|
||||
};
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
|
|||
See https://github.com/rust-lang/rustc_codegen_cranelift/issues/171\n\
|
||||
Please open an issue at https://github.com/rust-lang/rustc_codegen_cranelift/issues"
|
||||
);
|
||||
crate::base::codegen_panic_nounwind(fx, &msg, None);
|
||||
crate::base::codegen_panic_nounwind(fx, &msg, span);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -512,7 +512,7 @@ pub(super) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
|
|||
See https://github.com/rust-lang/rustc_codegen_cranelift/issues/171\n\
|
||||
Please open an issue at https://github.com/rust-lang/rustc_codegen_cranelift/issues"
|
||||
);
|
||||
crate::base::codegen_panic_nounwind(fx, &msg, None);
|
||||
crate::base::codegen_panic_nounwind(fx, &msg, fx.mir.span);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1321,7 +1321,7 @@ pub(super) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
See https://github.com/rust-lang/rustc_codegen_cranelift/issues/171\n\
|
||||
Please open an issue at https://github.com/rust-lang/rustc_codegen_cranelift/issues"
|
||||
);
|
||||
crate::base::codegen_panic_nounwind(fx, &msg, None);
|
||||
crate::base::codegen_panic_nounwind(fx, &msg, span);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -785,7 +785,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
|||
}
|
||||
})
|
||||
});
|
||||
crate::base::codegen_panic_nounwind(fx, &msg_str, Some(source_info.span));
|
||||
crate::base::codegen_panic_nounwind(fx, &msg_str, source_info.span);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
|
@ -884,7 +884,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
|||
crate::base::codegen_panic_nounwind(
|
||||
fx,
|
||||
"128bit atomics not yet supported",
|
||||
None,
|
||||
source_info.span,
|
||||
);
|
||||
return Ok(());
|
||||
} else {
|
||||
|
|
@ -919,7 +919,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
|||
crate::base::codegen_panic_nounwind(
|
||||
fx,
|
||||
"128bit atomics not yet supported",
|
||||
None,
|
||||
source_info.span,
|
||||
);
|
||||
return Ok(());
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ pub(crate) fn maybe_create_entry_wrapper(
|
|||
let call_inst = bcx.ins().call(main_func_ref, &[]);
|
||||
let call_results = bcx.func.dfg.inst_results(call_inst).to_owned();
|
||||
|
||||
let termination_trait = tcx.require_lang_item(LangItem::Termination, None);
|
||||
let termination_trait = tcx.require_lang_item(LangItem::Termination, DUMMY_SP);
|
||||
let report = tcx
|
||||
.associated_items(termination_trait)
|
||||
.find_by_ident_and_kind(
|
||||
|
|
@ -136,7 +136,7 @@ pub(crate) fn maybe_create_entry_wrapper(
|
|||
}
|
||||
} else {
|
||||
// Regular main fn invoked via start lang item.
|
||||
let start_def_id = tcx.require_lang_item(LangItem::Start, None);
|
||||
let start_def_id = tcx.require_lang_item(LangItem::Start, DUMMY_SP);
|
||||
let start_instance = Instance::expect_resolve(
|
||||
tcx,
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ fn codegen_three_way_compare<'tcx>(
|
|||
let gt = fx.bcx.ins().icmp(gt_cc, lhs, rhs);
|
||||
let lt = fx.bcx.ins().icmp(lt_cc, lhs, rhs);
|
||||
let val = fx.bcx.ins().isub(gt, lt);
|
||||
CValue::by_val(val, fx.layout_of(fx.tcx.ty_ordering_enum(Some(fx.mir.span))))
|
||||
CValue::by_val(val, fx.layout_of(fx.tcx.ty_ordering_enum(fx.mir.span)))
|
||||
}
|
||||
|
||||
fn codegen_compare_bin_op<'tcx>(
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ pub(crate) fn size_and_align_of<'tcx>(
|
|||
})
|
||||
});
|
||||
|
||||
codegen_panic_nounwind(fx, &msg_str, None);
|
||||
codegen_panic_nounwind(fx, &msg_str, fx.mir.span);
|
||||
|
||||
fx.bcx.switch_to_block(next_block);
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
|
|||
.layout()
|
||||
.non_1zst_field(fx)
|
||||
.expect("not exactly one non-1-ZST field in a `DispatchFromDyn` type");
|
||||
arg = arg.value_field(fx, FieldIdx::new(idx));
|
||||
arg = arg.value_field(fx, idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -62,8 +62,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
|
|||
let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap());
|
||||
let dyn_star = CPlace::for_ptr(Pointer::new(arg.load_scalar(fx)), inner_layout);
|
||||
let ptr = dyn_star.place_field(fx, FieldIdx::ZERO).to_ptr();
|
||||
let vtable =
|
||||
dyn_star.place_field(fx, FieldIdx::new(1)).to_cvalue(fx).load_scalar(fx);
|
||||
let vtable = dyn_star.place_field(fx, FieldIdx::ONE).to_cvalue(fx).load_scalar(fx);
|
||||
break 'block (ptr, vtable);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -561,7 +561,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
|
||||
let EntryFnType::Main { sigpipe } = entry_type;
|
||||
let (start_fn, start_ty, args, instance) = {
|
||||
let start_def_id = cx.tcx().require_lang_item(LangItem::Start, None);
|
||||
let start_def_id = cx.tcx().require_lang_item(LangItem::Start, DUMMY_SP);
|
||||
let start_instance = ty::Instance::expect_resolve(
|
||||
cx.tcx(),
|
||||
cx.typing_env(),
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ mod temp_stable_hash_impls {
|
|||
|
||||
pub(crate) fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
bx: &Bx,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
li: LangItem,
|
||||
) -> (Bx::FnAbiOfResult, Bx::Value, Instance<'tcx>) {
|
||||
let tcx = bx.tcx();
|
||||
|
|
|
|||
|
|
@ -783,7 +783,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
}
|
||||
};
|
||||
|
||||
let (fn_abi, llfn, instance) = common::build_langcall(bx, Some(span), lang_item);
|
||||
let (fn_abi, llfn, instance) = common::build_langcall(bx, span, lang_item);
|
||||
|
||||
// Codegen the actual panic invoke/call.
|
||||
let merging_succ =
|
||||
|
|
@ -803,7 +803,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
self.set_debug_loc(bx, terminator.source_info);
|
||||
|
||||
// Obtain the panic entry point.
|
||||
let (fn_abi, llfn, instance) = common::build_langcall(bx, Some(span), reason.lang_item());
|
||||
let (fn_abi, llfn, instance) = common::build_langcall(bx, span, reason.lang_item());
|
||||
|
||||
// Codegen the actual panic invoke/call.
|
||||
let merging_succ = helper.do_call(
|
||||
|
|
@ -871,7 +871,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
|
||||
// Obtain the panic entry point.
|
||||
let (fn_abi, llfn, instance) =
|
||||
common::build_langcall(bx, Some(source_info.span), LangItem::PanicNounwind);
|
||||
common::build_langcall(bx, source_info.span, LangItem::PanicNounwind);
|
||||
|
||||
// Codegen the actual panic invoke/call.
|
||||
Some(helper.do_call(
|
||||
|
|
@ -1077,7 +1077,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
let (idx, _) = op.layout.non_1zst_field(bx).expect(
|
||||
"not exactly one non-1-ZST field in a `DispatchFromDyn` type",
|
||||
);
|
||||
op = op.extract_field(self, bx, idx);
|
||||
op = op.extract_field(self, bx, idx.as_usize());
|
||||
}
|
||||
|
||||
// Now that we have `*dyn Trait` or `&dyn Trait`, split it up into its
|
||||
|
|
@ -1109,7 +1109,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
let (idx, _) = op.layout.non_1zst_field(bx).expect(
|
||||
"not exactly one non-1-ZST field in a `DispatchFromDyn` type",
|
||||
);
|
||||
op = op.extract_field(self, bx, idx);
|
||||
op = op.extract_field(self, bx, idx.as_usize());
|
||||
}
|
||||
|
||||
// Make sure that we've actually unwrapped the rcvr down
|
||||
|
|
@ -1830,7 +1830,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
|
||||
self.set_debug_loc(&mut bx, mir::SourceInfo::outermost(self.mir.span));
|
||||
|
||||
let (fn_abi, fn_ptr, instance) = common::build_langcall(&bx, None, reason.lang_item());
|
||||
let (fn_abi, fn_ptr, instance) =
|
||||
common::build_langcall(&bx, self.mir.span, reason.lang_item());
|
||||
if is_call_from_compiler_builtins_to_upstream_monomorphization(bx.tcx(), instance) {
|
||||
bx.abort();
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -45,9 +45,15 @@ pub enum OperandValue<V> {
|
|||
Immediate(V),
|
||||
/// A pair of immediate LLVM values. Used by wide pointers too.
|
||||
///
|
||||
/// An `OperandValue` *must* be this variant for any type for which
|
||||
/// # Invariants
|
||||
/// - For `Pair(a, b)`, `a` is always at offset 0, but may have `FieldIdx(1..)`
|
||||
/// - `b` is not at offset 0, because `V` is not a 1ZST type.
|
||||
/// - `a` and `b` will have a different FieldIdx, but otherwise `b`'s may be lower
|
||||
/// or they may not be adjacent, due to arbitrary numbers of 1ZST fields that
|
||||
/// will not affect the shape of the data which determines if `Pair` will be used.
|
||||
/// - An `OperandValue` *must* be this variant for any type for which
|
||||
/// [`LayoutTypeCodegenMethods::is_backend_scalar_pair`] returns `true`.
|
||||
/// The backend values in this variant must be the *immediate* backend types,
|
||||
/// - The backend values in this variant must be the *immediate* backend types,
|
||||
/// as returned by [`LayoutTypeCodegenMethods::scalar_pair_element_backend_type`]
|
||||
/// with `immediate: true`.
|
||||
Pair(V, V),
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use rustc_hir::LangItem;
|
|||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_span::DUMMY_SP;
|
||||
use tracing::{debug, trace};
|
||||
|
||||
use crate::common::IntPredicate;
|
||||
|
|
@ -62,7 +63,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
|
||||
// Obtain the panic entry point.
|
||||
let (fn_abi, llfn, _instance) =
|
||||
common::build_langcall(bx, None, LangItem::PanicNounwind);
|
||||
common::build_langcall(bx, DUMMY_SP, LangItem::PanicNounwind);
|
||||
|
||||
// Generate the call. Cannot use `do_call` since we don't have a MIR terminator so we
|
||||
// can't create a `TerminationCodegenHelper`. (But we are in good company, this code is
|
||||
|
|
|
|||
|
|
@ -345,11 +345,7 @@ fn build_error_for_const_call<'tcx>(
|
|||
non_or_conditionally,
|
||||
});
|
||||
|
||||
note_trait_if_possible(
|
||||
&mut err,
|
||||
self_ty,
|
||||
tcx.require_lang_item(LangItem::Deref, Some(span)),
|
||||
);
|
||||
note_trait_if_possible(&mut err, self_ty, tcx.require_lang_item(LangItem::Deref, span));
|
||||
err
|
||||
}
|
||||
_ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::FmtArgumentsNew) => {
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ impl Qualif for HasMutInterior {
|
|||
// requires borrowck, which in turn will invoke mir_const_qualifs again, causing a cycle error.
|
||||
// Instead we invoke an obligation context manually, and provide the opaque type inference settings
|
||||
// that allow the trait solver to just error out instead of cycling.
|
||||
let freeze_def_id = cx.tcx.require_lang_item(LangItem::Freeze, Some(cx.body.span));
|
||||
let freeze_def_id = cx.tcx.require_lang_item(LangItem::Freeze, cx.body.span);
|
||||
// FIXME(#132279): Once we've got a typing mode which reveals opaque types using the HIR
|
||||
// typeck results without causing query cycles, we should use this here instead of defining
|
||||
// opaque types.
|
||||
|
|
@ -180,7 +180,7 @@ impl Qualif for NeedsNonConstDrop {
|
|||
// that the components of this type are also `~const Destruct`. This
|
||||
// amounts to verifying that there are no values in this ADT that may have
|
||||
// a non-const drop.
|
||||
let destruct_def_id = cx.tcx.require_lang_item(LangItem::Destruct, Some(cx.body.span));
|
||||
let destruct_def_id = cx.tcx.require_lang_item(LangItem::Destruct, cx.body.span);
|
||||
let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env);
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
ocx.register_obligation(Obligation::new(
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
|
|||
return Err(ConstEvalErrKind::Panic { msg, file, line, col }).into();
|
||||
} else if self.tcx.is_lang_item(def_id, LangItem::PanicFmt) {
|
||||
// For panic_fmt, call const_panic_fmt instead.
|
||||
let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, None);
|
||||
let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, self.tcx.span);
|
||||
let new_instance = ty::Instance::expect_resolve(
|
||||
*self.tcx,
|
||||
self.typing_env(),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Not in interpret to make sure we do not use private implementation details
|
||||
|
||||
use rustc_abi::VariantIdx;
|
||||
use rustc_abi::{FieldIdx, VariantIdx};
|
||||
use rustc_middle::query::Key;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
|
|
@ -60,7 +60,7 @@ pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>(
|
|||
|
||||
let fields_iter = (0..field_count)
|
||||
.map(|i| {
|
||||
let field_op = ecx.project_field(&down, i).discard_err()?;
|
||||
let field_op = ecx.project_field(&down, FieldIdx::from_usize(i)).discard_err()?;
|
||||
let val = op_to_const(&ecx, &field_op, /* for diagnostics */ true);
|
||||
Some((val, field_op.layout.ty))
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use rustc_abi::{BackendRepr, VariantIdx};
|
||||
use rustc_abi::{BackendRepr, FieldIdx, VariantIdx};
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId, ReportedErrorInfo};
|
||||
use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout};
|
||||
|
|
@ -40,7 +40,7 @@ fn branches<'tcx>(
|
|||
}
|
||||
|
||||
for i in 0..field_count {
|
||||
let field = ecx.project_field(&place, i).unwrap();
|
||||
let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap();
|
||||
let valtree = const_to_valtree_inner(ecx, &field, num_nodes)?;
|
||||
branches.push(valtree);
|
||||
}
|
||||
|
|
@ -437,7 +437,7 @@ fn valtree_into_mplace<'tcx>(
|
|||
ty::Str | ty::Slice(_) | ty::Array(..) => {
|
||||
ecx.project_index(place, i as u64).unwrap()
|
||||
}
|
||||
_ => ecx.project_field(&place_adjusted, i).unwrap(),
|
||||
_ => ecx.project_field(&place_adjusted, FieldIdx::from_usize(i)).unwrap(),
|
||||
};
|
||||
|
||||
debug!(?place_inner);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
pub(super) fn fn_arg_field(
|
||||
&self,
|
||||
arg: &FnArg<'tcx, M::Provenance>,
|
||||
field: usize,
|
||||
field: FieldIdx,
|
||||
) -> InterpResult<'tcx, FnArg<'tcx, M::Provenance>> {
|
||||
interp_ok(match arg {
|
||||
FnArg::Copy(op) => FnArg::Copy(self.project_field(op, field)?),
|
||||
|
|
@ -600,10 +600,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
Cow::from(
|
||||
args.iter()
|
||||
.map(|a| interp_ok(a.clone()))
|
||||
.chain(
|
||||
(0..untuple_arg.layout().fields.count())
|
||||
.map(|i| self.fn_arg_field(untuple_arg, i)),
|
||||
)
|
||||
.chain((0..untuple_arg.layout().fields.count()).map(|i| {
|
||||
self.fn_arg_field(untuple_arg, FieldIdx::from_usize(i))
|
||||
}))
|
||||
.collect::<InterpResult<'_, Vec<_>>>()?,
|
||||
)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::assert_matches::assert_matches;
|
||||
|
||||
use rustc_abi::Integer;
|
||||
use rustc_abi::{FieldIdx, Integer};
|
||||
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
|
||||
use rustc_apfloat::{Float, FloatConvert};
|
||||
use rustc_middle::mir::CastKind;
|
||||
|
|
@ -484,6 +484,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
let mut found_cast_field = false;
|
||||
for i in 0..src.layout.fields.count() {
|
||||
let cast_ty_field = cast_ty.field(self, i);
|
||||
let i = FieldIdx::from_usize(i);
|
||||
let src_field = self.project_field(src, i)?;
|
||||
let dst_field = self.project_field(dest, i)?;
|
||||
if src_field.layout.is_1zst() && cast_ty_field.is_1zst() {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
// No need to validate that the discriminant here because the
|
||||
// `TyAndLayout::for_variant()` call earlier already checks the
|
||||
// variant is valid.
|
||||
let tag_dest = self.project_field(dest, tag_field.as_usize())?;
|
||||
let tag_dest = self.project_field(dest, tag_field)?;
|
||||
self.write_scalar(tag, &tag_dest)
|
||||
}
|
||||
None => {
|
||||
|
|
@ -96,7 +96,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
let tag_layout = self.layout_of(tag_scalar_layout.primitive().to_int_ty(*self.tcx))?;
|
||||
|
||||
// Read tag and sanity-check `tag_layout`.
|
||||
let tag_val = self.read_immediate(&self.project_field(op, tag_field.as_usize())?)?;
|
||||
let tag_val = self.read_immediate(&self.project_field(op, tag_field)?)?;
|
||||
assert_eq!(tag_layout.size, tag_val.layout.size);
|
||||
assert_eq!(tag_layout.backend_repr.is_signed(), tag_val.layout.backend_repr.is_signed());
|
||||
trace!("tag value: {}", tag_val);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout};
|
|||
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter};
|
||||
use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, mir, span_bug, ty};
|
||||
use rustc_span::DUMMY_SP;
|
||||
use tracing::trace;
|
||||
|
||||
use super::{
|
||||
|
|
@ -307,7 +308,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
|
|||
#[inline]
|
||||
pub fn from_ordering(c: std::cmp::Ordering, tcx: TyCtxt<'tcx>) -> Self {
|
||||
// Can use any typing env, since `Ordering` is always monomorphic.
|
||||
let ty = tcx.ty_ordering_enum(None);
|
||||
let ty = tcx.ty_ordering_enum(DUMMY_SP);
|
||||
let layout =
|
||||
tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)).unwrap();
|
||||
Self::from_scalar(Scalar::Int(c.into()), layout)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
use std::marker::PhantomData;
|
||||
use std::ops::Range;
|
||||
|
||||
use rustc_abi::{self as abi, Size, VariantIdx};
|
||||
use rustc_abi::{self as abi, FieldIdx, Size, VariantIdx};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||
use rustc_middle::{bug, mir, span_bug, ty};
|
||||
|
|
@ -144,22 +144,22 @@ where
|
|||
/// always possible without allocating, so it can take `&self`. Also return the field's layout.
|
||||
/// This supports both struct and array fields, but not slices!
|
||||
///
|
||||
/// This also works for arrays, but then the `usize` index type is restricting.
|
||||
/// For indexing into arrays, use `mplace_index`.
|
||||
/// This also works for arrays, but then the `FieldIdx` index type is restricting.
|
||||
/// For indexing into arrays, use [`Self::project_index`].
|
||||
pub fn project_field<P: Projectable<'tcx, M::Provenance>>(
|
||||
&self,
|
||||
base: &P,
|
||||
field: usize,
|
||||
field: FieldIdx,
|
||||
) -> InterpResult<'tcx, P> {
|
||||
// Slices nominally have length 0, so they will panic somewhere in `fields.offset`.
|
||||
debug_assert!(
|
||||
!matches!(base.layout().ty.kind(), ty::Slice(..)),
|
||||
"`field` projection called on a slice -- call `index` projection instead"
|
||||
);
|
||||
let offset = base.layout().fields.offset(field);
|
||||
let offset = base.layout().fields.offset(field.as_usize());
|
||||
// Computing the layout does normalization, so we get a normalized type out of this
|
||||
// even if the field type is non-normalized (possible e.g. via associated types).
|
||||
let field_layout = base.layout().field(self, field);
|
||||
let field_layout = base.layout().field(self, field.as_usize());
|
||||
|
||||
// Offset may need adjustment for unsized fields.
|
||||
let (meta, offset) = if field_layout.is_unsized() {
|
||||
|
|
@ -244,7 +244,7 @@ where
|
|||
}
|
||||
_ => span_bug!(
|
||||
self.cur_span(),
|
||||
"`mplace_index` called on non-array type {:?}",
|
||||
"`project_index` called on non-array type {:?}",
|
||||
base.layout().ty
|
||||
),
|
||||
};
|
||||
|
|
@ -260,7 +260,7 @@ where
|
|||
) -> InterpResult<'tcx, (P, u64)> {
|
||||
assert!(base.layout().ty.ty_adt_def().unwrap().repr().simd());
|
||||
// SIMD types must be newtypes around arrays, so all we have to do is project to their only field.
|
||||
let array = self.project_field(base, 0)?;
|
||||
let array = self.project_field(base, FieldIdx::ZERO)?;
|
||||
let len = array.len(self)?;
|
||||
interp_ok((array, len))
|
||||
}
|
||||
|
|
@ -384,7 +384,7 @@ where
|
|||
UnwrapUnsafeBinder(target) => base.transmute(self.layout_of(target)?, self)?,
|
||||
// We don't want anything happening here, this is here as a dummy.
|
||||
Subtype(_) => base.transmute(base.layout(), self)?,
|
||||
Field(field, _) => self.project_field(base, field.index())?,
|
||||
Field(field, _) => self.project_field(base, field)?,
|
||||
Downcast(_, variant) => self.project_downcast(base, variant)?,
|
||||
Deref => self.deref_pointer(&base.to_op(self)?)?.into(),
|
||||
Index(local) => {
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
}
|
||||
for (field_index, operand) in operands.iter_enumerated() {
|
||||
let field_index = active_field_index.unwrap_or(field_index);
|
||||
let field_dest = self.project_field(&variant_dest, field_index.as_usize())?;
|
||||
let field_dest = self.project_field(&variant_dest, field_index)?;
|
||||
let op = self.eval_operand(operand, Some(field_dest.layout))?;
|
||||
self.copy_op(&op, &field_dest)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use rustc_abi::{Align, Size};
|
||||
use rustc_abi::{Align, FieldIdx, Size};
|
||||
use rustc_middle::mir::interpret::{InterpResult, Pointer};
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::{self, ExistentialPredicateStableCmpExt, Ty, TyCtxt, VtblEntry};
|
||||
|
|
@ -137,8 +137,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
matches!(val.layout().ty.kind(), ty::Dynamic(_, _, ty::DynStar)),
|
||||
"`unpack_dyn_star` only makes sense on `dyn*` types"
|
||||
);
|
||||
let data = self.project_field(val, 0)?;
|
||||
let vtable = self.project_field(val, 1)?;
|
||||
let data = self.project_field(val, FieldIdx::ZERO)?;
|
||||
let vtable = self.project_field(val, FieldIdx::ONE)?;
|
||||
let vtable = self.read_pointer(&vtable.to_op(self)?)?;
|
||||
let ty = self.get_ptr_vtable_ty(vtable, Some(expected_trait))?;
|
||||
// `data` is already the right thing but has the wrong type. So we transmute it.
|
||||
|
|
|
|||
|
|
@ -112,8 +112,10 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized {
|
|||
// So we transmute it to a raw pointer.
|
||||
let raw_ptr_ty = Ty::new_mut_ptr(*self.ecx().tcx, self.ecx().tcx.types.unit);
|
||||
let raw_ptr_ty = self.ecx().layout_of(raw_ptr_ty)?;
|
||||
let vtable_field =
|
||||
self.ecx().project_field(v, 1)?.transmute(raw_ptr_ty, self.ecx())?;
|
||||
let vtable_field = self
|
||||
.ecx()
|
||||
.project_field(v, FieldIdx::ONE)?
|
||||
.transmute(raw_ptr_ty, self.ecx())?;
|
||||
self.visit_field(v, 1, &vtable_field)?;
|
||||
|
||||
// Then unpack the first field, and continue.
|
||||
|
|
@ -140,14 +142,16 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized {
|
|||
|
||||
// `Box` has two fields: the pointer we care about, and the allocator.
|
||||
assert_eq!(v.layout().fields.count(), 2, "`Box` must have exactly 2 fields");
|
||||
let (unique_ptr, alloc) =
|
||||
(self.ecx().project_field(v, 0)?, self.ecx().project_field(v, 1)?);
|
||||
let (unique_ptr, alloc) = (
|
||||
self.ecx().project_field(v, FieldIdx::ZERO)?,
|
||||
self.ecx().project_field(v, FieldIdx::ONE)?,
|
||||
);
|
||||
// Unfortunately there is some type junk in the way here: `unique_ptr` is a `Unique`...
|
||||
// (which means another 2 fields, the second of which is a `PhantomData`)
|
||||
assert_eq!(unique_ptr.layout().fields.count(), 2);
|
||||
let (nonnull_ptr, phantom) = (
|
||||
self.ecx().project_field(&unique_ptr, 0)?,
|
||||
self.ecx().project_field(&unique_ptr, 1)?,
|
||||
self.ecx().project_field(&unique_ptr, FieldIdx::ZERO)?,
|
||||
self.ecx().project_field(&unique_ptr, FieldIdx::ONE)?,
|
||||
);
|
||||
assert!(
|
||||
phantom.layout().ty.ty_adt_def().is_some_and(|adt| adt.is_phantom_data()),
|
||||
|
|
@ -156,7 +160,7 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized {
|
|||
);
|
||||
// ... that contains a `NonNull`... (gladly, only a single field here)
|
||||
assert_eq!(nonnull_ptr.layout().fields.count(), 1);
|
||||
let raw_ptr = self.ecx().project_field(&nonnull_ptr, 0)?; // the actual raw ptr
|
||||
let raw_ptr = self.ecx().project_field(&nonnull_ptr, FieldIdx::ZERO)?; // the actual raw ptr
|
||||
// ... whose only field finally is a raw ptr we can dereference.
|
||||
self.visit_box(ty, &raw_ptr)?;
|
||||
|
||||
|
|
@ -188,9 +192,8 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized {
|
|||
}
|
||||
FieldsShape::Arbitrary { memory_index, .. } => {
|
||||
for idx in Self::aggregate_field_iter(memory_index) {
|
||||
let idx = idx.as_usize();
|
||||
let field = self.ecx().project_field(v, idx)?;
|
||||
self.visit_field(v, idx, &field)?;
|
||||
self.visit_field(v, idx.as_usize(), &field)?;
|
||||
}
|
||||
}
|
||||
FieldsShape::Array { .. } => {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use rustc_abi::FieldIdx;
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
|
|
@ -35,17 +36,20 @@ fn alloc_caller_location<'tcx>(
|
|||
// Allocate memory for `CallerLocation` struct.
|
||||
let loc_ty = ecx
|
||||
.tcx
|
||||
.type_of(ecx.tcx.require_lang_item(LangItem::PanicLocation, None))
|
||||
.type_of(ecx.tcx.require_lang_item(LangItem::PanicLocation, ecx.tcx.span))
|
||||
.instantiate(*ecx.tcx, ecx.tcx.mk_args(&[ecx.tcx.lifetimes.re_erased.into()]));
|
||||
let loc_layout = ecx.layout_of(loc_ty).unwrap();
|
||||
let location = ecx.allocate(loc_layout, MemoryKind::CallerLocation).unwrap();
|
||||
|
||||
// Initialize fields.
|
||||
ecx.write_immediate(file_wide_ptr, &ecx.project_field(&location, 0).unwrap())
|
||||
ecx.write_immediate(
|
||||
file_wide_ptr,
|
||||
&ecx.project_field(&location, FieldIdx::from_u32(0)).unwrap(),
|
||||
)
|
||||
.expect("writing to memory we just allocated cannot fail");
|
||||
ecx.write_scalar(line, &ecx.project_field(&location, FieldIdx::from_u32(1)).unwrap())
|
||||
.expect("writing to memory we just allocated cannot fail");
|
||||
ecx.write_scalar(line, &ecx.project_field(&location, 1).unwrap())
|
||||
.expect("writing to memory we just allocated cannot fail");
|
||||
ecx.write_scalar(col, &ecx.project_field(&location, 2).unwrap())
|
||||
ecx.write_scalar(col, &ecx.project_field(&location, FieldIdx::from_u32(2)).unwrap())
|
||||
.expect("writing to memory we just allocated cannot fail");
|
||||
|
||||
location
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ match 2u8 {
|
|||
}
|
||||
```
|
||||
|
||||
Older Rust code using previous editions allowed `...` to stand for exclusive
|
||||
Older Rust code using previous editions allowed `...` to stand for inclusive
|
||||
ranges which are now signified using `..=`.
|
||||
|
||||
To make this code compile replace the `...` with `..=`.
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ impl Annotatable {
|
|||
|
||||
pub fn expect_stmt(self) -> ast::Stmt {
|
||||
match self {
|
||||
Annotatable::Stmt(stmt) => stmt.into_inner(),
|
||||
Annotatable::Stmt(stmt) => *stmt,
|
||||
_ => panic!("expected statement"),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1183,9 +1183,8 @@ impl InvocationCollectorNode for P<ast::Item> {
|
|||
matches!(self.kind, ItemKind::MacCall(..))
|
||||
}
|
||||
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
|
||||
let node = self.into_inner();
|
||||
match node.kind {
|
||||
ItemKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
|
||||
match self.kind {
|
||||
ItemKind::MacCall(mac) => (mac, self.attrs, AddSemicolon::No),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
@ -1339,7 +1338,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitItemTag>
|
|||
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
|
||||
}
|
||||
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
|
||||
let item = self.wrapped.into_inner();
|
||||
let item = self.wrapped;
|
||||
match item.kind {
|
||||
AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
|
||||
_ => unreachable!(),
|
||||
|
|
@ -1380,7 +1379,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag>
|
|||
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
|
||||
}
|
||||
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
|
||||
let item = self.wrapped.into_inner();
|
||||
let item = self.wrapped;
|
||||
match item.kind {
|
||||
AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
|
||||
_ => unreachable!(),
|
||||
|
|
@ -1421,7 +1420,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitImplItem
|
|||
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
|
||||
}
|
||||
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
|
||||
let item = self.wrapped.into_inner();
|
||||
let item = self.wrapped;
|
||||
match item.kind {
|
||||
AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
|
||||
_ => unreachable!(),
|
||||
|
|
@ -1459,9 +1458,8 @@ impl InvocationCollectorNode for P<ast::ForeignItem> {
|
|||
matches!(self.kind, ForeignItemKind::MacCall(..))
|
||||
}
|
||||
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
|
||||
let node = self.into_inner();
|
||||
match node.kind {
|
||||
ForeignItemKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
|
||||
match self.kind {
|
||||
ForeignItemKind::MacCall(mac) => (mac, self.attrs, AddSemicolon::No),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
@ -1596,16 +1594,16 @@ impl InvocationCollectorNode for ast::Stmt {
|
|||
// `StmtKind`s and treat them as statement macro invocations, not as items or expressions.
|
||||
let (add_semicolon, mac, attrs) = match self.kind {
|
||||
StmtKind::MacCall(mac) => {
|
||||
let ast::MacCallStmt { mac, style, attrs, .. } = mac.into_inner();
|
||||
let ast::MacCallStmt { mac, style, attrs, .. } = *mac;
|
||||
(style == MacStmtStyle::Semicolon, mac, attrs)
|
||||
}
|
||||
StmtKind::Item(item) => match item.into_inner() {
|
||||
StmtKind::Item(item) => match *item {
|
||||
ast::Item { kind: ItemKind::MacCall(mac), attrs, .. } => {
|
||||
(mac.args.need_semicolon(), mac, attrs)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
StmtKind::Semi(expr) => match expr.into_inner() {
|
||||
StmtKind::Semi(expr) => match *expr {
|
||||
ast::Expr { kind: ExprKind::MacCall(mac), attrs, .. } => {
|
||||
(mac.args.need_semicolon(), mac, attrs)
|
||||
}
|
||||
|
|
@ -1686,8 +1684,7 @@ impl InvocationCollectorNode for P<ast::Ty> {
|
|||
matches!(self.kind, ast::TyKind::MacCall(..))
|
||||
}
|
||||
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
|
||||
let node = self.into_inner();
|
||||
match node.kind {
|
||||
match self.kind {
|
||||
TyKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
@ -1710,8 +1707,7 @@ impl InvocationCollectorNode for P<ast::Pat> {
|
|||
matches!(self.kind, PatKind::MacCall(..))
|
||||
}
|
||||
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
|
||||
let node = self.into_inner();
|
||||
match node.kind {
|
||||
match self.kind {
|
||||
PatKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
@ -1737,9 +1733,8 @@ impl InvocationCollectorNode for P<ast::Expr> {
|
|||
matches!(self.kind, ExprKind::MacCall(..))
|
||||
}
|
||||
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
|
||||
let node = self.into_inner();
|
||||
match node.kind {
|
||||
ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
|
||||
match self.kind {
|
||||
ExprKind::MacCall(mac) => (mac, self.attrs, AddSemicolon::No),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
@ -1763,7 +1758,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, OptExprTag> {
|
|||
matches!(self.wrapped.kind, ast::ExprKind::MacCall(..))
|
||||
}
|
||||
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
|
||||
let node = self.wrapped.into_inner();
|
||||
let node = self.wrapped;
|
||||
match node.kind {
|
||||
ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
|
||||
_ => unreachable!(),
|
||||
|
|
@ -1797,7 +1792,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, MethodReceiverTag>
|
|||
matches!(self.wrapped.kind, ast::ExprKind::MacCall(..))
|
||||
}
|
||||
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
|
||||
let node = self.wrapped.into_inner();
|
||||
let node = self.wrapped;
|
||||
match node.kind {
|
||||
ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
|
||||
_ => unreachable!(),
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ fn allowed_union_or_unsafe_field<'tcx>(
|
|||
let def_id = tcx
|
||||
.lang_items()
|
||||
.get(LangItem::BikeshedGuaranteedNoDrop)
|
||||
.unwrap_or_else(|| tcx.require_lang_item(LangItem::Copy, Some(span)));
|
||||
.unwrap_or_else(|| tcx.require_lang_item(LangItem::Copy, span));
|
||||
let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, ty) else {
|
||||
tcx.dcx().span_delayed_bug(span, "could not normalize field type");
|
||||
return true;
|
||||
|
|
@ -1142,7 +1142,7 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
|
|||
return;
|
||||
};
|
||||
|
||||
if let Some(second_field) = fields.get(FieldIdx::from_u32(1)) {
|
||||
if let Some(second_field) = fields.get(FieldIdx::ONE) {
|
||||
struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot have multiple fields")
|
||||
.with_span_label(tcx.def_span(second_field.did), "excess field")
|
||||
.emit();
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ pub(crate) fn check_intrinsic_type(
|
|||
ty::BoundVariableKind::Region(ty::BoundRegionKind::ClosureEnv),
|
||||
]);
|
||||
let mk_va_list_ty = |mutbl| {
|
||||
let did = tcx.require_lang_item(LangItem::VaList, Some(span));
|
||||
let did = tcx.require_lang_item(LangItem::VaList, span);
|
||||
let region = ty::Region::new_bound(
|
||||
tcx,
|
||||
ty::INNERMOST,
|
||||
|
|
@ -442,9 +442,7 @@ pub(crate) fn check_intrinsic_type(
|
|||
|
||||
sym::bswap | sym::bitreverse => (1, 0, vec![param(0)], param(0)),
|
||||
|
||||
sym::three_way_compare => {
|
||||
(1, 0, vec![param(0), param(0)], tcx.ty_ordering_enum(Some(span)))
|
||||
}
|
||||
sym::three_way_compare => (1, 0, vec![param(0), param(0)], tcx.ty_ordering_enum(span)),
|
||||
|
||||
sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
|
||||
(1, 0, vec![param(0), param(0)], Ty::new_tup(tcx, &[param(0), tcx.types.bool]))
|
||||
|
|
@ -520,7 +518,7 @@ pub(crate) fn check_intrinsic_type(
|
|||
|
||||
sym::discriminant_value => {
|
||||
let assoc_items = tcx.associated_item_def_ids(
|
||||
tcx.require_lang_item(hir::LangItem::DiscriminantKind, None),
|
||||
tcx.require_lang_item(hir::LangItem::DiscriminantKind, span),
|
||||
);
|
||||
let discriminant_def_id = assoc_items[0];
|
||||
|
||||
|
|
|
|||
|
|
@ -969,7 +969,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
|
|||
),
|
||||
wfcx.param_env,
|
||||
ty,
|
||||
tcx.require_lang_item(LangItem::UnsizedConstParamTy, Some(hir_ty.span)),
|
||||
tcx.require_lang_item(LangItem::UnsizedConstParamTy, hir_ty.span),
|
||||
);
|
||||
Ok(())
|
||||
})
|
||||
|
|
@ -983,7 +983,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
|
|||
),
|
||||
wfcx.param_env,
|
||||
ty,
|
||||
tcx.require_lang_item(LangItem::ConstParamTy, Some(hir_ty.span)),
|
||||
tcx.require_lang_item(LangItem::ConstParamTy, hir_ty.span),
|
||||
);
|
||||
Ok(())
|
||||
})
|
||||
|
|
@ -1232,7 +1232,7 @@ fn check_type_defn<'tcx>(
|
|||
),
|
||||
wfcx.param_env,
|
||||
ty,
|
||||
tcx.require_lang_item(LangItem::Sized, Some(hir_ty.span)),
|
||||
tcx.require_lang_item(LangItem::Sized, hir_ty.span),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -1356,7 +1356,7 @@ fn check_static_item(
|
|||
),
|
||||
wfcx.param_env,
|
||||
item_ty,
|
||||
tcx.require_lang_item(LangItem::Sized, Some(ty_span)),
|
||||
tcx.require_lang_item(LangItem::Sized, ty_span),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -1375,7 +1375,7 @@ fn check_static_item(
|
|||
),
|
||||
wfcx.param_env,
|
||||
item_ty,
|
||||
tcx.require_lang_item(LangItem::Sync, Some(ty_span)),
|
||||
tcx.require_lang_item(LangItem::Sync, ty_span),
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
|
|
@ -1401,7 +1401,7 @@ fn check_const_item(
|
|||
),
|
||||
wfcx.param_env,
|
||||
ty,
|
||||
tcx.require_lang_item(LangItem::Sized, None),
|
||||
tcx.require_lang_item(LangItem::Sized, ty_span),
|
||||
);
|
||||
|
||||
check_where_clauses(wfcx, item_span, def_id);
|
||||
|
|
@ -1725,13 +1725,13 @@ fn check_fn_or_method<'tcx>(
|
|||
ObligationCause::new(span, wfcx.body_def_id, ObligationCauseCode::RustCall),
|
||||
wfcx.param_env,
|
||||
*ty,
|
||||
tcx.require_lang_item(hir::LangItem::Tuple, Some(span)),
|
||||
tcx.require_lang_item(hir::LangItem::Tuple, span),
|
||||
);
|
||||
wfcx.register_bound(
|
||||
ObligationCause::new(span, wfcx.body_def_id, ObligationCauseCode::RustCall),
|
||||
wfcx.param_env,
|
||||
*ty,
|
||||
tcx.require_lang_item(hir::LangItem::Sized, Some(span)),
|
||||
tcx.require_lang_item(hir::LangItem::Sized, span),
|
||||
);
|
||||
} else {
|
||||
tcx.dcx().span_err(
|
||||
|
|
@ -1776,7 +1776,7 @@ fn check_sized_if_body<'tcx>(
|
|||
ObligationCause::new(span, def_id, code),
|
||||
wfcx.param_env,
|
||||
ty,
|
||||
tcx.require_lang_item(LangItem::Sized, Some(span)),
|
||||
tcx.require_lang_item(LangItem::Sized, span),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -2013,7 +2013,7 @@ fn receiver_is_valid<'tcx>(
|
|||
// deref chain implement `LegacyReceiver`.
|
||||
if arbitrary_self_types_enabled.is_none() {
|
||||
let legacy_receiver_trait_def_id =
|
||||
tcx.require_lang_item(LangItem::LegacyReceiver, Some(span));
|
||||
tcx.require_lang_item(LangItem::LegacyReceiver, span);
|
||||
if !legacy_receiver_is_implemented(
|
||||
wfcx,
|
||||
legacy_receiver_trait_def_id,
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
|||
// redundant errors for `DispatchFromDyn`. This is best effort, though.
|
||||
let mut res = Ok(());
|
||||
tcx.for_each_relevant_impl(
|
||||
tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)),
|
||||
tcx.require_lang_item(LangItem::CoerceUnsized, span),
|
||||
source,
|
||||
|impl_def_id| {
|
||||
res = res.and(tcx.ensure_ok().coerce_unsized_info(impl_def_id));
|
||||
|
|
@ -379,8 +379,8 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
|||
let span = tcx.def_span(impl_did);
|
||||
let trait_name = "CoerceUnsized";
|
||||
|
||||
let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, Some(span));
|
||||
let unsize_trait = tcx.require_lang_item(LangItem::Unsize, Some(span));
|
||||
let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, span);
|
||||
let unsize_trait = tcx.require_lang_item(LangItem::Unsize, span);
|
||||
|
||||
let source = tcx.type_of(impl_did).instantiate_identity();
|
||||
let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().instantiate_identity();
|
||||
|
|
@ -591,7 +591,7 @@ fn infringing_fields_error<'tcx>(
|
|||
impl_did: LocalDefId,
|
||||
impl_span: Span,
|
||||
) -> ErrorGuaranteed {
|
||||
let trait_did = tcx.require_lang_item(lang_item, Some(impl_span));
|
||||
let trait_did = tcx.require_lang_item(lang_item, impl_span);
|
||||
|
||||
let trait_name = tcx.def_path_str(trait_did);
|
||||
|
||||
|
|
@ -748,7 +748,7 @@ fn visit_implementation_of_pointer_like(checker: &Checker<'_>) -> Result<(), Err
|
|||
ObligationCause::misc(impl_span, checker.impl_def_id),
|
||||
param_env,
|
||||
nontrivial_field_ty,
|
||||
tcx.require_lang_item(LangItem::PointerLike, Some(impl_span)),
|
||||
tcx.require_lang_item(LangItem::PointerLike, impl_span),
|
||||
);
|
||||
// FIXME(dyn-star): We should regionck this implementation.
|
||||
if ocx.select_all_or_error().is_empty() {
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ fn generic_arg_mismatch_err(
|
|||
let param_name = tcx.hir_ty_param_name(param_local_id);
|
||||
let param_type = tcx.type_of(param.def_id).instantiate_identity();
|
||||
if param_type.is_suggestable(tcx, false) {
|
||||
err.span_suggestion(
|
||||
err.span_suggestion_verbose(
|
||||
tcx.def_span(src_def_id),
|
||||
"consider changing this type parameter to a const parameter",
|
||||
format!("const {param_name}: {param_type}"),
|
||||
|
|
|
|||
|
|
@ -2590,7 +2590,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
.unwrap_or_else(|guar| Ty::new_error(tcx, guar))
|
||||
}
|
||||
&hir::TyKind::Path(hir::QPath::LangItem(lang_item, span)) => {
|
||||
let def_id = tcx.require_lang_item(lang_item, Some(span));
|
||||
let def_id = tcx.require_lang_item(lang_item, span);
|
||||
let (args, _) = self.lower_generic_args_of_path(
|
||||
span,
|
||||
def_id,
|
||||
|
|
|
|||
|
|
@ -137,6 +137,18 @@ hir_typeck_lossy_provenance_ptr2int =
|
|||
|
||||
hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}`
|
||||
|
||||
hir_typeck_naked_asm_outside_naked_fn =
|
||||
the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]`
|
||||
|
||||
hir_typeck_naked_functions_asm_block =
|
||||
naked functions must contain a single `naked_asm!` invocation
|
||||
.label_multiple_asm = multiple `naked_asm!` invocations are not allowed in naked functions
|
||||
.label_non_asm = not allowed in naked functions
|
||||
|
||||
hir_typeck_naked_functions_must_naked_asm =
|
||||
the `asm!` macro is not allowed in naked functions
|
||||
.label = consider using the `naked_asm!` macro instead
|
||||
|
||||
hir_typeck_never_type_fallback_flowing_into_unsafe_call = never type fallback affects this call to an `unsafe` function
|
||||
.help = specify the type explicitly
|
||||
hir_typeck_never_type_fallback_flowing_into_unsafe_deref = never type fallback affects this raw pointer dereference
|
||||
|
|
@ -159,6 +171,9 @@ hir_typeck_no_field_on_variant = no field named `{$field}` on enum variant `{$co
|
|||
hir_typeck_no_field_on_variant_enum = this enum variant...
|
||||
hir_typeck_no_field_on_variant_field = ...does not have this field
|
||||
|
||||
hir_typeck_no_patterns =
|
||||
patterns not allowed in naked function parameters
|
||||
|
||||
hir_typeck_note_caller_chooses_ty_for_ty_param = the caller chooses a type for `{$ty_param_name}` which can be different from `{$found_ty}`
|
||||
|
||||
hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide
|
||||
|
|
@ -167,6 +182,10 @@ hir_typeck_option_result_asref = use `{$def_path}::as_ref` to convert `{$expecte
|
|||
hir_typeck_option_result_cloned = use `{$def_path}::cloned` to clone the value inside the `{$def_path}`
|
||||
hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value inside the `{$def_path}`
|
||||
|
||||
hir_typeck_params_not_allowed =
|
||||
referencing function parameters is not allowed in naked functions
|
||||
.help = follow the calling convention in asm block to use parameters
|
||||
|
||||
hir_typeck_pass_to_variadic_function = can't pass `{$ty}` to variadic function
|
||||
.suggestion = cast the value to `{$cast_ty}`
|
||||
.teach_help = certain types, like `{$ty}`, must be cast before passing them to a variadic function to match the implicit cast that a C compiler would perform as part of C's numeric promotion rules
|
||||
|
|
|
|||
|
|
@ -508,7 +508,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
if let Some(ty) = fn_sig.inputs().last().copied() {
|
||||
self.register_bound(
|
||||
ty,
|
||||
self.tcx.require_lang_item(hir::LangItem::Tuple, Some(sp)),
|
||||
self.tcx.require_lang_item(hir::LangItem::Tuple, sp),
|
||||
self.cause(sp, ObligationCauseCode::RustCall),
|
||||
);
|
||||
self.require_type_is_sized(ty, sp, ObligationCauseCode::RustCall);
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ pub(super) fn check_fn<'a, 'tcx>(
|
|||
// (as it's created inside the body itself, not passed in from outside).
|
||||
let maybe_va_list = fn_sig.c_variadic.then(|| {
|
||||
let span = body.params.last().unwrap().span;
|
||||
let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(span));
|
||||
let va_list_did = tcx.require_lang_item(LangItem::VaList, span);
|
||||
let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span));
|
||||
|
||||
tcx.type_of(va_list_did).instantiate(tcx, &[region.into()])
|
||||
|
|
@ -178,7 +178,7 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>
|
|||
tcx.dcx().span_err(span, "should have no const parameters");
|
||||
}
|
||||
|
||||
let panic_info_did = tcx.require_lang_item(hir::LangItem::PanicInfo, Some(span));
|
||||
let panic_info_did = tcx.require_lang_item(hir::LangItem::PanicInfo, span);
|
||||
|
||||
// build type `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !`
|
||||
let panic_info_ty = tcx.type_of(panic_info_did).instantiate(
|
||||
|
|
|
|||
|
|
@ -142,13 +142,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
Ty::new_adt(
|
||||
tcx,
|
||||
tcx.adt_def(
|
||||
tcx.require_lang_item(hir::LangItem::Poll, Some(expr_span)),
|
||||
),
|
||||
tcx.adt_def(tcx.require_lang_item(hir::LangItem::Poll, expr_span)),
|
||||
tcx.mk_args(&[Ty::new_adt(
|
||||
tcx,
|
||||
tcx.adt_def(
|
||||
tcx.require_lang_item(hir::LangItem::Option, Some(expr_span)),
|
||||
tcx.require_lang_item(hir::LangItem::Option, expr_span),
|
||||
),
|
||||
tcx.mk_args(&[yield_ty.into()]),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -760,8 +760,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||
self.param_env,
|
||||
ty::TraitRef::new(
|
||||
self.tcx,
|
||||
self.tcx
|
||||
.require_lang_item(hir::LangItem::PointerLike, Some(self.cause.span)),
|
||||
self.tcx.require_lang_item(hir::LangItem::PointerLike, self.cause.span),
|
||||
[a],
|
||||
),
|
||||
),
|
||||
|
|
@ -1969,7 +1968,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
|||
fcx.param_env,
|
||||
ty::TraitRef::new(
|
||||
fcx.tcx,
|
||||
fcx.tcx.require_lang_item(hir::LangItem::Sized, None),
|
||||
fcx.tcx.require_lang_item(hir::LangItem::Sized, DUMMY_SP),
|
||||
[sig.output()],
|
||||
),
|
||||
))
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ use std::borrow::Cow;
|
|||
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{
|
||||
Applicability, Diag, DiagArgValue, DiagSymbolList, EmissionGuarantee, IntoDiagArg, MultiSpan,
|
||||
Subdiagnostic,
|
||||
Applicability, Diag, DiagArgValue, DiagCtxtHandle, DiagSymbolList, Diagnostic,
|
||||
EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic,
|
||||
};
|
||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
|
|
@ -983,3 +983,55 @@ pub(crate) struct RegisterTypeUnstable<'a> {
|
|||
pub span: Span,
|
||||
pub ty: Ty<'a>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_naked_asm_outside_naked_fn)]
|
||||
pub(crate) struct NakedAsmOutsideNakedFn {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_no_patterns)]
|
||||
pub(crate) struct NoPatterns {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_params_not_allowed)]
|
||||
#[help]
|
||||
pub(crate) struct ParamsNotAllowed {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
pub(crate) struct NakedFunctionsAsmBlock {
|
||||
pub span: Span,
|
||||
pub multiple_asms: Vec<Span>,
|
||||
pub non_asms: Vec<Span>,
|
||||
}
|
||||
|
||||
impl<G: EmissionGuarantee> Diagnostic<'_, G> for NakedFunctionsAsmBlock {
|
||||
#[track_caller]
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
|
||||
let mut diag = Diag::new(dcx, level, fluent::hir_typeck_naked_functions_asm_block);
|
||||
diag.span(self.span);
|
||||
diag.code(E0787);
|
||||
for span in self.multiple_asms.iter() {
|
||||
diag.span_label(*span, fluent::hir_typeck_label_multiple_asm);
|
||||
}
|
||||
for span in self.non_asms.iter() {
|
||||
diag.span_label(*span, fluent::hir_typeck_label_non_asm);
|
||||
}
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_naked_functions_must_naked_asm, code = E0787)]
|
||||
pub(crate) struct NakedFunctionsMustNakedAsm {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,9 +44,9 @@ use crate::errors::{
|
|||
AddressOfTemporaryTaken, BaseExpressionDoubleDot, BaseExpressionDoubleDotAddExpr,
|
||||
BaseExpressionDoubleDotEnableDefaultFieldValues, BaseExpressionDoubleDotRemove,
|
||||
CantDereference, FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct,
|
||||
HelpUseLatestEdition, NoFieldOnType, NoFieldOnVariant, ReturnLikeStatementKind,
|
||||
ReturnStmtOutsideOfFnBody, StructExprNonExhaustive, TypeMismatchFruTypo,
|
||||
YieldExprOutsideOfCoroutine,
|
||||
HelpUseLatestEdition, NakedAsmOutsideNakedFn, NoFieldOnType, NoFieldOnVariant,
|
||||
ReturnLikeStatementKind, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive,
|
||||
TypeMismatchFruTypo, YieldExprOutsideOfCoroutine,
|
||||
};
|
||||
use crate::{
|
||||
BreakableCtxt, CoroutineTypes, Diverges, FnCtxt, GatherLocalsVisitor, Needs,
|
||||
|
|
@ -524,7 +524,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
ExprKind::InlineAsm(asm) => {
|
||||
// We defer some asm checks as we may not have resolved the input and output types yet (they may still be infer vars).
|
||||
self.deferred_asm_checks.borrow_mut().push((asm, expr.hir_id));
|
||||
self.check_expr_asm(asm)
|
||||
self.check_expr_asm(asm, expr.span)
|
||||
}
|
||||
ExprKind::OffsetOf(container, fields) => {
|
||||
self.check_expr_offset_of(container, fields, expr)
|
||||
|
|
@ -1407,7 +1407,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let lhs_deref_ty_is_sized = self
|
||||
.infcx
|
||||
.type_implements_trait(
|
||||
self.tcx.require_lang_item(LangItem::Sized, None),
|
||||
self.tcx.require_lang_item(LangItem::Sized, span),
|
||||
[lhs_deref_ty],
|
||||
self.param_env,
|
||||
)
|
||||
|
|
@ -3761,7 +3761,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_expr_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>) -> Ty<'tcx> {
|
||||
fn check_expr_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>, span: Span) -> Ty<'tcx> {
|
||||
if let rustc_ast::AsmMacro::NakedAsm = asm.asm_macro {
|
||||
if !self.tcx.has_attr(self.body_id, sym::naked) {
|
||||
self.tcx.dcx().emit_err(NakedAsmOutsideNakedFn { span });
|
||||
}
|
||||
}
|
||||
|
||||
let mut diverge = asm.asm_macro.diverges(asm.options);
|
||||
|
||||
for (op, _op_sp) in asm.operands {
|
||||
|
|
|
|||
|
|
@ -409,7 +409,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
code: traits::ObligationCauseCode<'tcx>,
|
||||
) {
|
||||
if !ty.references_error() {
|
||||
let lang_item = self.tcx.require_lang_item(LangItem::Sized, None);
|
||||
let lang_item = self.tcx.require_lang_item(LangItem::Sized, span);
|
||||
self.require_type_meets(ty, span, code, lang_item);
|
||||
}
|
||||
}
|
||||
|
|
@ -443,7 +443,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// Nothing else is required here.
|
||||
} else {
|
||||
// We can't be sure, let's required full `Sized`.
|
||||
let lang_item = self.tcx.require_lang_item(LangItem::Sized, None);
|
||||
let lang_item = self.tcx.require_lang_item(LangItem::Sized, span);
|
||||
self.require_type_meets(ty, span, ObligationCauseCode::Misc, lang_item);
|
||||
}
|
||||
}
|
||||
|
|
@ -732,7 +732,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
span: Span,
|
||||
hir_id: HirId,
|
||||
) -> (Res, Ty<'tcx>) {
|
||||
let def_id = self.tcx.require_lang_item(lang_item, Some(span));
|
||||
let def_id = self.tcx.require_lang_item(lang_item, span);
|
||||
let def_kind = self.tcx.def_kind(def_id);
|
||||
|
||||
let item_ty = if let DefKind::Variant = def_kind {
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
_ => traits::IsConstable::No,
|
||||
};
|
||||
|
||||
let lang_item = self.tcx.require_lang_item(LangItem::Copy, None);
|
||||
let lang_item = self.tcx.require_lang_item(LangItem::Copy, element.span);
|
||||
let code = traits::ObligationCauseCode::RepeatElementCopy {
|
||||
is_constable,
|
||||
elt_span: element.span,
|
||||
|
|
@ -1680,8 +1680,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
ast::LitKind::CStr(_, _) => Ty::new_imm_ref(
|
||||
tcx,
|
||||
tcx.lifetimes.re_static,
|
||||
tcx.type_of(tcx.require_lang_item(hir::LangItem::CStr, Some(lit.span)))
|
||||
.skip_binder(),
|
||||
tcx.type_of(tcx.require_lang_item(hir::LangItem::CStr, lit.span)).skip_binder(),
|
||||
),
|
||||
ast::LitKind::Err(guar) => Ty::new_error(tcx, guar),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2679,7 +2679,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let mut sugg_sp = sp;
|
||||
if let hir::ExprKind::MethodCall(segment, receiver, args, _) = expr.kind {
|
||||
let clone_trait =
|
||||
self.tcx.require_lang_item(LangItem::Clone, Some(segment.ident.span));
|
||||
self.tcx.require_lang_item(LangItem::Clone, segment.ident.span);
|
||||
if args.is_empty()
|
||||
&& self
|
||||
.typeck_results
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
|||
_ if ty.references_error() => return None,
|
||||
ty::Adt(adt, args) if self.tcx().is_lang_item(adt.did(), LangItem::MaybeUninit) => {
|
||||
let fields = &adt.non_enum_variant().fields;
|
||||
let ty = fields[FieldIdx::from_u32(1)].ty(self.tcx(), args);
|
||||
let ty = fields[FieldIdx::ONE].ty(self.tcx(), args);
|
||||
// FIXME: Are we just trying to map to the `T` in `MaybeUninit<T>`?
|
||||
// If so, just get it from the args.
|
||||
let ty::Adt(ty, args) = ty.kind() else {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ mod fn_ctxt;
|
|||
mod gather_locals;
|
||||
mod intrinsicck;
|
||||
mod method;
|
||||
mod naked_functions;
|
||||
mod op;
|
||||
mod opaque_types;
|
||||
mod pat;
|
||||
|
|
@ -55,8 +56,8 @@ use rustc_middle::query::Providers;
|
|||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::config;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::{Span, sym};
|
||||
use tracing::{debug, instrument};
|
||||
use typeck_root_ctxt::TypeckRootCtxt;
|
||||
|
||||
|
|
@ -170,6 +171,10 @@ fn typeck_with_inspect<'tcx>(
|
|||
.map(|(idx, ty)| fcx.normalize(arg_span(idx), ty)),
|
||||
);
|
||||
|
||||
if tcx.has_attr(def_id, sym::naked) {
|
||||
naked_functions::typeck_naked_fn(tcx, def_id, body);
|
||||
}
|
||||
|
||||
check_fn(&mut fcx, fn_sig, None, decl, def_id, body, tcx.features().unsized_fn_params());
|
||||
} else {
|
||||
let expected_type = if let Some(infer_ty) = infer_type_if_missing(&fcx, node) {
|
||||
|
|
|
|||
|
|
@ -1,56 +1,29 @@
|
|||
//! Checks validity of naked functions.
|
||||
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{LocalDefId, LocalModDefId};
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::{ExprKind, HirIdSet, StmtKind};
|
||||
use rustc_middle::hir::nested_filter::OnlyBodies;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::{Span, sym};
|
||||
|
||||
use crate::errors::{
|
||||
NakedAsmOutsideNakedFn, NakedFunctionsAsmBlock, NakedFunctionsMustNakedAsm, NoPatterns,
|
||||
ParamsNotAllowed,
|
||||
NakedFunctionsAsmBlock, NakedFunctionsMustNakedAsm, NoPatterns, ParamsNotAllowed,
|
||||
};
|
||||
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
*providers = Providers { check_mod_naked_functions, ..*providers };
|
||||
}
|
||||
|
||||
fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
|
||||
let items = tcx.hir_module_items(module_def_id);
|
||||
for def_id in items.definitions() {
|
||||
if !matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let body = match tcx.hir_node_by_def_id(def_id) {
|
||||
hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Fn { body: body_id, .. }, ..
|
||||
})
|
||||
| hir::Node::TraitItem(hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body_id)),
|
||||
..
|
||||
})
|
||||
| hir::Node::ImplItem(hir::ImplItem {
|
||||
kind: hir::ImplItemKind::Fn(_, body_id), ..
|
||||
}) => tcx.hir_body(*body_id),
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
if tcx.has_attr(def_id, sym::naked) {
|
||||
check_no_patterns(tcx, body.params);
|
||||
check_no_parameters_use(tcx, body);
|
||||
check_asm(tcx, def_id, body);
|
||||
} else {
|
||||
// `naked_asm!` is not allowed outside of functions marked as `#[naked]`
|
||||
let mut visitor = CheckNakedAsmInNakedFn { tcx };
|
||||
visitor.visit_body(body);
|
||||
}
|
||||
}
|
||||
/// Naked fns can only have trivial binding patterns in arguments,
|
||||
/// may not actually use those arguments, and the body must consist of just
|
||||
/// a single asm statement.
|
||||
pub(crate) fn typeck_naked_fn<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
body: &'tcx hir::Body<'tcx>,
|
||||
) {
|
||||
debug_assert!(tcx.has_attr(def_id, sym::naked));
|
||||
check_no_patterns(tcx, body.params);
|
||||
check_no_parameters_use(tcx, body);
|
||||
check_asm(tcx, def_id, body);
|
||||
}
|
||||
|
||||
/// Checks that parameters don't use patterns. Mirrors the checks for function declarations.
|
||||
|
|
@ -231,25 +204,3 @@ impl<'tcx> Visitor<'tcx> for CheckInlineAssembly {
|
|||
self.check_expr(expr, expr.span);
|
||||
}
|
||||
}
|
||||
|
||||
struct CheckNakedAsmInNakedFn<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for CheckNakedAsmInNakedFn<'tcx> {
|
||||
type NestedFilter = OnlyBodies;
|
||||
|
||||
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
|
||||
if let ExprKind::InlineAsm(inline_asm) = expr.kind {
|
||||
if let rustc_ast::AsmMacro::NakedAsm = inline_asm.asm_macro {
|
||||
self.tcx.dcx().emit_err(NakedAsmOutsideNakedFn { span: expr.span });
|
||||
}
|
||||
}
|
||||
|
||||
hir::intravisit::walk_expr(self, expr);
|
||||
}
|
||||
}
|
||||
|
|
@ -796,7 +796,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
if *negated {
|
||||
self.register_bound(
|
||||
ty,
|
||||
self.tcx.require_lang_item(LangItem::Neg, Some(lt.span)),
|
||||
self.tcx.require_lang_item(LangItem::Neg, lt.span),
|
||||
ObligationCause::dummy_with_span(lt.span),
|
||||
);
|
||||
}
|
||||
|
|
@ -2553,13 +2553,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let tcx = self.tcx;
|
||||
self.register_bound(
|
||||
source_ty,
|
||||
tcx.require_lang_item(hir::LangItem::DerefPure, Some(span)),
|
||||
tcx.require_lang_item(hir::LangItem::DerefPure, span),
|
||||
self.misc(span),
|
||||
);
|
||||
// The expected type for the deref pat's inner pattern is `<expected as Deref>::Target`.
|
||||
let target_ty = Ty::new_projection(
|
||||
tcx,
|
||||
tcx.require_lang_item(hir::LangItem::DerefTarget, Some(span)),
|
||||
tcx.require_lang_item(hir::LangItem::DerefTarget, span),
|
||||
[source_ty],
|
||||
);
|
||||
let target_ty = self.normalize(span, target_ty);
|
||||
|
|
@ -2580,7 +2580,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
for mutably_derefed_ty in derefed_tys {
|
||||
self.register_bound(
|
||||
mutably_derefed_ty,
|
||||
self.tcx.require_lang_item(hir::LangItem::DerefMut, Some(span)),
|
||||
self.tcx.require_lang_item(hir::LangItem::DerefMut, span),
|
||||
self.misc(span),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1560,7 +1560,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
};
|
||||
|
||||
let is_drop_defined_for_ty = |ty: Ty<'tcx>| {
|
||||
let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span));
|
||||
let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, closure_span);
|
||||
self.infcx
|
||||
.type_implements_trait(drop_trait, [ty], self.tcx.param_env(closure_def_id))
|
||||
.must_apply_modulo_regions()
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
|
|||
assert!(entry.is_some());
|
||||
}
|
||||
|
||||
pub(crate) fn is_empty(&self) -> bool {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
|
||||
opaque_types.is_empty() && duplicate_entries.is_empty()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -956,7 +956,6 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
|
|||
tcx.par_hir_for_each_module(|module| {
|
||||
tcx.ensure_ok().check_mod_loops(module);
|
||||
tcx.ensure_ok().check_mod_attrs(module);
|
||||
tcx.ensure_ok().check_mod_naked_functions(module);
|
||||
tcx.ensure_ok().check_mod_unstable_api_usage(module);
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ impl<'a> Cursor<'a> {
|
|||
|
||||
/// Peeks the third symbol from the input stream without consuming it.
|
||||
pub fn third(&self) -> char {
|
||||
// `.next()` optimizes better than `.nth(1)`
|
||||
// `.next()` optimizes better than `.nth(2)`
|
||||
let mut iter = self.chars.clone();
|
||||
iter.next();
|
||||
iter.next();
|
||||
|
|
|
|||
|
|
@ -30,14 +30,13 @@ mod cursor;
|
|||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
use LiteralKind::*;
|
||||
use TokenKind::*;
|
||||
use cursor::EOF_CHAR;
|
||||
pub use cursor::{Cursor, FrontmatterAllowed};
|
||||
use unicode_properties::UnicodeEmoji;
|
||||
pub use unicode_xid::UNICODE_VERSION as UNICODE_XID_VERSION;
|
||||
|
||||
use self::LiteralKind::*;
|
||||
use self::TokenKind::*;
|
||||
use crate::cursor::EOF_CHAR;
|
||||
pub use crate::cursor::{Cursor, FrontmatterAllowed};
|
||||
|
||||
/// Parsed token.
|
||||
/// It doesn't contain information about data that has been parsed,
|
||||
/// only the type of the token and its size.
|
||||
|
|
@ -372,9 +371,8 @@ pub fn is_ident(string: &str) -> bool {
|
|||
impl Cursor<'_> {
|
||||
/// Parses a token from the input string.
|
||||
pub fn advance_token(&mut self) -> Token {
|
||||
let first_char = match self.bump() {
|
||||
Some(c) => c,
|
||||
None => return Token::new(TokenKind::Eof, 0),
|
||||
let Some(first_char) = self.bump() else {
|
||||
return Token::new(TokenKind::Eof, 0);
|
||||
};
|
||||
|
||||
let token_kind = match first_char {
|
||||
|
|
@ -788,7 +786,7 @@ impl Cursor<'_> {
|
|||
} else {
|
||||
// No base prefix, parse number in the usual way.
|
||||
self.eat_decimal_digits();
|
||||
};
|
||||
}
|
||||
|
||||
match self.first() {
|
||||
// Don't be greedy if this is actually an
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ pub use rustc_session::lint::builtin::*;
|
|||
use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::{BytePos, Ident, InnerSpan, Span, Symbol, kw, sym};
|
||||
use rustc_span::{BytePos, DUMMY_SP, Ident, InnerSpan, Span, Symbol, kw, sym};
|
||||
use rustc_target::asm::InlineAsmArch;
|
||||
use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt};
|
||||
use rustc_trait_selection::traits::misc::type_allowed_to_implement_copy;
|
||||
|
|
@ -635,7 +635,8 @@ fn type_implements_negative_copy_modulo_regions<'tcx>(
|
|||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> bool {
|
||||
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
|
||||
let trait_ref = ty::TraitRef::new(tcx, tcx.require_lang_item(hir::LangItem::Copy, None), [ty]);
|
||||
let trait_ref =
|
||||
ty::TraitRef::new(tcx, tcx.require_lang_item(hir::LangItem::Copy, DUMMY_SP), [ty]);
|
||||
let pred = ty::TraitPredicate { trait_ref, polarity: ty::PredicatePolarity::Negative };
|
||||
let obligation = traits::Obligation {
|
||||
cause: traits::ObligationCause::dummy(),
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ pub(crate) struct StrictCoherenceNeedsNegativeCoherence {
|
|||
#[diag(middle_requires_lang_item)]
|
||||
pub(crate) struct RequiresLangItem {
|
||||
#[primary_span]
|
||||
pub span: Option<Span>,
|
||||
pub span: Span,
|
||||
pub name: Symbol,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use crate::ty::{self, TyCtxt};
|
|||
impl<'tcx> TyCtxt<'tcx> {
|
||||
/// Returns the `DefId` for a given `LangItem`.
|
||||
/// If not found, fatally aborts compilation.
|
||||
pub fn require_lang_item(self, lang_item: LangItem, span: Option<Span>) -> DefId {
|
||||
pub fn require_lang_item(self, lang_item: LangItem, span: Span) -> DefId {
|
||||
self.lang_items().get(lang_item).unwrap_or_else(|| {
|
||||
self.dcx().emit_fatal(crate::error::RequiresLangItem { span, name: lang_item.name() });
|
||||
})
|
||||
|
|
|
|||
|
|
@ -835,7 +835,7 @@ impl<'tcx> BinOp {
|
|||
&BinOp::Cmp => {
|
||||
// these should be integer-like types of the same size.
|
||||
assert_eq!(lhs_ty, rhs_ty);
|
||||
tcx.ty_ordering_enum(None)
|
||||
tcx.ty_ordering_enum(DUMMY_SP)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1120,10 +1120,6 @@ rustc_queries! {
|
|||
desc { |tcx| "checking loops in {}", describe_as_module(key, tcx) }
|
||||
}
|
||||
|
||||
query check_mod_naked_functions(key: LocalModDefId) {
|
||||
desc { |tcx| "checking naked functions in {}", describe_as_module(key, tcx) }
|
||||
}
|
||||
|
||||
query check_mod_privacy(key: LocalModDefId) {
|
||||
desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,8 +128,8 @@ impl OverloadedDeref {
|
|||
/// for this overloaded deref's mutability.
|
||||
pub fn method_call<'tcx>(&self, tcx: TyCtxt<'tcx>) -> DefId {
|
||||
let trait_def_id = match self.mutbl {
|
||||
hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, None),
|
||||
hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, None),
|
||||
hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, self.span),
|
||||
hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, self.span),
|
||||
};
|
||||
tcx.associated_items(trait_def_id)
|
||||
.in_definition_order()
|
||||
|
|
|
|||
|
|
@ -458,7 +458,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
}
|
||||
|
||||
fn require_lang_item(self, lang_item: TraitSolverLangItem) -> DefId {
|
||||
self.require_lang_item(trait_lang_item_to_lang_item(lang_item), None)
|
||||
self.require_lang_item(trait_lang_item_to_lang_item(lang_item), DUMMY_SP)
|
||||
}
|
||||
|
||||
fn is_lang_item(self, def_id: DefId, lang_item: TraitSolverLangItem) -> bool {
|
||||
|
|
@ -1710,7 +1710,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
|
||||
/// Gets a `Ty` representing the [`LangItem::OrderingEnum`]
|
||||
#[track_caller]
|
||||
pub fn ty_ordering_enum(self, span: Option<Span>) -> Ty<'tcx> {
|
||||
pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
|
||||
let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
|
||||
self.type_of(ordering_enum).no_bound_vars().unwrap()
|
||||
}
|
||||
|
|
@ -2253,7 +2253,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
Ty::new_imm_ref(
|
||||
self,
|
||||
self.lifetimes.re_static,
|
||||
self.type_of(self.require_lang_item(LangItem::PanicLocation, None))
|
||||
self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
|
||||
.instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
|
||||
)
|
||||
}
|
||||
|
|
@ -2712,7 +2712,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
/// Given a `ty`, return whether it's an `impl Future<...>`.
|
||||
pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
|
||||
let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
|
||||
let future_trait = self.require_lang_item(LangItem::Future, None);
|
||||
let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
|
||||
|
||||
self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
|
||||
let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
|
||||
|
|
|
|||
|
|
@ -786,7 +786,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
}
|
||||
|
||||
pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> {
|
||||
let def_id = tcx.require_lang_item(LangItem::DropInPlace, None);
|
||||
let def_id = tcx.require_lang_item(LangItem::DropInPlace, DUMMY_SP);
|
||||
let args = tcx.mk_args(&[ty.into()]);
|
||||
Instance::expect_resolve(
|
||||
tcx,
|
||||
|
|
@ -798,7 +798,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
}
|
||||
|
||||
pub fn resolve_async_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> {
|
||||
let def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, None);
|
||||
let def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, DUMMY_SP);
|
||||
let args = tcx.mk_args(&[ty.into()]);
|
||||
Instance::expect_resolve(
|
||||
tcx,
|
||||
|
|
@ -824,7 +824,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
closure_did: DefId,
|
||||
args: ty::GenericArgsRef<'tcx>,
|
||||
) -> Instance<'tcx> {
|
||||
let fn_once = tcx.require_lang_item(LangItem::FnOnce, None);
|
||||
let fn_once = tcx.require_lang_item(LangItem::FnOnce, DUMMY_SP);
|
||||
let call_once = tcx
|
||||
.associated_items(fn_once)
|
||||
.in_definition_order()
|
||||
|
|
|
|||
|
|
@ -593,7 +593,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
ty: Ty<'tcx>,
|
||||
mutbl: ty::Mutability,
|
||||
) -> Ty<'tcx> {
|
||||
let pin = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, None));
|
||||
let pin = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, DUMMY_SP));
|
||||
Ty::new_adt(tcx, pin, tcx.mk_args(&[Ty::new_ref(tcx, r, ty, mutbl).into()]))
|
||||
}
|
||||
|
||||
|
|
@ -857,19 +857,19 @@ impl<'tcx> Ty<'tcx> {
|
|||
|
||||
#[inline]
|
||||
pub fn new_box(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
let def_id = tcx.require_lang_item(LangItem::OwnedBox, None);
|
||||
let def_id = tcx.require_lang_item(LangItem::OwnedBox, DUMMY_SP);
|
||||
Ty::new_generic_adt(tcx, def_id, ty)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn new_maybe_uninit(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
let def_id = tcx.require_lang_item(LangItem::MaybeUninit, None);
|
||||
let def_id = tcx.require_lang_item(LangItem::MaybeUninit, DUMMY_SP);
|
||||
Ty::new_generic_adt(tcx, def_id, ty)
|
||||
}
|
||||
|
||||
/// Creates a `&mut Context<'_>` [`Ty`] with erased lifetimes.
|
||||
pub fn new_task_context(tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
let context_did = tcx.require_lang_item(LangItem::Context, None);
|
||||
let context_did = tcx.require_lang_item(LangItem::Context, DUMMY_SP);
|
||||
let context_adt_ref = tcx.adt_def(context_did);
|
||||
let context_args = tcx.mk_args(&[tcx.lifetimes.re_erased.into()]);
|
||||
let context_ty = Ty::new_adt(tcx, context_adt_ref, context_args);
|
||||
|
|
@ -1549,7 +1549,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
|
||||
ty::Param(_) | ty::Alias(..) | ty::Infer(ty::TyVar(_)) => {
|
||||
let assoc_items = tcx.associated_item_def_ids(
|
||||
tcx.require_lang_item(hir::LangItem::DiscriminantKind, None),
|
||||
tcx.require_lang_item(hir::LangItem::DiscriminantKind, DUMMY_SP),
|
||||
);
|
||||
Ty::new_projection_from_args(tcx, assoc_items[0], tcx.mk_args(&[self.into()]))
|
||||
}
|
||||
|
|
@ -1629,7 +1629,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
ty::Str | ty::Slice(_) => Ok(tcx.types.usize),
|
||||
|
||||
ty::Dynamic(_, _, ty::Dyn) => {
|
||||
let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None);
|
||||
let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, DUMMY_SP);
|
||||
Ok(tcx.type_of(dyn_metadata).instantiate(tcx, &[tail.into()]))
|
||||
}
|
||||
|
||||
|
|
@ -1683,7 +1683,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
match pointee_ty.ptr_metadata_ty_or_tail(tcx, |x| x) {
|
||||
Ok(metadata_ty) => metadata_ty,
|
||||
Err(tail_ty) => {
|
||||
let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None);
|
||||
let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, DUMMY_SP);
|
||||
Ty::new_projection(tcx, metadata_def_id, [tail_ty])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ pub struct TypeckResults<'tcx> {
|
|||
|
||||
/// Tracks the rvalue scoping rules which defines finer scoping for rvalue expressions
|
||||
/// by applying extended parameter rules.
|
||||
/// Details may be find in `rustc_hir_analysis::check::rvalue_scopes`.
|
||||
/// Details may be found in `rustc_hir_analysis::check::rvalue_scopes`.
|
||||
pub rvalue_scopes: RvalueScopes,
|
||||
|
||||
/// Stores the predicates that apply on coroutine witness types.
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// malloc some memory of suitable size and align:
|
||||
let exchange_malloc = Operand::function_handle(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::ExchangeMalloc, Some(expr_span)),
|
||||
tcx.require_lang_item(LangItem::ExchangeMalloc, expr_span),
|
||||
[],
|
||||
expr_span,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -307,7 +307,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
} else if this.infcx.type_is_use_cloned_modulo_regions(this.param_env, ty) {
|
||||
// Convert `expr.use` to a call like `Clone::clone(&expr)`
|
||||
let success = this.cfg.start_new_block();
|
||||
let clone_trait = this.tcx.require_lang_item(LangItem::Clone, None);
|
||||
let clone_trait = this.tcx.require_lang_item(LangItem::Clone, span);
|
||||
let clone_fn = this.tcx.associated_item_def_ids(clone_trait)[0];
|
||||
let func = Operand::function_handle(this.tcx, clone_fn, [ty.into()], expr_span);
|
||||
let ref_ty = Ty::new_imm_ref(this.tcx, this.tcx.lifetimes.re_erased, ty);
|
||||
|
|
|
|||
|
|
@ -364,7 +364,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let borrow_kind = super::util::ref_pat_borrow_kind(mutability);
|
||||
let source_info = self.source_info(span);
|
||||
let re_erased = self.tcx.lifetimes.re_erased;
|
||||
let trait_item = self.tcx.require_lang_item(trait_item, None);
|
||||
let trait_item = self.tcx.require_lang_item(trait_item, span);
|
||||
let method = trait_method(self.tcx, trait_item, method, [ty]);
|
||||
let ref_src = self.temp(Ty::new_ref(self.tcx, re_erased, ty, mutability), span);
|
||||
// `let ref_src = &src_place;`
|
||||
|
|
@ -437,7 +437,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
val: Operand<'tcx>,
|
||||
) {
|
||||
let str_ty = self.tcx.types.str_;
|
||||
let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span));
|
||||
let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, source_info.span);
|
||||
let method = trait_method(self.tcx, eq_def_id, sym::eq, [str_ty, str_ty]);
|
||||
|
||||
let bool_ty = self.tcx.types.bool;
|
||||
|
|
|
|||
|
|
@ -38,7 +38,10 @@ impl<'tcx> ThirBuildCx<'tcx> {
|
|||
}
|
||||
|
||||
pub(crate) fn mirror_exprs(&mut self, exprs: &'tcx [hir::Expr<'tcx>]) -> Box<[ExprId]> {
|
||||
exprs.iter().map(|expr| self.mirror_expr_inner(expr)).collect()
|
||||
// `mirror_exprs` may also recurse deeply, so it needs protection from stack overflow.
|
||||
// Note that we *could* forward to `mirror_expr` for that, but we can consolidate the
|
||||
// overhead of stack growth by doing it outside the iteration.
|
||||
ensure_sufficient_stack(|| exprs.iter().map(|expr| self.mirror_expr_inner(expr)).collect())
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self, hir_expr))]
|
||||
|
|
@ -220,7 +223,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
|
|||
});
|
||||
|
||||
// kind = Pin { __pointer: pointer }
|
||||
let pin_did = self.tcx.require_lang_item(rustc_hir::LangItem::Pin, Some(span));
|
||||
let pin_did = self.tcx.require_lang_item(rustc_hir::LangItem::Pin, span);
|
||||
let args = self.tcx.mk_args(&[new_pin_target.into()]);
|
||||
let kind = ExprKind::Adt(Box::new(AdtExpr {
|
||||
adt_def: self.tcx.adt_def(pin_did),
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
|
|||
// C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
|
||||
// (as it's created inside the body itself, not passed in from outside).
|
||||
let ty = if fn_decl.c_variadic && index == fn_decl.inputs.len() {
|
||||
let va_list_did = self.tcx.require_lang_item(LangItem::VaList, Some(param.span));
|
||||
let va_list_did = self.tcx.require_lang_item(LangItem::VaList, param.span);
|
||||
|
||||
self.tcx
|
||||
.type_of(va_list_did)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use rustc_middle::ty::{
|
|||
};
|
||||
use rustc_middle::{mir, span_bug};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::{Span, sym};
|
||||
use rustc_span::{DUMMY_SP, Span, sym};
|
||||
use rustc_trait_selection::traits::ObligationCause;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use tracing::{debug, instrument, trace};
|
||||
|
|
@ -480,8 +480,9 @@ fn type_has_partial_eq_impl<'tcx>(
|
|||
// (If there isn't, then we can safely issue a hard
|
||||
// error, because that's never worked, due to compiler
|
||||
// using `PartialEq::eq` in this scenario in the past.)
|
||||
let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, None);
|
||||
let structural_partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::StructuralPeq, None);
|
||||
let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, DUMMY_SP);
|
||||
let structural_partial_eq_trait_id =
|
||||
tcx.require_lang_item(hir::LangItem::StructuralPeq, DUMMY_SP);
|
||||
|
||||
let partial_eq_obligation = Obligation::new(
|
||||
tcx,
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ impl<'tcx> TransformVisitor<'tcx> {
|
|||
CoroutineKind::Coroutine(_) => span_bug!(body.span, "`Coroutine`s cannot be fused"),
|
||||
// `gen` continues return `None`
|
||||
CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
|
||||
let option_def_id = self.tcx.require_lang_item(LangItem::Option, None);
|
||||
let option_def_id = self.tcx.require_lang_item(LangItem::Option, body.span);
|
||||
make_aggregate_adt(
|
||||
option_def_id,
|
||||
VariantIdx::ZERO,
|
||||
|
|
@ -242,7 +242,7 @@ impl<'tcx> TransformVisitor<'tcx> {
|
|||
span: source_info.span,
|
||||
const_: Const::Unevaluated(
|
||||
UnevaluatedConst::new(
|
||||
self.tcx.require_lang_item(LangItem::AsyncGenFinished, None),
|
||||
self.tcx.require_lang_item(LangItem::AsyncGenFinished, body.span),
|
||||
self.tcx.mk_args(&[yield_ty.into()]),
|
||||
),
|
||||
self.old_yield_ty,
|
||||
|
|
@ -282,7 +282,7 @@ impl<'tcx> TransformVisitor<'tcx> {
|
|||
const ONE: VariantIdx = VariantIdx::from_usize(1);
|
||||
let rvalue = match self.coroutine_kind {
|
||||
CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => {
|
||||
let poll_def_id = self.tcx.require_lang_item(LangItem::Poll, None);
|
||||
let poll_def_id = self.tcx.require_lang_item(LangItem::Poll, source_info.span);
|
||||
let args = self.tcx.mk_args(&[self.old_ret_ty.into()]);
|
||||
let (variant_idx, operands) = if is_return {
|
||||
(ZERO, IndexVec::from_raw(vec![val])) // Poll::Ready(val)
|
||||
|
|
@ -292,7 +292,7 @@ impl<'tcx> TransformVisitor<'tcx> {
|
|||
make_aggregate_adt(poll_def_id, variant_idx, args, operands)
|
||||
}
|
||||
CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
|
||||
let option_def_id = self.tcx.require_lang_item(LangItem::Option, None);
|
||||
let option_def_id = self.tcx.require_lang_item(LangItem::Option, source_info.span);
|
||||
let args = self.tcx.mk_args(&[self.old_yield_ty.into()]);
|
||||
let (variant_idx, operands) = if is_return {
|
||||
(ZERO, IndexVec::new()) // None
|
||||
|
|
@ -310,7 +310,10 @@ impl<'tcx> TransformVisitor<'tcx> {
|
|||
span: source_info.span,
|
||||
const_: Const::Unevaluated(
|
||||
UnevaluatedConst::new(
|
||||
self.tcx.require_lang_item(LangItem::AsyncGenFinished, None),
|
||||
self.tcx.require_lang_item(
|
||||
LangItem::AsyncGenFinished,
|
||||
source_info.span,
|
||||
),
|
||||
self.tcx.mk_args(&[yield_ty.into()]),
|
||||
),
|
||||
self.old_yield_ty,
|
||||
|
|
@ -323,7 +326,7 @@ impl<'tcx> TransformVisitor<'tcx> {
|
|||
}
|
||||
CoroutineKind::Coroutine(_) => {
|
||||
let coroutine_state_def_id =
|
||||
self.tcx.require_lang_item(LangItem::CoroutineState, None);
|
||||
self.tcx.require_lang_item(LangItem::CoroutineState, source_info.span);
|
||||
let args = self.tcx.mk_args(&[self.old_yield_ty.into(), self.old_ret_ty.into()]);
|
||||
let variant_idx = if is_return {
|
||||
ONE // CoroutineState::Complete(val)
|
||||
|
|
@ -496,7 +499,7 @@ fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Bo
|
|||
fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let ref_coroutine_ty = body.local_decls.raw[1].ty;
|
||||
|
||||
let pin_did = tcx.require_lang_item(LangItem::Pin, Some(body.span));
|
||||
let pin_did = tcx.require_lang_item(LangItem::Pin, body.span);
|
||||
let pin_adt_ref = tcx.adt_def(pin_did);
|
||||
let args = tcx.mk_args(&[ref_coroutine_ty.into()]);
|
||||
let pin_ref_coroutine_ty = Ty::new_adt(tcx, pin_adt_ref, args);
|
||||
|
|
@ -557,7 +560,7 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> Ty
|
|||
// replace the type of the `resume` argument
|
||||
replace_resume_ty_local(tcx, body, CTX_ARG, context_mut_ref);
|
||||
|
||||
let get_context_def_id = tcx.require_lang_item(LangItem::GetContext, None);
|
||||
let get_context_def_id = tcx.require_lang_item(LangItem::GetContext, body.span);
|
||||
|
||||
for bb in body.basic_blocks.indices() {
|
||||
let bb_data = &body[bb];
|
||||
|
|
@ -618,7 +621,7 @@ fn replace_resume_ty_local<'tcx>(
|
|||
#[cfg(debug_assertions)]
|
||||
{
|
||||
if let ty::Adt(resume_ty_adt, _) = local_ty.kind() {
|
||||
let expected_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, None));
|
||||
let expected_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, body.span));
|
||||
assert_eq!(*resume_ty_adt, expected_adt);
|
||||
} else {
|
||||
panic!("expected `ResumeTy`, found `{:?}`", local_ty);
|
||||
|
|
@ -1095,7 +1098,7 @@ fn insert_term_block<'tcx>(body: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) ->
|
|||
|
||||
fn return_poll_ready_assign<'tcx>(tcx: TyCtxt<'tcx>, source_info: SourceInfo) -> Statement<'tcx> {
|
||||
// Poll::Ready(())
|
||||
let poll_def_id = tcx.require_lang_item(LangItem::Poll, None);
|
||||
let poll_def_id = tcx.require_lang_item(LangItem::Poll, source_info.span);
|
||||
let args = tcx.mk_args(&[tcx.types.unit.into()]);
|
||||
let val = Operand::Constant(Box::new(ConstOperand {
|
||||
span: source_info.span,
|
||||
|
|
@ -1437,7 +1440,7 @@ fn check_field_tys_sized<'tcx>(
|
|||
),
|
||||
param_env,
|
||||
field_ty.ty,
|
||||
tcx.require_lang_item(hir::LangItem::Sized, Some(field_ty.source_info.span)),
|
||||
tcx.require_lang_item(hir::LangItem::Sized, field_ty.source_info.span),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -1473,14 +1476,14 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform {
|
|||
let new_ret_ty = match coroutine_kind {
|
||||
CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => {
|
||||
// Compute Poll<return_ty>
|
||||
let poll_did = tcx.require_lang_item(LangItem::Poll, None);
|
||||
let poll_did = tcx.require_lang_item(LangItem::Poll, body.span);
|
||||
let poll_adt_ref = tcx.adt_def(poll_did);
|
||||
let poll_args = tcx.mk_args(&[old_ret_ty.into()]);
|
||||
Ty::new_adt(tcx, poll_adt_ref, poll_args)
|
||||
}
|
||||
CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
|
||||
// Compute Option<yield_ty>
|
||||
let option_did = tcx.require_lang_item(LangItem::Option, None);
|
||||
let option_did = tcx.require_lang_item(LangItem::Option, body.span);
|
||||
let option_adt_ref = tcx.adt_def(option_did);
|
||||
let option_args = tcx.mk_args(&[old_yield_ty.into()]);
|
||||
Ty::new_adt(tcx, option_adt_ref, option_args)
|
||||
|
|
@ -1491,7 +1494,7 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform {
|
|||
}
|
||||
CoroutineKind::Coroutine(_) => {
|
||||
// Compute CoroutineState<yield_ty, return_ty>
|
||||
let state_did = tcx.require_lang_item(LangItem::CoroutineState, None);
|
||||
let state_did = tcx.require_lang_item(LangItem::CoroutineState, body.span);
|
||||
let state_adt_ref = tcx.adt_def(state_did);
|
||||
let state_args = tcx.mk_args(&[old_yield_ty.into(), old_ret_ty.into()]);
|
||||
Ty::new_adt(tcx, state_adt_ref, state_args)
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ fn build_poll_call<'tcx>(
|
|||
context_ref_place: &Place<'tcx>,
|
||||
unwind: UnwindAction,
|
||||
) -> BasicBlock {
|
||||
let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, None);
|
||||
let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, DUMMY_SP);
|
||||
let poll_fn = Ty::new_fn_def(tcx, poll_fn, [fut_ty]);
|
||||
let poll_fn = Operand::Constant(Box::new(ConstOperand {
|
||||
span: DUMMY_SP,
|
||||
|
|
@ -77,11 +77,8 @@ fn build_pin_fut<'tcx>(
|
|||
let fut_ty = fut_place.ty(&body.local_decls, tcx).ty;
|
||||
let fut_ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, fut_ty);
|
||||
let fut_ref_place = Place::from(body.local_decls.push(LocalDecl::new(fut_ref_ty, span)));
|
||||
let pin_fut_new_unchecked_fn = Ty::new_fn_def(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::PinNewUnchecked, Some(span)),
|
||||
[fut_ref_ty],
|
||||
);
|
||||
let pin_fut_new_unchecked_fn =
|
||||
Ty::new_fn_def(tcx, tcx.require_lang_item(LangItem::PinNewUnchecked, span), [fut_ref_ty]);
|
||||
let fut_pin_ty = pin_fut_new_unchecked_fn.fn_sig(tcx).output().skip_binder();
|
||||
let fut_pin_place = Place::from(body.local_decls.push(LocalDecl::new(fut_pin_ty, span)));
|
||||
let pin_fut_new_unchecked_fn = Operand::Constant(Box::new(ConstOperand {
|
||||
|
|
@ -143,13 +140,15 @@ fn build_poll_switch<'tcx>(
|
|||
let Discr { val: poll_ready_discr, ty: poll_discr_ty } = poll_enum
|
||||
.discriminant_for_variant(
|
||||
tcx,
|
||||
poll_enum_adt.variant_index_with_id(tcx.require_lang_item(LangItem::PollReady, None)),
|
||||
poll_enum_adt
|
||||
.variant_index_with_id(tcx.require_lang_item(LangItem::PollReady, DUMMY_SP)),
|
||||
)
|
||||
.unwrap();
|
||||
let poll_pending_discr = poll_enum
|
||||
.discriminant_for_variant(
|
||||
tcx,
|
||||
poll_enum_adt.variant_index_with_id(tcx.require_lang_item(LangItem::PollPending, None)),
|
||||
poll_enum_adt
|
||||
.variant_index_with_id(tcx.require_lang_item(LangItem::PollPending, DUMMY_SP)),
|
||||
)
|
||||
.unwrap()
|
||||
.val;
|
||||
|
|
@ -316,16 +315,17 @@ pub(super) fn expand_async_drops<'tcx>(
|
|||
// pending => return rv (yield)
|
||||
// ready => *continue_bb|drop_bb*
|
||||
|
||||
let source_info = body[bb].terminator.as_ref().unwrap().source_info;
|
||||
|
||||
// Compute Poll<> (aka Poll with void return)
|
||||
let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None));
|
||||
let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, source_info.span));
|
||||
let poll_enum = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()]));
|
||||
let poll_decl = LocalDecl::new(poll_enum, body.span);
|
||||
let poll_decl = LocalDecl::new(poll_enum, source_info.span);
|
||||
let poll_unit_place = Place::from(body.local_decls.push(poll_decl));
|
||||
|
||||
// First state-loop yield for mainline
|
||||
let context_ref_place =
|
||||
Place::from(body.local_decls.push(LocalDecl::new(context_mut_ref, body.span)));
|
||||
let source_info = body[bb].terminator.as_ref().unwrap().source_info;
|
||||
Place::from(body.local_decls.push(LocalDecl::new(context_mut_ref, source_info.span)));
|
||||
let arg = Rvalue::Use(Operand::Move(Place::from(CTX_ARG)));
|
||||
body[bb].statements.push(Statement {
|
||||
source_info,
|
||||
|
|
@ -353,8 +353,9 @@ pub(super) fn expand_async_drops<'tcx>(
|
|||
let mut dropline_context_ref: Option<Place<'_>> = None;
|
||||
let mut dropline_call_bb: Option<BasicBlock> = None;
|
||||
if !is_dropline_bb {
|
||||
let context_ref_place2: Place<'_> =
|
||||
Place::from(body.local_decls.push(LocalDecl::new(context_mut_ref, body.span)));
|
||||
let context_ref_place2: Place<'_> = Place::from(
|
||||
body.local_decls.push(LocalDecl::new(context_mut_ref, source_info.span)),
|
||||
);
|
||||
let drop_yield_block = insert_term_block(body, TerminatorKind::Unreachable); // `kind` replaced later to yield
|
||||
let drop_switch_block = build_poll_switch(
|
||||
tcx,
|
||||
|
|
@ -394,7 +395,7 @@ pub(super) fn expand_async_drops<'tcx>(
|
|||
span: source_info.span,
|
||||
const_: Const::Unevaluated(
|
||||
UnevaluatedConst::new(
|
||||
tcx.require_lang_item(LangItem::AsyncGenPending, None),
|
||||
tcx.require_lang_item(LangItem::AsyncGenPending, source_info.span),
|
||||
tcx.mk_args(&[yield_ty.into()]),
|
||||
),
|
||||
full_yield_ty,
|
||||
|
|
@ -404,7 +405,7 @@ pub(super) fn expand_async_drops<'tcx>(
|
|||
} else {
|
||||
// value needed only for return-yields or gen-coroutines, so just const here
|
||||
Operand::Constant(Box::new(ConstOperand {
|
||||
span: body.span,
|
||||
span: source_info.span,
|
||||
user_ty: None,
|
||||
const_: Const::from_bool(tcx, false),
|
||||
}))
|
||||
|
|
@ -595,7 +596,7 @@ pub(super) fn create_coroutine_drop_shim<'tcx>(
|
|||
|
||||
// Update the body's def to become the drop glue.
|
||||
let coroutine_instance = body.source.instance;
|
||||
let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, None);
|
||||
let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, body.span);
|
||||
let drop_instance = InstanceKind::DropGlue(drop_in_place, Some(coroutine_ty));
|
||||
|
||||
// Temporary change MirSource to coroutine's instance so that dump_mir produces more sensible
|
||||
|
|
@ -666,7 +667,7 @@ pub(super) fn create_coroutine_drop_shim_async<'tcx>(
|
|||
}
|
||||
|
||||
// Replace the return variable: Poll<RetT> to Poll<()>
|
||||
let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None));
|
||||
let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, body.span));
|
||||
let poll_enum = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()]));
|
||||
body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(poll_enum, source_info);
|
||||
|
||||
|
|
@ -717,7 +718,7 @@ pub(super) fn create_coroutine_drop_shim_proxy_async<'tcx>(
|
|||
let source_info = SourceInfo::outermost(body.span);
|
||||
|
||||
// Replace the return variable: Poll<RetT> to Poll<()>
|
||||
let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None));
|
||||
let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, body.span));
|
||||
let poll_enum = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()]));
|
||||
body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(poll_enum, source_info);
|
||||
|
||||
|
|
|
|||
|
|
@ -616,7 +616,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
|
|||
place,
|
||||
operand,
|
||||
&mut |elem, op| match elem {
|
||||
TrackElem::Field(idx) => self.ecx.project_field(op, idx.as_usize()).discard_err(),
|
||||
TrackElem::Field(idx) => self.ecx.project_field(op, idx).discard_err(),
|
||||
TrackElem::Variant(idx) => self.ecx.project_downcast(op, idx).discard_err(),
|
||||
TrackElem::Discriminant => {
|
||||
let variant = self.ecx.read_discriminant(op).discard_err()?;
|
||||
|
|
@ -890,7 +890,8 @@ fn try_write_constant<'tcx>(
|
|||
|
||||
ty::Tuple(elem_tys) => {
|
||||
for (i, elem) in elem_tys.iter().enumerate() {
|
||||
let Some(field) = map.apply(place, TrackElem::Field(FieldIdx::from_usize(i))) else {
|
||||
let i = FieldIdx::from_usize(i);
|
||||
let Some(field) = map.apply(place, TrackElem::Field(i)) else {
|
||||
throw_machine_stop_str!("missing field in tuple")
|
||||
};
|
||||
let field_dest = ecx.project_field(dest, i)?;
|
||||
|
|
@ -928,7 +929,7 @@ fn try_write_constant<'tcx>(
|
|||
let Some(field) = map.apply(variant_place, TrackElem::Field(i)) else {
|
||||
throw_machine_stop_str!("missing field in ADT")
|
||||
};
|
||||
let field_dest = ecx.project_field(&variant_dest, i.as_usize())?;
|
||||
let field_dest = ecx.project_field(&variant_dest, i)?;
|
||||
try_write_constant(ecx, &field_dest, field, ty, state, map)?;
|
||||
}
|
||||
ecx.write_discriminant(variant_idx, dest)?;
|
||||
|
|
|
|||
|
|
@ -235,11 +235,8 @@ where
|
|||
|
||||
let (fut_ty, drop_fn_def_id, trait_args) = if call_destructor_only {
|
||||
// Resolving obj.<AsyncDrop::drop>()
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::AsyncDrop, Some(span)),
|
||||
[drop_ty],
|
||||
);
|
||||
let trait_ref =
|
||||
ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::AsyncDrop, span), [drop_ty]);
|
||||
let (drop_trait, trait_args) = match tcx.codegen_select_candidate(
|
||||
ty::TypingEnv::fully_monomorphized().as_query_input(trait_ref),
|
||||
) {
|
||||
|
|
@ -292,7 +289,7 @@ where
|
|||
(sig.output(), drop_fn_def_id, trait_args)
|
||||
} else {
|
||||
// Resolving async_drop_in_place<T> function for drop_ty
|
||||
let drop_fn_def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, Some(span));
|
||||
let drop_fn_def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, span);
|
||||
let trait_args = tcx.mk_args(&[drop_ty.into()]);
|
||||
let sig = tcx.fn_sig(drop_fn_def_id).instantiate(tcx, trait_args);
|
||||
let sig = tcx.instantiate_bound_regions_with_erased(sig);
|
||||
|
|
@ -319,7 +316,7 @@ where
|
|||
// pin_obj_place preparation
|
||||
let pin_obj_new_unchecked_fn = Ty::new_fn_def(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::PinNewUnchecked, Some(span)),
|
||||
tcx.require_lang_item(LangItem::PinNewUnchecked, span),
|
||||
[GenericArg::from(obj_ref_ty)],
|
||||
);
|
||||
let pin_obj_ty = pin_obj_new_unchecked_fn.fn_sig(tcx).output().no_bound_vars().unwrap();
|
||||
|
|
@ -937,7 +934,7 @@ where
|
|||
fn destructor_call_block_sync(&mut self, (succ, unwind): (BasicBlock, Unwind)) -> BasicBlock {
|
||||
debug!("destructor_call_block_sync({:?}, {:?})", self, succ);
|
||||
let tcx = self.tcx();
|
||||
let drop_trait = tcx.require_lang_item(LangItem::Drop, None);
|
||||
let drop_trait = tcx.require_lang_item(LangItem::Drop, DUMMY_SP);
|
||||
let drop_fn = tcx.associated_item_def_ids(drop_trait)[0];
|
||||
let ty = self.place_ty(self.place);
|
||||
|
||||
|
|
|
|||
|
|
@ -438,8 +438,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
dest.clone()
|
||||
};
|
||||
for (field_index, op) in fields.into_iter().enumerate() {
|
||||
let field_dest =
|
||||
self.ecx.project_field(&variant_dest, field_index).discard_err()?;
|
||||
let field_dest = self
|
||||
.ecx
|
||||
.project_field(&variant_dest, FieldIdx::from_usize(field_index))
|
||||
.discard_err()?;
|
||||
self.ecx.copy_op(op, &field_dest).discard_err()?;
|
||||
}
|
||||
self.ecx
|
||||
|
|
@ -1583,7 +1585,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
// We needed to check the variant to avoid trying to read the tag
|
||||
// field from an enum where no fields have variants, since that tag
|
||||
// field isn't in the `Aggregate` from which we're getting values.
|
||||
Some((FieldIdx::from_usize(field_idx), field_layout.ty))
|
||||
Some((field_idx, field_layout.ty))
|
||||
} else if let ty::Adt(adt, args) = ty.kind()
|
||||
&& adt.is_struct()
|
||||
&& adt.repr().transparent()
|
||||
|
|
|
|||
|
|
@ -388,7 +388,7 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> {
|
|||
lhs,
|
||||
constant,
|
||||
&mut |elem, op| match elem {
|
||||
TrackElem::Field(idx) => self.ecx.project_field(op, idx.as_usize()).discard_err(),
|
||||
TrackElem::Field(idx) => self.ecx.project_field(op, idx).discard_err(),
|
||||
TrackElem::Variant(idx) => self.ecx.project_downcast(op, idx).discard_err(),
|
||||
TrackElem::Discriminant => {
|
||||
let variant = self.ecx.read_discriminant(op).discard_err()?;
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<
|
|||
build_call_shim(tcx, instance, None, CallKind::Direct(def_id))
|
||||
}
|
||||
ty::InstanceKind::ClosureOnceShim { call_once: _, track_caller: _ } => {
|
||||
let fn_mut = tcx.require_lang_item(LangItem::FnMut, None);
|
||||
let fn_mut = tcx.require_lang_item(LangItem::FnMut, DUMMY_SP);
|
||||
let call_mut = tcx
|
||||
.associated_items(fn_mut)
|
||||
.in_definition_order()
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ pub(super) fn build_async_drop_shim<'tcx>(
|
|||
let needs_async_drop = drop_ty.needs_async_drop(tcx, typing_env);
|
||||
let needs_sync_drop = !needs_async_drop && drop_ty.needs_drop(tcx, typing_env);
|
||||
|
||||
let resume_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, None));
|
||||
let resume_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, DUMMY_SP));
|
||||
let resume_ty = Ty::new_adt(tcx, resume_adt, ty::List::empty());
|
||||
|
||||
let fn_sig = ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
|
|
@ -220,7 +220,7 @@ fn build_adrop_for_coroutine_shim<'tcx>(
|
|||
body.source.instance = instance;
|
||||
body.phase = MirPhase::Runtime(RuntimePhase::Initial);
|
||||
body.var_debug_info.clear();
|
||||
let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, Some(span)));
|
||||
let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, span));
|
||||
let args = tcx.mk_args(&[proxy_ref.into()]);
|
||||
let pin_proxy_ref = Ty::new_adt(tcx, pin_adt_ref, args);
|
||||
|
||||
|
|
@ -308,10 +308,10 @@ fn build_adrop_for_adrop_shim<'tcx>(
|
|||
let cor_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, impl_ty);
|
||||
|
||||
// ret_ty = `Poll<()>`
|
||||
let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None));
|
||||
let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, span));
|
||||
let ret_ty = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()]));
|
||||
// env_ty = `Pin<&mut proxy_ty>`
|
||||
let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, None));
|
||||
let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, span));
|
||||
let env_ty = Ty::new_adt(tcx, pin_adt_ref, tcx.mk_args(&[proxy_ref.into()]));
|
||||
// sig = `fn (Pin<&mut proxy_ty>, &mut Context) -> Poll<()>`
|
||||
let sig = tcx.mk_fn_sig(
|
||||
|
|
@ -376,7 +376,7 @@ fn build_adrop_for_adrop_shim<'tcx>(
|
|||
let cor_pin_ty = Ty::new_adt(tcx, pin_adt_ref, tcx.mk_args(&[cor_ref.into()]));
|
||||
let cor_pin_place = Place::from(locals.push(LocalDecl::new(cor_pin_ty, span)));
|
||||
|
||||
let pin_fn = tcx.require_lang_item(LangItem::PinNewUnchecked, Some(span));
|
||||
let pin_fn = tcx.require_lang_item(LangItem::PinNewUnchecked, span);
|
||||
// call Pin<FutTy>::new_unchecked(&mut impl_cor)
|
||||
blocks.push(BasicBlockData {
|
||||
statements,
|
||||
|
|
@ -396,7 +396,7 @@ fn build_adrop_for_adrop_shim<'tcx>(
|
|||
});
|
||||
// When dropping async drop coroutine, we continue its execution:
|
||||
// we call impl::poll (impl_layout, ctx)
|
||||
let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, None);
|
||||
let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, span);
|
||||
let resume_ctx = Place::from(Local::new(2));
|
||||
blocks.push(BasicBlockData {
|
||||
statements: vec![],
|
||||
|
|
|
|||
|
|
@ -1253,7 +1253,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
self.tcx,
|
||||
self.tcx.require_lang_item(
|
||||
LangItem::CoerceUnsized,
|
||||
Some(self.body.source_info(location).span),
|
||||
self.body.source_info(location).span,
|
||||
),
|
||||
[op_ty, *target_type],
|
||||
)) {
|
||||
|
|
|
|||
|
|
@ -781,7 +781,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
|
|||
|
||||
let tcx = self.tcx;
|
||||
let push_mono_lang_item = |this: &mut Self, lang_item: LangItem| {
|
||||
let instance = Instance::mono(tcx, tcx.require_lang_item(lang_item, Some(source)));
|
||||
let instance = Instance::mono(tcx, tcx.require_lang_item(lang_item, source));
|
||||
if tcx.should_codegen_locally(instance) {
|
||||
this.used_items.push(create_fn_mono_item(tcx, instance, source));
|
||||
}
|
||||
|
|
@ -921,7 +921,7 @@ fn visit_instance_use<'tcx>(
|
|||
// be lowered in codegen to nothing or a call to panic_nounwind. So if we encounter any
|
||||
// of those intrinsics, we need to include a mono item for panic_nounwind, else we may try to
|
||||
// codegen a call to that function without generating code for the function itself.
|
||||
let def_id = tcx.require_lang_item(LangItem::PanicNounwind, None);
|
||||
let def_id = tcx.require_lang_item(LangItem::PanicNounwind, source);
|
||||
let panic_instance = Instance::mono(tcx, def_id);
|
||||
if tcx.should_codegen_locally(panic_instance) {
|
||||
output.push(create_fn_mono_item(tcx, panic_instance, source));
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue