Auto merge of #121131 - matthiaskrgr:rollup-mo3b8nz, r=matthiaskrgr
Rollup of 10 pull requests Successful merges: - #111106 (Add known issue of let binding to format_args doc) - #118749 (Make contributing to windows bindings easier) - #120982 (Add APIs for fetching foreign items ) - #121022 (rustdoc: cross-crate re-exports: correctly render late-bound params in source order even if early-bound params are present) - #121082 (Clarified docs on non-atomic oprations on owned/mut refs to atomics) - #121084 (Make sure `tcx.create_def` also depends on the forever red node, instead of just `tcx.at(span).create_def`) - #121098 (Remove unnecessary else block from `thread_local!` expanded code) - #121105 (Do not report overflow errors on ConstArgHasType goals) - #121116 (Reinstate some delayed bugs.) - #121122 (Enforce coroutine-closure layouts are identical) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
4ae1e79876
@ -4588,6 +4588,7 @@ dependencies = [
|
|||||||
"rustc_data_structures",
|
"rustc_data_structures",
|
||||||
"rustc_hir",
|
"rustc_hir",
|
||||||
"rustc_middle",
|
"rustc_middle",
|
||||||
|
"rustc_session",
|
||||||
"rustc_span",
|
"rustc_span",
|
||||||
"rustc_target",
|
"rustc_target",
|
||||||
"scoped-tls",
|
"scoped-tls",
|
||||||
|
@ -323,7 +323,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
|
ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
|
||||||
ExprKind::Err => hir::ExprKind::Err(self.dcx().has_errors().unwrap()),
|
ExprKind::Err => {
|
||||||
|
hir::ExprKind::Err(self.dcx().span_delayed_bug(e.span, "lowered ExprKind::Err"))
|
||||||
|
}
|
||||||
ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr),
|
ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr),
|
||||||
|
|
||||||
ExprKind::Paren(_) | ExprKind::ForLoop { .. } => {
|
ExprKind::Paren(_) | ExprKind::ForLoop { .. } => {
|
||||||
|
@ -98,6 +98,26 @@ impl<'tcx> MirPass<'tcx> for Validator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enforce that coroutine-closure layouts are identical.
|
||||||
|
if let Some(layout) = body.coroutine_layout()
|
||||||
|
&& let Some(by_move_body) = body.coroutine_by_move_body()
|
||||||
|
&& let Some(by_move_layout) = by_move_body.coroutine_layout()
|
||||||
|
{
|
||||||
|
if layout != by_move_layout {
|
||||||
|
// If this turns out not to be true, please let compiler-errors know.
|
||||||
|
// It is possible to support, but requires some changes to the layout
|
||||||
|
// computation code.
|
||||||
|
cfg_checker.fail(
|
||||||
|
Location::START,
|
||||||
|
format!(
|
||||||
|
"Coroutine layout differs from by-move coroutine layout:\n\
|
||||||
|
layout: {layout:#?}\n\
|
||||||
|
by_move_layout: {by_move_layout:#?}",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,8 @@ rustc_index::newtype_index! {
|
|||||||
pub struct CoroutineSavedLocal {}
|
pub struct CoroutineSavedLocal {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
|
||||||
pub struct CoroutineSavedTy<'tcx> {
|
pub struct CoroutineSavedTy<'tcx> {
|
||||||
pub ty: Ty<'tcx>,
|
pub ty: Ty<'tcx>,
|
||||||
/// Source info corresponding to the local in the original MIR body.
|
/// Source info corresponding to the local in the original MIR body.
|
||||||
@ -96,7 +97,8 @@ pub struct CoroutineSavedTy<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The layout of coroutine state.
|
/// The layout of coroutine state.
|
||||||
#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
|
#[derive(Clone, PartialEq, Eq)]
|
||||||
|
#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
|
||||||
pub struct CoroutineLayout<'tcx> {
|
pub struct CoroutineLayout<'tcx> {
|
||||||
/// The type of every local stored inside the coroutine.
|
/// The type of every local stored inside the coroutine.
|
||||||
pub field_tys: IndexVec<CoroutineSavedLocal, CoroutineSavedTy<'tcx>>,
|
pub field_tys: IndexVec<CoroutineSavedLocal, CoroutineSavedTy<'tcx>>,
|
||||||
|
@ -1053,6 +1053,22 @@ impl<'tcx> TyCtxtAt<'tcx> {
|
|||||||
name: Symbol,
|
name: Symbol,
|
||||||
def_kind: DefKind,
|
def_kind: DefKind,
|
||||||
) -> TyCtxtFeed<'tcx, LocalDefId> {
|
) -> TyCtxtFeed<'tcx, LocalDefId> {
|
||||||
|
let feed = self.tcx.create_def(parent, name, def_kind);
|
||||||
|
|
||||||
|
feed.def_span(self.span);
|
||||||
|
feed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> TyCtxt<'tcx> {
|
||||||
|
/// `tcx`-dependent operations performed for every created definition.
|
||||||
|
pub fn create_def(
|
||||||
|
self,
|
||||||
|
parent: LocalDefId,
|
||||||
|
name: Symbol,
|
||||||
|
def_kind: DefKind,
|
||||||
|
) -> TyCtxtFeed<'tcx, LocalDefId> {
|
||||||
|
let data = def_kind.def_path_data(name);
|
||||||
// The following call has the side effect of modifying the tables inside `definitions`.
|
// The following call has the side effect of modifying the tables inside `definitions`.
|
||||||
// These very tables are relied on by the incr. comp. engine to decode DepNodes and to
|
// These very tables are relied on by the incr. comp. engine to decode DepNodes and to
|
||||||
// decode the on-disk cache.
|
// decode the on-disk cache.
|
||||||
@ -1067,18 +1083,6 @@ impl<'tcx> TyCtxtAt<'tcx> {
|
|||||||
// This is fine because:
|
// This is fine because:
|
||||||
// - those queries are `eval_always` so we won't miss their result changing;
|
// - those queries are `eval_always` so we won't miss their result changing;
|
||||||
// - this write will have happened before these queries are called.
|
// - this write will have happened before these queries are called.
|
||||||
let def_id = self.tcx.create_def(parent, name, def_kind);
|
|
||||||
|
|
||||||
let feed = self.tcx.feed_local_def_id(def_id);
|
|
||||||
feed.def_span(self.span);
|
|
||||||
feed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> TyCtxt<'tcx> {
|
|
||||||
/// `tcx`-dependent operations performed for every created definition.
|
|
||||||
pub fn create_def(self, parent: LocalDefId, name: Symbol, def_kind: DefKind) -> LocalDefId {
|
|
||||||
let data = def_kind.def_path_data(name);
|
|
||||||
let def_id = self.untracked.definitions.write().create_def(parent, data);
|
let def_id = self.untracked.definitions.write().create_def(parent, data);
|
||||||
|
|
||||||
// This function modifies `self.definitions` using a side-effect.
|
// This function modifies `self.definitions` using a side-effect.
|
||||||
@ -1098,7 +1102,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
feed.visibility(ty::Visibility::Restricted(parent_mod));
|
feed.visibility(ty::Visibility::Restricted(parent_mod));
|
||||||
}
|
}
|
||||||
|
|
||||||
def_id
|
feed
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> + 'tcx {
|
pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> + 'tcx {
|
||||||
|
@ -265,7 +265,8 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
|
|||||||
let body = &tcx.mir_const(def).borrow();
|
let body = &tcx.mir_const(def).borrow();
|
||||||
|
|
||||||
if body.return_ty().references_error() {
|
if body.return_ty().references_error() {
|
||||||
assert!(tcx.dcx().has_errors().is_some(), "mir_const_qualif: MIR had errors");
|
// It's possible to reach here without an error being emitted (#121103).
|
||||||
|
tcx.dcx().span_delayed_bug(body.span, "mir_const_qualif: MIR had errors");
|
||||||
return Default::default();
|
return Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1245,7 +1245,7 @@ impl<'tcx> Resolver<'_, 'tcx> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// FIXME: remove `def_span` body, pass in the right spans here and call `tcx.at().create_def()`
|
// FIXME: remove `def_span` body, pass in the right spans here and call `tcx.at().create_def()`
|
||||||
let def_id = self.tcx.create_def(parent, name, def_kind);
|
let def_id = self.tcx.create_def(parent, name, def_kind).def_id();
|
||||||
|
|
||||||
// Create the definition.
|
// Create the definition.
|
||||||
if expn_id != ExpnId::root() {
|
if expn_id != ExpnId::root() {
|
||||||
|
@ -9,6 +9,7 @@ rustc_abi = { path = "../rustc_abi" }
|
|||||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||||
rustc_hir = { path = "../rustc_hir" }
|
rustc_hir = { path = "../rustc_hir" }
|
||||||
rustc_middle = { path = "../rustc_middle" }
|
rustc_middle = { path = "../rustc_middle" }
|
||||||
|
rustc_session = { path = "../rustc_session" }
|
||||||
rustc_span = { path = "../rustc_span" }
|
rustc_span = { path = "../rustc_span" }
|
||||||
rustc_target = { path = "../rustc_target" }
|
rustc_target = { path = "../rustc_target" }
|
||||||
scoped-tls = "1.0"
|
scoped-tls = "1.0"
|
||||||
|
@ -85,6 +85,10 @@ impl<'tcx> Tables<'tcx> {
|
|||||||
stable_mir::ty::AdtDef(self.create_def_id(did))
|
stable_mir::ty::AdtDef(self.create_def_id(did))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn foreign_module_def(&mut self, did: DefId) -> stable_mir::ty::ForeignModuleDef {
|
||||||
|
stable_mir::ty::ForeignModuleDef(self.create_def_id(did))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn foreign_def(&mut self, did: DefId) -> stable_mir::ty::ForeignDef {
|
pub fn foreign_def(&mut self, did: DefId) -> stable_mir::ty::ForeignDef {
|
||||||
stable_mir::ty::ForeignDef(self.create_def_id(did))
|
stable_mir::ty::ForeignDef(self.create_def_id(did))
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,10 @@ use stable_mir::mir::mono::{InstanceDef, StaticDef};
|
|||||||
use stable_mir::mir::Body;
|
use stable_mir::mir::Body;
|
||||||
use stable_mir::target::{MachineInfo, MachineSize};
|
use stable_mir::target::{MachineInfo, MachineSize};
|
||||||
use stable_mir::ty::{
|
use stable_mir::ty::{
|
||||||
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, GenericArgs,
|
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, ForeignDef,
|
||||||
LineInfo, PolyFnSig, RigidTy, Span, Ty, TyKind, VariantDef,
|
ForeignItemKind, GenericArgs, LineInfo, PolyFnSig, RigidTy, Span, Ty, TyKind, VariantDef,
|
||||||
};
|
};
|
||||||
use stable_mir::{Crate, CrateItem, CrateNum, DefId, Error, Filename, ItemKind, Symbol};
|
use stable_mir::{Crate, CrateDef, CrateItem, CrateNum, DefId, Error, Filename, ItemKind, Symbol};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
@ -67,6 +67,39 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
|||||||
tables.tcx.is_mir_available(def_id)
|
tables.tcx.is_mir_available(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn foreign_modules(&self, crate_num: CrateNum) -> Vec<stable_mir::ty::ForeignModuleDef> {
|
||||||
|
let mut tables = self.0.borrow_mut();
|
||||||
|
let tcx = tables.tcx;
|
||||||
|
tcx.foreign_modules(crate_num.internal(&mut *tables, tcx))
|
||||||
|
.keys()
|
||||||
|
.map(|mod_def_id| tables.foreign_module_def(*mod_def_id))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foreign_module(
|
||||||
|
&self,
|
||||||
|
mod_def: stable_mir::ty::ForeignModuleDef,
|
||||||
|
) -> stable_mir::ty::ForeignModule {
|
||||||
|
let mut tables = self.0.borrow_mut();
|
||||||
|
let def_id = tables[mod_def.def_id()];
|
||||||
|
let mod_def = tables.tcx.foreign_modules(def_id.krate).get(&def_id).unwrap();
|
||||||
|
mod_def.stable(&mut *tables)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foreign_items(&self, mod_def: stable_mir::ty::ForeignModuleDef) -> Vec<ForeignDef> {
|
||||||
|
let mut tables = self.0.borrow_mut();
|
||||||
|
let def_id = tables[mod_def.def_id()];
|
||||||
|
tables
|
||||||
|
.tcx
|
||||||
|
.foreign_modules(def_id.krate)
|
||||||
|
.get(&def_id)
|
||||||
|
.unwrap()
|
||||||
|
.foreign_items
|
||||||
|
.iter()
|
||||||
|
.map(|item_def| tables.foreign_def(*item_def))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
fn all_trait_decls(&self) -> stable_mir::TraitDecls {
|
fn all_trait_decls(&self) -> stable_mir::TraitDecls {
|
||||||
let mut tables = self.0.borrow_mut();
|
let mut tables = self.0.borrow_mut();
|
||||||
tables.tcx.all_traits().map(|trait_def_id| tables.trait_def(trait_def_id)).collect()
|
tables.tcx.all_traits().map(|trait_def_id| tables.trait_def(trait_def_id)).collect()
|
||||||
@ -225,6 +258,21 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
|||||||
tables.tcx.is_foreign_item(tables[item])
|
tables.tcx.is_foreign_item(tables[item])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn foreign_item_kind(&self, def: ForeignDef) -> ForeignItemKind {
|
||||||
|
let mut tables = self.0.borrow_mut();
|
||||||
|
let def_id = tables[def.def_id()];
|
||||||
|
let tcx = tables.tcx;
|
||||||
|
use rustc_hir::def::DefKind;
|
||||||
|
match tcx.def_kind(def_id) {
|
||||||
|
DefKind::Fn => ForeignItemKind::Fn(tables.fn_def(def_id)),
|
||||||
|
DefKind::Static(..) => ForeignItemKind::Static(tables.static_def(def_id)),
|
||||||
|
DefKind::ForeignTy => ForeignItemKind::Type(
|
||||||
|
tables.intern_ty(rustc_middle::ty::Ty::new_foreign(tcx, def_id)),
|
||||||
|
),
|
||||||
|
def_kind => unreachable!("Unexpected kind for a foreign item: {:?}", def_kind),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn adt_kind(&self, def: AdtDef) -> AdtKind {
|
fn adt_kind(&self, def: AdtDef) -> AdtKind {
|
||||||
let mut tables = self.0.borrow_mut();
|
let mut tables = self.0.borrow_mut();
|
||||||
let tcx = tables.tcx;
|
let tcx = tables.tcx;
|
||||||
|
@ -202,41 +202,13 @@ where
|
|||||||
impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> {
|
impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> {
|
||||||
type T = stable_mir::ty::FnSig;
|
type T = stable_mir::ty::FnSig;
|
||||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||||
use rustc_target::spec::abi;
|
use stable_mir::ty::FnSig;
|
||||||
use stable_mir::ty::{Abi, FnSig};
|
|
||||||
|
|
||||||
FnSig {
|
FnSig {
|
||||||
inputs_and_output: self.inputs_and_output.iter().map(|ty| ty.stable(tables)).collect(),
|
inputs_and_output: self.inputs_and_output.iter().map(|ty| ty.stable(tables)).collect(),
|
||||||
c_variadic: self.c_variadic,
|
c_variadic: self.c_variadic,
|
||||||
unsafety: self.unsafety.stable(tables),
|
unsafety: self.unsafety.stable(tables),
|
||||||
abi: match self.abi {
|
abi: self.abi.stable(tables),
|
||||||
abi::Abi::Rust => Abi::Rust,
|
|
||||||
abi::Abi::C { unwind } => Abi::C { unwind },
|
|
||||||
abi::Abi::Cdecl { unwind } => Abi::Cdecl { unwind },
|
|
||||||
abi::Abi::Stdcall { unwind } => Abi::Stdcall { unwind },
|
|
||||||
abi::Abi::Fastcall { unwind } => Abi::Fastcall { unwind },
|
|
||||||
abi::Abi::Vectorcall { unwind } => Abi::Vectorcall { unwind },
|
|
||||||
abi::Abi::Thiscall { unwind } => Abi::Thiscall { unwind },
|
|
||||||
abi::Abi::Aapcs { unwind } => Abi::Aapcs { unwind },
|
|
||||||
abi::Abi::Win64 { unwind } => Abi::Win64 { unwind },
|
|
||||||
abi::Abi::SysV64 { unwind } => Abi::SysV64 { unwind },
|
|
||||||
abi::Abi::PtxKernel => Abi::PtxKernel,
|
|
||||||
abi::Abi::Msp430Interrupt => Abi::Msp430Interrupt,
|
|
||||||
abi::Abi::X86Interrupt => Abi::X86Interrupt,
|
|
||||||
abi::Abi::EfiApi => Abi::EfiApi,
|
|
||||||
abi::Abi::AvrInterrupt => Abi::AvrInterrupt,
|
|
||||||
abi::Abi::AvrNonBlockingInterrupt => Abi::AvrNonBlockingInterrupt,
|
|
||||||
abi::Abi::CCmseNonSecureCall => Abi::CCmseNonSecureCall,
|
|
||||||
abi::Abi::Wasm => Abi::Wasm,
|
|
||||||
abi::Abi::System { unwind } => Abi::System { unwind },
|
|
||||||
abi::Abi::RustIntrinsic => Abi::RustIntrinsic,
|
|
||||||
abi::Abi::RustCall => Abi::RustCall,
|
|
||||||
abi::Abi::PlatformIntrinsic => Abi::PlatformIntrinsic,
|
|
||||||
abi::Abi::Unadjusted => Abi::Unadjusted,
|
|
||||||
abi::Abi::RustCold => Abi::RustCold,
|
|
||||||
abi::Abi::RiscvInterruptM => Abi::RiscvInterruptM,
|
|
||||||
abi::Abi::RiscvInterruptS => Abi::RiscvInterruptS,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -832,3 +804,51 @@ impl<'tcx> Stable<'tcx> for ty::Movability {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> Stable<'tcx> for rustc_target::spec::abi::Abi {
|
||||||
|
type T = stable_mir::ty::Abi;
|
||||||
|
|
||||||
|
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||||
|
use rustc_target::spec::abi;
|
||||||
|
use stable_mir::ty::Abi;
|
||||||
|
match *self {
|
||||||
|
abi::Abi::Rust => Abi::Rust,
|
||||||
|
abi::Abi::C { unwind } => Abi::C { unwind },
|
||||||
|
abi::Abi::Cdecl { unwind } => Abi::Cdecl { unwind },
|
||||||
|
abi::Abi::Stdcall { unwind } => Abi::Stdcall { unwind },
|
||||||
|
abi::Abi::Fastcall { unwind } => Abi::Fastcall { unwind },
|
||||||
|
abi::Abi::Vectorcall { unwind } => Abi::Vectorcall { unwind },
|
||||||
|
abi::Abi::Thiscall { unwind } => Abi::Thiscall { unwind },
|
||||||
|
abi::Abi::Aapcs { unwind } => Abi::Aapcs { unwind },
|
||||||
|
abi::Abi::Win64 { unwind } => Abi::Win64 { unwind },
|
||||||
|
abi::Abi::SysV64 { unwind } => Abi::SysV64 { unwind },
|
||||||
|
abi::Abi::PtxKernel => Abi::PtxKernel,
|
||||||
|
abi::Abi::Msp430Interrupt => Abi::Msp430Interrupt,
|
||||||
|
abi::Abi::X86Interrupt => Abi::X86Interrupt,
|
||||||
|
abi::Abi::EfiApi => Abi::EfiApi,
|
||||||
|
abi::Abi::AvrInterrupt => Abi::AvrInterrupt,
|
||||||
|
abi::Abi::AvrNonBlockingInterrupt => Abi::AvrNonBlockingInterrupt,
|
||||||
|
abi::Abi::CCmseNonSecureCall => Abi::CCmseNonSecureCall,
|
||||||
|
abi::Abi::Wasm => Abi::Wasm,
|
||||||
|
abi::Abi::System { unwind } => Abi::System { unwind },
|
||||||
|
abi::Abi::RustIntrinsic => Abi::RustIntrinsic,
|
||||||
|
abi::Abi::RustCall => Abi::RustCall,
|
||||||
|
abi::Abi::PlatformIntrinsic => Abi::PlatformIntrinsic,
|
||||||
|
abi::Abi::Unadjusted => Abi::Unadjusted,
|
||||||
|
abi::Abi::RustCold => Abi::RustCold,
|
||||||
|
abi::Abi::RiscvInterruptM => Abi::RiscvInterruptM,
|
||||||
|
abi::Abi::RiscvInterruptS => Abi::RiscvInterruptS,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> Stable<'tcx> for rustc_session::cstore::ForeignModule {
|
||||||
|
type T = stable_mir::ty::ForeignModule;
|
||||||
|
|
||||||
|
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||||
|
stable_mir::ty::ForeignModule {
|
||||||
|
def_id: tables.foreign_module_def(self.def_id),
|
||||||
|
abi: self.abi.stable(tables),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -423,6 +423,21 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
|||||||
ty::PredicateKind::AliasRelate(..) => {
|
ty::PredicateKind::AliasRelate(..) => {
|
||||||
bug!("AliasRelate is only used by the new solver")
|
bug!("AliasRelate is only used by the new solver")
|
||||||
}
|
}
|
||||||
|
// Compute `ConstArgHasType` above the overflow check below.
|
||||||
|
// This is because this is not ever a useful obligation to report
|
||||||
|
// as the cause of an overflow.
|
||||||
|
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
|
||||||
|
match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
|
||||||
|
DefineOpaqueTypes::No,
|
||||||
|
ct.ty(),
|
||||||
|
ty,
|
||||||
|
) {
|
||||||
|
Ok(inf_ok) => ProcessResult::Changed(mk_pending(inf_ok.into_obligations())),
|
||||||
|
Err(_) => ProcessResult::Error(FulfillmentErrorCode::SelectionError(
|
||||||
|
SelectionError::Unimplemented,
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// General case overflow check. Allow `process_trait_obligation`
|
// General case overflow check. Allow `process_trait_obligation`
|
||||||
// and `process_projection_obligation` to handle checking for
|
// and `process_projection_obligation` to handle checking for
|
||||||
@ -650,18 +665,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
|
|
||||||
match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
|
|
||||||
DefineOpaqueTypes::No,
|
|
||||||
ct.ty(),
|
|
||||||
ty,
|
|
||||||
) {
|
|
||||||
Ok(inf_ok) => ProcessResult::Changed(mk_pending(inf_ok.into_obligations())),
|
|
||||||
Err(_) => ProcessResult::Error(FulfillmentErrorCode::SelectionError(
|
|
||||||
SelectionError::Unimplemented,
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,10 @@ use crate::mir::mono::{Instance, InstanceDef, StaticDef};
|
|||||||
use crate::mir::Body;
|
use crate::mir::Body;
|
||||||
use crate::target::MachineInfo;
|
use crate::target::MachineInfo;
|
||||||
use crate::ty::{
|
use crate::ty::{
|
||||||
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, GenericArgs,
|
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, ForeignDef,
|
||||||
GenericPredicates, Generics, ImplDef, ImplTrait, LineInfo, PolyFnSig, RigidTy, Span, TraitDecl,
|
ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates, Generics,
|
||||||
TraitDef, Ty, TyKind, VariantDef,
|
ImplDef, ImplTrait, LineInfo, PolyFnSig, RigidTy, Span, TraitDecl, TraitDef, Ty, TyKind,
|
||||||
|
VariantDef,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
mir, Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls, ItemKind,
|
mir, Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls, ItemKind,
|
||||||
@ -31,6 +32,9 @@ pub trait Context {
|
|||||||
fn mir_body(&self, item: DefId) -> mir::Body;
|
fn mir_body(&self, item: DefId) -> mir::Body;
|
||||||
/// Check whether the body of a function is available.
|
/// Check whether the body of a function is available.
|
||||||
fn has_body(&self, item: DefId) -> bool;
|
fn has_body(&self, item: DefId) -> bool;
|
||||||
|
fn foreign_modules(&self, crate_num: CrateNum) -> Vec<ForeignModuleDef>;
|
||||||
|
fn foreign_module(&self, mod_def: ForeignModuleDef) -> ForeignModule;
|
||||||
|
fn foreign_items(&self, mod_def: ForeignModuleDef) -> Vec<ForeignDef>;
|
||||||
fn all_trait_decls(&self) -> TraitDecls;
|
fn all_trait_decls(&self) -> TraitDecls;
|
||||||
fn trait_decls(&self, crate_num: CrateNum) -> TraitDecls;
|
fn trait_decls(&self, crate_num: CrateNum) -> TraitDecls;
|
||||||
fn trait_decl(&self, trait_def: &TraitDef) -> TraitDecl;
|
fn trait_decl(&self, trait_def: &TraitDef) -> TraitDecl;
|
||||||
@ -66,6 +70,9 @@ pub trait Context {
|
|||||||
/// Returns whether this is a foreign item.
|
/// Returns whether this is a foreign item.
|
||||||
fn is_foreign_item(&self, item: DefId) -> bool;
|
fn is_foreign_item(&self, item: DefId) -> bool;
|
||||||
|
|
||||||
|
/// Returns the kind of a given foreign item.
|
||||||
|
fn foreign_item_kind(&self, def: ForeignDef) -> ForeignItemKind;
|
||||||
|
|
||||||
/// Returns the kind of a given algebraic data type
|
/// Returns the kind of a given algebraic data type
|
||||||
fn adt_kind(&self, def: AdtDef) -> AdtKind;
|
fn adt_kind(&self, def: AdtDef) -> AdtKind;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ pub use crate::error::*;
|
|||||||
use crate::mir::pretty::function_name;
|
use crate::mir::pretty::function_name;
|
||||||
use crate::mir::Body;
|
use crate::mir::Body;
|
||||||
use crate::mir::Mutability;
|
use crate::mir::Mutability;
|
||||||
use crate::ty::{ImplDef, IndexedVal, Span, TraitDef, Ty};
|
use crate::ty::{ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty};
|
||||||
|
|
||||||
pub mod abi;
|
pub mod abi;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@ -86,6 +86,11 @@ pub struct Crate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Crate {
|
impl Crate {
|
||||||
|
/// The list of foreign modules in this crate.
|
||||||
|
pub fn foreign_modules(&self) -> Vec<ForeignModuleDef> {
|
||||||
|
with(|cx| cx.foreign_modules(self.id))
|
||||||
|
}
|
||||||
|
|
||||||
/// The list of traits declared in this crate.
|
/// The list of traits declared in this crate.
|
||||||
pub fn trait_decls(&self) -> TraitDecls {
|
pub fn trait_decls(&self) -> TraitDecls {
|
||||||
with(|cx| cx.trait_decls(self.id))
|
with(|cx| cx.trait_decls(self.id))
|
||||||
|
@ -4,9 +4,9 @@ use super::{
|
|||||||
with, DefId, Error, Symbol,
|
with, DefId, Error, Symbol,
|
||||||
};
|
};
|
||||||
use crate::abi::Layout;
|
use crate::abi::Layout;
|
||||||
use crate::crate_def::CrateDef;
|
|
||||||
use crate::mir::alloc::{read_target_int, read_target_uint, AllocId};
|
use crate::mir::alloc::{read_target_int, read_target_uint, AllocId};
|
||||||
use crate::target::MachineInfo;
|
use crate::target::MachineInfo;
|
||||||
|
use crate::{crate_def::CrateDef, mir::mono::StaticDef};
|
||||||
use crate::{Filename, Opaque};
|
use crate::{Filename, Opaque};
|
||||||
use std::fmt::{self, Debug, Display, Formatter};
|
use std::fmt::{self, Debug, Display, Formatter};
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
@ -539,11 +539,45 @@ pub enum Movability {
|
|||||||
Movable,
|
Movable,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crate_def! {
|
||||||
|
pub ForeignModuleDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ForeignModuleDef {
|
||||||
|
pub fn module(&self) -> ForeignModule {
|
||||||
|
with(|cx| cx.foreign_module(*self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ForeignModule {
|
||||||
|
pub def_id: ForeignModuleDef,
|
||||||
|
pub abi: Abi,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ForeignModule {
|
||||||
|
pub fn items(&self) -> Vec<ForeignDef> {
|
||||||
|
with(|cx| cx.foreign_items(self.def_id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
crate_def! {
|
crate_def! {
|
||||||
/// Hold information about a ForeignItem in a crate.
|
/// Hold information about a ForeignItem in a crate.
|
||||||
pub ForeignDef;
|
pub ForeignDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ForeignDef {
|
||||||
|
pub fn kind(&self) -> ForeignItemKind {
|
||||||
|
with(|cx| cx.foreign_item_kind(*self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
||||||
|
pub enum ForeignItemKind {
|
||||||
|
Fn(FnDef),
|
||||||
|
Static(StaticDef),
|
||||||
|
Type(Ty),
|
||||||
|
}
|
||||||
|
|
||||||
crate_def! {
|
crate_def! {
|
||||||
/// Hold information about a function definition in a crate.
|
/// Hold information about a function definition in a crate.
|
||||||
pub FnDef;
|
pub FnDef;
|
||||||
|
@ -969,6 +969,14 @@ pub(crate) mod builtin {
|
|||||||
/// let s = fmt::format(format_args!("hello {}", "world"));
|
/// let s = fmt::format(format_args!("hello {}", "world"));
|
||||||
/// assert_eq!(s, format!("hello {}", "world"));
|
/// assert_eq!(s, format!("hello {}", "world"));
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Lifetime limitation
|
||||||
|
///
|
||||||
|
/// Except when no formatting arguments are used,
|
||||||
|
/// the produced `fmt::Arguments` value borrows temporary values,
|
||||||
|
/// which means it can only be used within the same expression
|
||||||
|
/// and cannot be stored for later use.
|
||||||
|
/// This is a known limitation, see [#92698](https://github.com/rust-lang/rust/issues/92698).
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[cfg_attr(not(test), rustc_diagnostic_item = "format_args_macro")]
|
#[cfg_attr(not(test), rustc_diagnostic_item = "format_args_macro")]
|
||||||
#[allow_internal_unsafe]
|
#[allow_internal_unsafe]
|
||||||
|
@ -27,8 +27,9 @@
|
|||||||
//! Rust atomics currently follow the same rules as [C++20 atomics][cpp], specifically `atomic_ref`.
|
//! Rust atomics currently follow the same rules as [C++20 atomics][cpp], specifically `atomic_ref`.
|
||||||
//! Basically, creating a *shared reference* to one of the Rust atomic types corresponds to creating
|
//! Basically, creating a *shared reference* to one of the Rust atomic types corresponds to creating
|
||||||
//! an `atomic_ref` in C++; the `atomic_ref` is destroyed when the lifetime of the shared reference
|
//! an `atomic_ref` in C++; the `atomic_ref` is destroyed when the lifetime of the shared reference
|
||||||
//! ends. (A Rust atomic type that is exclusively owned or behind a mutable reference does *not*
|
//! ends. A Rust atomic type that is exclusively owned or behind a mutable reference does *not*
|
||||||
//! correspond to an "atomic object" in C++, since it can be accessed via non-atomic operations.)
|
//! correspond to an “atomic object” in C++, since the underlying primitive can be mutably accessed,
|
||||||
|
//! for example with `get_mut`, to perform non-atomic operations.
|
||||||
//!
|
//!
|
||||||
//! [cpp]: https://en.cppreference.com/w/cpp/atomic
|
//! [cpp]: https://en.cppreference.com/w/cpp/atomic
|
||||||
//!
|
//!
|
||||||
|
@ -94,7 +94,8 @@ pub macro thread_local_inner {
|
|||||||
if let $crate::option::Option::Some(init) = init {
|
if let $crate::option::Option::Some(init) = init {
|
||||||
if let $crate::option::Option::Some(value) = init.take() {
|
if let $crate::option::Option::Some(value) = init.take() {
|
||||||
return value;
|
return value;
|
||||||
} else if $crate::cfg!(debug_assertions) {
|
}
|
||||||
|
if $crate::cfg!(debug_assertions) {
|
||||||
$crate::unreachable!("missing default value");
|
$crate::unreachable!("missing default value");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
9
library/std/src/sys/pal/windows/c/README.md
Normal file
9
library/std/src/sys/pal/windows/c/README.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
The `windows_sys.rs` file is autogenerated from `bindings.txt` and must not
|
||||||
|
be edited manually.
|
||||||
|
|
||||||
|
To add bindings, edit `bindings.txt` then regenerate using the following command:
|
||||||
|
|
||||||
|
./x run generate-windows-sys && ./x fmt library/std
|
||||||
|
|
||||||
|
If you need to override generated functions or types then add them to
|
||||||
|
`library/std/src/sys/pal/windows/c.rs`.
|
@ -1,7 +1,6 @@
|
|||||||
--out windows_sys.rs
|
--out windows_sys.rs
|
||||||
--config flatten std
|
--config flatten std
|
||||||
--filter
|
--filter
|
||||||
// tidy-alphabetical-start
|
|
||||||
!Windows.Win32.Foundation.INVALID_HANDLE_VALUE
|
!Windows.Win32.Foundation.INVALID_HANDLE_VALUE
|
||||||
Windows.Wdk.Storage.FileSystem.FILE_COMPLETE_IF_OPLOCKED
|
Windows.Wdk.Storage.FileSystem.FILE_COMPLETE_IF_OPLOCKED
|
||||||
Windows.Wdk.Storage.FileSystem.FILE_CONTAINS_EXTENDED_CREATE_INFORMATION
|
Windows.Wdk.Storage.FileSystem.FILE_CONTAINS_EXTENDED_CREATE_INFORMATION
|
||||||
@ -2592,5 +2591,3 @@ Windows.Win32.System.Threading.WakeAllConditionVariable
|
|||||||
Windows.Win32.System.Threading.WakeConditionVariable
|
Windows.Win32.System.Threading.WakeConditionVariable
|
||||||
Windows.Win32.System.WindowsProgramming.PROGRESS_CONTINUE
|
Windows.Win32.System.WindowsProgramming.PROGRESS_CONTINUE
|
||||||
Windows.Win32.UI.Shell.GetUserProfileDirectoryW
|
Windows.Win32.UI.Shell.GetUserProfileDirectoryW
|
||||||
// tidy-alphabetical-end
|
|
||||||
|
|
@ -1,9 +1,3 @@
|
|||||||
// This file is autogenerated.
|
|
||||||
//
|
|
||||||
// To add bindings, edit windows_sys.lst then use `./x run generate-windows-sys` to
|
|
||||||
// regenerate the bindings.
|
|
||||||
//
|
|
||||||
// ignore-tidy-filelength
|
|
||||||
// Bindings generated by `windows-bindgen` 0.52.0
|
// Bindings generated by `windows-bindgen` 0.52.0
|
||||||
|
|
||||||
#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]
|
#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]
|
||||||
@ -4351,3 +4345,4 @@ impl ::core::clone::Clone for XSAVE_FORMAT {
|
|||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ignore-tidy-filelength
|
||||||
|
@ -334,7 +334,7 @@ where
|
|||||||
match br {
|
match br {
|
||||||
// We only care about named late bound regions, as we need to add them
|
// We only care about named late bound regions, as we need to add them
|
||||||
// to the 'for<>' section
|
// to the 'for<>' section
|
||||||
ty::BrNamed(_, name) => Some(GenericParamDef::lifetime(name)),
|
ty::BrNamed(def_id, name) => Some(GenericParamDef::lifetime(def_id, name)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -18,8 +18,8 @@ use rustc_span::hygiene::MacroKind;
|
|||||||
use rustc_span::symbol::{kw, sym, Symbol};
|
use rustc_span::symbol::{kw, sym, Symbol};
|
||||||
|
|
||||||
use crate::clean::{
|
use crate::clean::{
|
||||||
self, clean_bound_vars, clean_fn_decl_from_did_and_sig, clean_generics, clean_impl_item,
|
self, clean_bound_vars, clean_generics, clean_impl_item, clean_middle_assoc_item,
|
||||||
clean_middle_assoc_item, clean_middle_field, clean_middle_ty, clean_trait_ref_with_bindings,
|
clean_middle_field, clean_middle_ty, clean_poly_fn_sig, clean_trait_ref_with_bindings,
|
||||||
clean_ty, clean_ty_alias_inner_type, clean_ty_generics, clean_variant_def, utils, Attributes,
|
clean_ty, clean_ty_alias_inner_type, clean_ty_generics, clean_variant_def, utils, Attributes,
|
||||||
AttributesExt, ImplKind, ItemId, Type,
|
AttributesExt, ImplKind, ItemId, Type,
|
||||||
};
|
};
|
||||||
@ -72,7 +72,9 @@ pub(crate) fn try_inline(
|
|||||||
}
|
}
|
||||||
Res::Def(DefKind::Fn, did) => {
|
Res::Def(DefKind::Fn, did) => {
|
||||||
record_extern_fqn(cx, did, ItemType::Function);
|
record_extern_fqn(cx, did, ItemType::Function);
|
||||||
cx.with_param_env(did, |cx| clean::FunctionItem(build_external_function(cx, did)))
|
cx.with_param_env(did, |cx| {
|
||||||
|
clean::enter_impl_trait(cx, |cx| clean::FunctionItem(build_function(cx, did)))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
Res::Def(DefKind::Struct, did) => {
|
Res::Def(DefKind::Struct, did) => {
|
||||||
record_extern_fqn(cx, did, ItemType::Struct);
|
record_extern_fqn(cx, did, ItemType::Struct);
|
||||||
@ -274,18 +276,38 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean
|
|||||||
clean::Trait { def_id: did, generics, items: trait_items, bounds: supertrait_bounds }
|
clean::Trait { def_id: did, generics, items: trait_items, bounds: supertrait_bounds }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> Box<clean::Function> {
|
pub(crate) fn build_function<'tcx>(
|
||||||
let sig = cx.tcx.fn_sig(did).instantiate_identity();
|
cx: &mut DocContext<'tcx>,
|
||||||
let predicates = cx.tcx.explicit_predicates_of(did);
|
def_id: DefId,
|
||||||
|
) -> Box<clean::Function> {
|
||||||
|
let sig = cx.tcx.fn_sig(def_id).instantiate_identity();
|
||||||
|
// The generics need to be cleaned before the signature.
|
||||||
|
let mut generics =
|
||||||
|
clean_ty_generics(cx, cx.tcx.generics_of(def_id), cx.tcx.explicit_predicates_of(def_id));
|
||||||
|
let bound_vars = clean_bound_vars(sig.bound_vars());
|
||||||
|
|
||||||
|
// At the time of writing early & late-bound params are stored separately in rustc,
|
||||||
|
// namely in `generics.params` and `bound_vars` respectively.
|
||||||
|
//
|
||||||
|
// To reestablish the original source code order of the generic parameters, we
|
||||||
|
// need to manually sort them by their definition span after concatenation.
|
||||||
|
//
|
||||||
|
// See also:
|
||||||
|
// * https://rustc-dev-guide.rust-lang.org/bound-vars-and-params.html
|
||||||
|
// * https://rustc-dev-guide.rust-lang.org/what-does-early-late-bound-mean.html
|
||||||
|
let has_early_bound_params = !generics.params.is_empty();
|
||||||
|
let has_late_bound_params = !bound_vars.is_empty();
|
||||||
|
generics.params.extend(bound_vars);
|
||||||
|
if has_early_bound_params && has_late_bound_params {
|
||||||
|
// If this ever becomes a performances bottleneck either due to the sorting
|
||||||
|
// or due to the query calls, consider inserting the late-bound lifetime params
|
||||||
|
// right after the last early-bound lifetime param followed by only sorting
|
||||||
|
// the slice of lifetime params.
|
||||||
|
generics.params.sort_by_key(|param| cx.tcx.def_ident_span(param.def_id).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
let decl = clean_poly_fn_sig(cx, Some(def_id), sig);
|
||||||
|
|
||||||
let (generics, decl) = clean::enter_impl_trait(cx, |cx| {
|
|
||||||
// NOTE: generics need to be cleaned before the decl!
|
|
||||||
let mut generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
|
|
||||||
// FIXME: This does not place parameters in source order (late-bound ones come last)
|
|
||||||
generics.params.extend(clean_bound_vars(sig.bound_vars()));
|
|
||||||
let decl = clean_fn_decl_from_did_and_sig(cx, Some(did), sig);
|
|
||||||
(generics, decl)
|
|
||||||
});
|
|
||||||
Box::new(clean::Function { decl, generics })
|
Box::new(clean::Function { decl, generics })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,7 +523,6 @@ fn clean_generic_param_def<'tcx>(
|
|||||||
(
|
(
|
||||||
def.name,
|
def.name,
|
||||||
GenericParamDefKind::Type {
|
GenericParamDefKind::Type {
|
||||||
did: def.def_id,
|
|
||||||
bounds: ThinVec::new(), // These are filled in from the where-clauses.
|
bounds: ThinVec::new(), // These are filled in from the where-clauses.
|
||||||
default: default.map(Box::new),
|
default: default.map(Box::new),
|
||||||
synthetic,
|
synthetic,
|
||||||
@ -555,7 +554,7 @@ fn clean_generic_param_def<'tcx>(
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
GenericParamDef { name, kind }
|
GenericParamDef { name, def_id: def.def_id, kind }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clean_generic_param<'tcx>(
|
fn clean_generic_param<'tcx>(
|
||||||
@ -594,7 +593,6 @@ fn clean_generic_param<'tcx>(
|
|||||||
(
|
(
|
||||||
param.name.ident().name,
|
param.name.ident().name,
|
||||||
GenericParamDefKind::Type {
|
GenericParamDefKind::Type {
|
||||||
did: param.def_id.to_def_id(),
|
|
||||||
bounds,
|
bounds,
|
||||||
default: default.map(|t| clean_ty(t, cx)).map(Box::new),
|
default: default.map(|t| clean_ty(t, cx)).map(Box::new),
|
||||||
synthetic,
|
synthetic,
|
||||||
@ -612,7 +610,7 @@ fn clean_generic_param<'tcx>(
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
GenericParamDef { name, kind }
|
GenericParamDef { name, def_id: param.def_id.to_def_id(), kind }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Synthetic type-parameters are inserted after normal ones.
|
/// Synthetic type-parameters are inserted after normal ones.
|
||||||
@ -644,8 +642,8 @@ pub(crate) fn clean_generics<'tcx>(
|
|||||||
let param = clean_generic_param(cx, Some(gens), param);
|
let param = clean_generic_param(cx, Some(gens), param);
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Lifetime { .. } => unreachable!(),
|
GenericParamDefKind::Lifetime { .. } => unreachable!(),
|
||||||
GenericParamDefKind::Type { did, ref bounds, .. } => {
|
GenericParamDefKind::Type { ref bounds, .. } => {
|
||||||
cx.impl_trait_bounds.insert(did.into(), bounds.to_vec());
|
cx.impl_trait_bounds.insert(param.def_id.into(), bounds.to_vec());
|
||||||
}
|
}
|
||||||
GenericParamDefKind::Const { .. } => unreachable!(),
|
GenericParamDefKind::Const { .. } => unreachable!(),
|
||||||
}
|
}
|
||||||
@ -1062,8 +1060,11 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attrib
|
|||||||
match literal.kind {
|
match literal.kind {
|
||||||
ast::LitKind::Int(a, _) => {
|
ast::LitKind::Int(a, _) => {
|
||||||
let gen = func.generics.params.remove(0);
|
let gen = func.generics.params.remove(0);
|
||||||
if let GenericParamDef { name, kind: GenericParamDefKind::Const { ty, .. } } =
|
if let GenericParamDef {
|
||||||
gen
|
name,
|
||||||
|
kind: GenericParamDefKind::Const { ty, .. },
|
||||||
|
..
|
||||||
|
} = gen
|
||||||
{
|
{
|
||||||
func.decl
|
func.decl
|
||||||
.inputs
|
.inputs
|
||||||
@ -1167,7 +1168,7 @@ fn clean_fn_decl_with_args<'tcx>(
|
|||||||
FnDecl { inputs: args, output, c_variadic: decl.c_variadic }
|
FnDecl { inputs: args, output, c_variadic: decl.c_variadic }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clean_fn_decl_from_did_and_sig<'tcx>(
|
fn clean_poly_fn_sig<'tcx>(
|
||||||
cx: &mut DocContext<'tcx>,
|
cx: &mut DocContext<'tcx>,
|
||||||
did: Option<DefId>,
|
did: Option<DefId>,
|
||||||
sig: ty::PolyFnSig<'tcx>,
|
sig: ty::PolyFnSig<'tcx>,
|
||||||
@ -1357,16 +1358,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::AssocKind::Fn => {
|
ty::AssocKind::Fn => {
|
||||||
let sig = tcx.fn_sig(assoc_item.def_id).instantiate_identity();
|
let mut item = inline::build_function(cx, assoc_item.def_id);
|
||||||
let mut generics = clean_ty_generics(
|
|
||||||
cx,
|
|
||||||
tcx.generics_of(assoc_item.def_id),
|
|
||||||
tcx.explicit_predicates_of(assoc_item.def_id),
|
|
||||||
);
|
|
||||||
// FIXME: This does not place parameters in source order (late-bound ones come last)
|
|
||||||
generics.params.extend(clean_bound_vars(sig.bound_vars()));
|
|
||||||
|
|
||||||
let mut decl = clean_fn_decl_from_did_and_sig(cx, Some(assoc_item.def_id), sig);
|
|
||||||
|
|
||||||
if assoc_item.fn_has_self_parameter {
|
if assoc_item.fn_has_self_parameter {
|
||||||
let self_ty = match assoc_item.container {
|
let self_ty = match assoc_item.container {
|
||||||
@ -1375,12 +1367,13 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
|
|||||||
}
|
}
|
||||||
ty::TraitContainer => tcx.types.self_param,
|
ty::TraitContainer => tcx.types.self_param,
|
||||||
};
|
};
|
||||||
let self_arg_ty = sig.input(0).skip_binder();
|
let self_arg_ty =
|
||||||
|
tcx.fn_sig(assoc_item.def_id).instantiate_identity().input(0).skip_binder();
|
||||||
if self_arg_ty == self_ty {
|
if self_arg_ty == self_ty {
|
||||||
decl.inputs.values[0].type_ = Generic(kw::SelfUpper);
|
item.decl.inputs.values[0].type_ = Generic(kw::SelfUpper);
|
||||||
} else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() {
|
} else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() {
|
||||||
if ty == self_ty {
|
if ty == self_ty {
|
||||||
match decl.inputs.values[0].type_ {
|
match item.decl.inputs.values[0].type_ {
|
||||||
BorrowedRef { ref mut type_, .. } => **type_ = Generic(kw::SelfUpper),
|
BorrowedRef { ref mut type_, .. } => **type_ = Generic(kw::SelfUpper),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
@ -1397,9 +1390,9 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
|
|||||||
ty::ImplContainer => Some(assoc_item.defaultness(tcx)),
|
ty::ImplContainer => Some(assoc_item.defaultness(tcx)),
|
||||||
ty::TraitContainer => None,
|
ty::TraitContainer => None,
|
||||||
};
|
};
|
||||||
MethodItem(Box::new(Function { generics, decl }), defaultness)
|
MethodItem(item, defaultness)
|
||||||
} else {
|
} else {
|
||||||
TyMethodItem(Box::new(Function { generics, decl }))
|
TyMethodItem(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::AssocKind::Type => {
|
ty::AssocKind::Type => {
|
||||||
@ -2083,7 +2076,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
|||||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
ty::FnDef(..) | ty::FnPtr(_) => {
|
||||||
// FIXME: should we merge the outer and inner binders somehow?
|
// FIXME: should we merge the outer and inner binders somehow?
|
||||||
let sig = bound_ty.skip_binder().fn_sig(cx.tcx);
|
let sig = bound_ty.skip_binder().fn_sig(cx.tcx);
|
||||||
let decl = clean_fn_decl_from_did_and_sig(cx, None, sig);
|
let decl = clean_poly_fn_sig(cx, None, sig);
|
||||||
let generic_params = clean_bound_vars(sig.bound_vars());
|
let generic_params = clean_bound_vars(sig.bound_vars());
|
||||||
|
|
||||||
BareFunction(Box::new(BareFunctionDecl {
|
BareFunction(Box::new(BareFunctionDecl {
|
||||||
@ -2166,10 +2159,10 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
|||||||
.iter()
|
.iter()
|
||||||
.flat_map(|pred| pred.bound_vars())
|
.flat_map(|pred| pred.bound_vars())
|
||||||
.filter_map(|var| match var {
|
.filter_map(|var| match var {
|
||||||
ty::BoundVariableKind::Region(ty::BrNamed(_, name))
|
ty::BoundVariableKind::Region(ty::BrNamed(def_id, name))
|
||||||
if name != kw::UnderscoreLifetime =>
|
if name != kw::UnderscoreLifetime =>
|
||||||
{
|
{
|
||||||
Some(GenericParamDef::lifetime(name))
|
Some(GenericParamDef::lifetime(def_id, name))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
@ -3141,20 +3134,22 @@ fn clean_bound_vars<'tcx>(
|
|||||||
bound_vars
|
bound_vars
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|var| match var {
|
.filter_map(|var| match var {
|
||||||
ty::BoundVariableKind::Region(ty::BrNamed(_, name))
|
ty::BoundVariableKind::Region(ty::BrNamed(def_id, name))
|
||||||
if name != kw::UnderscoreLifetime =>
|
if name != kw::UnderscoreLifetime =>
|
||||||
{
|
{
|
||||||
Some(GenericParamDef::lifetime(name))
|
Some(GenericParamDef::lifetime(def_id, name))
|
||||||
}
|
}
|
||||||
ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(did, name)) => Some(GenericParamDef {
|
ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(def_id, name)) => {
|
||||||
|
Some(GenericParamDef {
|
||||||
name,
|
name,
|
||||||
|
def_id,
|
||||||
kind: GenericParamDefKind::Type {
|
kind: GenericParamDefKind::Type {
|
||||||
did,
|
|
||||||
bounds: ThinVec::new(),
|
bounds: ThinVec::new(),
|
||||||
default: None,
|
default: None,
|
||||||
synthetic: false,
|
synthetic: false,
|
||||||
},
|
},
|
||||||
}),
|
})
|
||||||
|
}
|
||||||
// FIXME(non_lifetime_binders): Support higher-ranked const parameters.
|
// FIXME(non_lifetime_binders): Support higher-ranked const parameters.
|
||||||
ty::BoundVariableKind::Const => None,
|
ty::BoundVariableKind::Const => None,
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -1326,7 +1326,7 @@ impl WherePredicate {
|
|||||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
pub(crate) enum GenericParamDefKind {
|
pub(crate) enum GenericParamDefKind {
|
||||||
Lifetime { outlives: ThinVec<Lifetime> },
|
Lifetime { outlives: ThinVec<Lifetime> },
|
||||||
Type { did: DefId, bounds: ThinVec<GenericBound>, default: Option<Box<Type>>, synthetic: bool },
|
Type { bounds: ThinVec<GenericBound>, default: Option<Box<Type>>, synthetic: bool },
|
||||||
// Option<Box<String>> makes this type smaller than `Option<String>` would.
|
// Option<Box<String>> makes this type smaller than `Option<String>` would.
|
||||||
Const { ty: Box<Type>, default: Option<Box<String>>, is_host_effect: bool },
|
Const { ty: Box<Type>, default: Option<Box<String>>, is_host_effect: bool },
|
||||||
}
|
}
|
||||||
@ -1340,12 +1340,13 @@ impl GenericParamDefKind {
|
|||||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
pub(crate) struct GenericParamDef {
|
pub(crate) struct GenericParamDef {
|
||||||
pub(crate) name: Symbol,
|
pub(crate) name: Symbol,
|
||||||
|
pub(crate) def_id: DefId,
|
||||||
pub(crate) kind: GenericParamDefKind,
|
pub(crate) kind: GenericParamDefKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GenericParamDef {
|
impl GenericParamDef {
|
||||||
pub(crate) fn lifetime(name: Symbol) -> Self {
|
pub(crate) fn lifetime(def_id: DefId, name: Symbol) -> Self {
|
||||||
Self { name, kind: GenericParamDefKind::Lifetime { outlives: ThinVec::new() } }
|
Self { name, def_id, kind: GenericParamDefKind::Lifetime { outlives: ThinVec::new() } }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_synthetic_param(&self) -> bool {
|
pub(crate) fn is_synthetic_param(&self) -> bool {
|
||||||
|
@ -456,7 +456,7 @@ impl FromWithTcx<clean::GenericParamDefKind> for GenericParamDefKind {
|
|||||||
Lifetime { outlives } => GenericParamDefKind::Lifetime {
|
Lifetime { outlives } => GenericParamDefKind::Lifetime {
|
||||||
outlives: outlives.into_iter().map(convert_lifetime).collect(),
|
outlives: outlives.into_iter().map(convert_lifetime).collect(),
|
||||||
},
|
},
|
||||||
Type { did: _, bounds, default, synthetic } => GenericParamDefKind::Type {
|
Type { bounds, default, synthetic } => GenericParamDefKind::Type {
|
||||||
bounds: bounds.into_tcx(tcx),
|
bounds: bounds.into_tcx(tcx),
|
||||||
default: default.map(|x| (*x).into_tcx(tcx)),
|
default: default.map(|x| (*x).into_tcx(tcx)),
|
||||||
synthetic,
|
synthetic,
|
||||||
@ -486,19 +486,16 @@ impl FromWithTcx<clean::WherePredicate> for WherePredicate {
|
|||||||
outlives: outlives.iter().map(|lt| lt.0.to_string()).collect(),
|
outlives: outlives.iter().map(|lt| lt.0.to_string()).collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clean::GenericParamDefKind::Type {
|
clean::GenericParamDefKind::Type { bounds, default, synthetic } => {
|
||||||
did: _,
|
GenericParamDefKind::Type {
|
||||||
bounds,
|
|
||||||
default,
|
|
||||||
synthetic,
|
|
||||||
} => GenericParamDefKind::Type {
|
|
||||||
bounds: bounds
|
bounds: bounds
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|bound| bound.into_tcx(tcx))
|
.map(|bound| bound.into_tcx(tcx))
|
||||||
.collect(),
|
.collect(),
|
||||||
default: default.map(|ty| (*ty).into_tcx(tcx)),
|
default: default.map(|ty| (*ty).into_tcx(tcx)),
|
||||||
synthetic,
|
synthetic,
|
||||||
},
|
}
|
||||||
|
}
|
||||||
clean::GenericParamDefKind::Const {
|
clean::GenericParamDefKind::Const {
|
||||||
ty,
|
ty,
|
||||||
default,
|
default,
|
||||||
|
@ -1,34 +1,49 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::{self, Read, Seek, Write};
|
use std::io::{Read, Seek, SeekFrom, Write};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
/// This is printed to the file before the rest of the contents.
|
|
||||||
const PRELUDE: &str = r#"// This file is autogenerated.
|
|
||||||
//
|
|
||||||
// To add bindings, edit windows_sys.lst then use `./x run generate-windows-sys` to
|
|
||||||
// regenerate the bindings.
|
|
||||||
//
|
|
||||||
// ignore-tidy-filelength
|
|
||||||
"#;
|
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn Error>> {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let mut path: PathBuf =
|
let mut path: PathBuf =
|
||||||
env::args_os().nth(1).expect("a path to the rust repository is required").into();
|
env::args_os().nth(1).expect("a path to the rust repository is required").into();
|
||||||
path.push("library/std/src/sys/pal/windows/c");
|
path.push("library/std/src/sys/pal/windows/c");
|
||||||
env::set_current_dir(&path)?;
|
env::set_current_dir(&path)?;
|
||||||
|
|
||||||
let info = windows_bindgen::bindgen(["--etc", "windows_sys.lst"])?;
|
sort_bindings("bindings.txt")?;
|
||||||
|
|
||||||
|
let info = windows_bindgen::bindgen(["--etc", "bindings.txt"])?;
|
||||||
println!("{info}");
|
println!("{info}");
|
||||||
|
|
||||||
// add some gunk to the output file.
|
let mut f = std::fs::File::options().append(true).open("windows_sys.rs")?;
|
||||||
let mut f = fs::File::options().read(true).write(true).open("windows_sys.rs")?;
|
writeln!(&mut f, "// ignore-tidy-filelength")?;
|
||||||
let mut bindings = String::new();
|
|
||||||
f.read_to_string(&mut bindings)?;
|
|
||||||
f.seek(io::SeekFrom::Start(0))?;
|
|
||||||
f.write_all(PRELUDE.as_bytes())?;
|
|
||||||
f.write_all(bindings.as_bytes())?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sort_bindings(file_name: &str) -> Result<(), Box<dyn Error>> {
|
||||||
|
let mut f = fs::File::options().read(true).write(true).open(file_name)?;
|
||||||
|
let mut bindings = String::new();
|
||||||
|
f.read_to_string(&mut bindings)?;
|
||||||
|
f.set_len(0)?;
|
||||||
|
f.seek(SeekFrom::Start(0))?;
|
||||||
|
|
||||||
|
let mut lines = bindings.split_inclusive('\n');
|
||||||
|
for line in &mut lines {
|
||||||
|
f.write(line.as_bytes())?;
|
||||||
|
if line.contains("--filter") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut bindings = Vec::new();
|
||||||
|
for line in &mut lines {
|
||||||
|
if !line.trim().is_empty() {
|
||||||
|
bindings.push(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bindings.sort_by(|a, b| a.to_lowercase().cmp(&b.to_lowercase()));
|
||||||
|
for line in bindings {
|
||||||
|
f.write(line.as_bytes())?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
// Here, `'a` and `'c` are late-bound and `'b`, `'d`, `T` and `N` are early-bound.
|
||||||
|
|
||||||
|
pub fn f<'a, 'b, 'c, 'd, T, const N: usize>(_: impl Copy)
|
||||||
|
where
|
||||||
|
'b:,
|
||||||
|
'd:,
|
||||||
|
{}
|
||||||
|
|
||||||
|
pub struct Ty;
|
||||||
|
|
||||||
|
impl Ty {
|
||||||
|
pub fn f<'a, 'b, 'c, 'd, T, const N: usize>(_: impl Copy)
|
||||||
|
where
|
||||||
|
'b:,
|
||||||
|
'd:,
|
||||||
|
{}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
// Check that we correctly render late-bound lifetime params in source order
|
||||||
|
// even if early-bound generic params are present.
|
||||||
|
//
|
||||||
|
// For context, at the time of writing early- and late-bound params are stored
|
||||||
|
// separately in rustc and therefore rustdoc needs to manually merge them.
|
||||||
|
|
||||||
|
#![crate_name = "usr"]
|
||||||
|
// aux-crate:dep=early-late-bound-lifetime-params.rs
|
||||||
|
// edition:2021
|
||||||
|
|
||||||
|
// @has usr/fn.f.html
|
||||||
|
// @has - '//pre[@class="rust item-decl"]' "fn f<'a, 'b, 'c, 'd, T, const N: usize>(_: impl Copy)"
|
||||||
|
pub use dep::f;
|
||||||
|
|
||||||
|
// @has usr/struct.Ty.html
|
||||||
|
// @has - '//*[@id="method.f"]' "fn f<'a, 'b, 'c, 'd, T, const N: usize>(_: impl Copy)"
|
||||||
|
pub use dep::Ty;
|
93
tests/ui-fulldeps/stable-mir/check_foreign.rs
Normal file
93
tests/ui-fulldeps/stable-mir/check_foreign.rs
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
// run-pass
|
||||||
|
//! Test retrieval and kinds of foreign items.
|
||||||
|
|
||||||
|
// ignore-stage1
|
||||||
|
// ignore-cross-compile
|
||||||
|
// ignore-remote
|
||||||
|
// ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
|
||||||
|
// edition: 2021
|
||||||
|
|
||||||
|
#![feature(rustc_private)]
|
||||||
|
#![feature(assert_matches)]
|
||||||
|
#![feature(control_flow_enum)]
|
||||||
|
|
||||||
|
extern crate rustc_middle;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate rustc_smir;
|
||||||
|
extern crate rustc_driver;
|
||||||
|
extern crate rustc_interface;
|
||||||
|
extern crate rustc_span;
|
||||||
|
extern crate stable_mir;
|
||||||
|
|
||||||
|
use rustc_smir::rustc_internal;
|
||||||
|
use stable_mir::{
|
||||||
|
ty::{Abi, ForeignItemKind},
|
||||||
|
*,
|
||||||
|
};
|
||||||
|
use std::assert_matches::assert_matches;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
|
const CRATE_NAME: &str = "input";
|
||||||
|
|
||||||
|
/// This function uses the Stable MIR APIs to get information about the test crate.
|
||||||
|
fn test_foreign() -> ControlFlow<()> {
|
||||||
|
let mods =
|
||||||
|
local_crate().foreign_modules().into_iter().map(|def| def.module()).collect::<Vec<_>>();
|
||||||
|
assert_eq!(mods.len(), 2);
|
||||||
|
|
||||||
|
let rust_mod = mods.iter().find(|m| matches!(m.abi, Abi::Rust)).unwrap();
|
||||||
|
assert_eq!(rust_mod.items().len(), 1);
|
||||||
|
|
||||||
|
let c_mod = mods.iter().find(|m| matches!(m.abi, Abi::C { .. })).unwrap();
|
||||||
|
let c_items = c_mod.items();
|
||||||
|
assert_eq!(c_items.len(), 3);
|
||||||
|
for item in c_items {
|
||||||
|
let kind = item.kind();
|
||||||
|
match item.name().as_str() {
|
||||||
|
"foo" => assert_matches!(kind, ForeignItemKind::Fn(..)),
|
||||||
|
"bar" => assert_matches!(kind, ForeignItemKind::Static(..)),
|
||||||
|
"Baz" => assert_matches!(kind, ForeignItemKind::Type(..)),
|
||||||
|
name => unreachable!("Unexpected item {name}"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This test will generate and analyze a dummy crate using the stable mir.
|
||||||
|
/// For that, it will first write the dummy crate into a file.
|
||||||
|
/// Then it will create a `StableMir` using custom arguments and then
|
||||||
|
/// it will run the compiler.
|
||||||
|
fn main() {
|
||||||
|
let path = "foreign_input.rs";
|
||||||
|
generate_input(&path).unwrap();
|
||||||
|
let args = vec![
|
||||||
|
"rustc".to_string(),
|
||||||
|
"-Cpanic=abort".to_string(),
|
||||||
|
"--crate-type=lib".to_string(),
|
||||||
|
"--crate-name".to_string(),
|
||||||
|
CRATE_NAME.to_string(),
|
||||||
|
path.to_string(),
|
||||||
|
];
|
||||||
|
run!(args, || test_foreign()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_input(path: &str) -> std::io::Result<()> {
|
||||||
|
let mut file = std::fs::File::create(path)?;
|
||||||
|
write!(
|
||||||
|
file,
|
||||||
|
r#"
|
||||||
|
#![feature(extern_types)]
|
||||||
|
#![allow(unused)]
|
||||||
|
extern "Rust" {{
|
||||||
|
fn rust_foo(x: i32) -> i32;
|
||||||
|
}}
|
||||||
|
extern "C" {{
|
||||||
|
fn foo(x: i32) -> i32;
|
||||||
|
static bar: i32;
|
||||||
|
type Baz;
|
||||||
|
}}
|
||||||
|
"#
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
28
tests/ui/codegen/overflow-during-mono.rs
Normal file
28
tests/ui/codegen/overflow-during-mono.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// build-fail
|
||||||
|
//~^ ERROR overflow evaluating the requirement
|
||||||
|
|
||||||
|
#![recursion_limit = "32"]
|
||||||
|
|
||||||
|
fn quicksort<It: Clone + Iterator<Item = T>, I: IntoIterator<IntoIter = It>, T: Ord>(
|
||||||
|
i: I,
|
||||||
|
) -> Vec<T> {
|
||||||
|
let mut i = i.into_iter();
|
||||||
|
|
||||||
|
match i.next() {
|
||||||
|
Some(x) => {
|
||||||
|
let less = i.clone().filter(|y| y < &x);
|
||||||
|
let greater = i.filter(|y| &x <= y);
|
||||||
|
|
||||||
|
let mut v = quicksort(less);
|
||||||
|
let u = quicksort(greater);
|
||||||
|
v.push(x);
|
||||||
|
v.extend(u);
|
||||||
|
v
|
||||||
|
}
|
||||||
|
None => vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("{:?}", quicksort([5i32, 1, 6, 3, 6, 1, 9, 0, -1, 6, 8]));
|
||||||
|
}
|
11
tests/ui/codegen/overflow-during-mono.stderr
Normal file
11
tests/ui/codegen/overflow-during-mono.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error[E0275]: overflow evaluating the requirement `{closure@$DIR/overflow-during-mono.rs:13:41: 13:44}: Sized`
|
||||||
|
|
|
||||||
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "64"]` attribute to your crate (`overflow_during_mono`)
|
||||||
|
= note: required for `Filter<std::array::IntoIter<i32, 11>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `Iterator`
|
||||||
|
= note: 31 redundant requirements hidden
|
||||||
|
= note: required for `Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<std::array::IntoIter<i32, 11>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `Iterator`
|
||||||
|
= note: required for `Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<Filter<std::array::IntoIter<i32, 11>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `IntoIterator`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0275`.
|
9
tests/ui/lowering/issue-121108.rs
Normal file
9
tests/ui/lowering/issue-121108.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#![derive(Clone, Copy)] //~ ERROR `derive` attribute cannot be used at crate level
|
||||||
|
|
||||||
|
use std::ptr::addr_of;
|
||||||
|
|
||||||
|
const UNINHABITED_VARIANT: () = unsafe {
|
||||||
|
let v = *addr_of!(data).cast(); //~ ERROR cannot determine resolution for the macro `addr_of`
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {}
|
25
tests/ui/lowering/issue-121108.stderr
Normal file
25
tests/ui/lowering/issue-121108.stderr
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
error: `derive` attribute cannot be used at crate level
|
||||||
|
--> $DIR/issue-121108.rs:1:1
|
||||||
|
|
|
||||||
|
LL | #![derive(Clone, Copy)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL |
|
||||||
|
LL | use std::ptr::addr_of;
|
||||||
|
| ------- the inner attribute doesn't annotate this `use` import
|
||||||
|
|
|
||||||
|
help: perhaps you meant to use an outer attribute
|
||||||
|
|
|
||||||
|
LL - #![derive(Clone, Copy)]
|
||||||
|
LL + #[derive(Clone, Copy)]
|
||||||
|
|
|
||||||
|
|
||||||
|
error: cannot determine resolution for the macro `addr_of`
|
||||||
|
--> $DIR/issue-121108.rs:6:14
|
||||||
|
|
|
||||||
|
LL | let v = *addr_of!(data).cast();
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= note: import resolution is stuck, try simplifying macro imports
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
3
tests/ui/mir/issue-121103.rs
Normal file
3
tests/ui/mir/issue-121103.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fn main(_: <lib2::GenericType<42> as lib2::TypeFn>::Output) {}
|
||||||
|
//~^ ERROR failed to resolve: use of undeclared crate or module `lib2`
|
||||||
|
//~| ERROR failed to resolve: use of undeclared crate or module `lib2`
|
15
tests/ui/mir/issue-121103.stderr
Normal file
15
tests/ui/mir/issue-121103.stderr
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `lib2`
|
||||||
|
--> $DIR/issue-121103.rs:1:38
|
||||||
|
|
|
||||||
|
LL | fn main(_: <lib2::GenericType<42> as lib2::TypeFn>::Output) {}
|
||||||
|
| ^^^^ use of undeclared crate or module `lib2`
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `lib2`
|
||||||
|
--> $DIR/issue-121103.rs:1:13
|
||||||
|
|
|
||||||
|
LL | fn main(_: <lib2::GenericType<42> as lib2::TypeFn>::Output) {}
|
||||||
|
| ^^^^ use of undeclared crate or module `lib2`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0433`.
|
Loading…
x
Reference in New Issue
Block a user