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_hir",
|
||||
"rustc_middle",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"scoped-tls",
|
||||
|
@ -323,7 +323,9 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
|
||||
)
|
||||
}
|
||||
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::Paren(_) | ExprKind::ForLoop { .. } => {
|
||||
|
@ -98,6 +98,26 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 @@ pub struct UnsafetyCheckResult {
|
||||
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 ty: Ty<'tcx>,
|
||||
/// Source info corresponding to the local in the original MIR body.
|
||||
@ -96,7 +97,8 @@ pub struct CoroutineSavedTy<'tcx> {
|
||||
}
|
||||
|
||||
/// 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> {
|
||||
/// The type of every local stored inside the coroutine.
|
||||
pub field_tys: IndexVec<CoroutineSavedLocal, CoroutineSavedTy<'tcx>>,
|
||||
|
@ -1053,6 +1053,22 @@ pub fn create_def(
|
||||
name: Symbol,
|
||||
def_kind: DefKind,
|
||||
) -> 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`.
|
||||
// These very tables are relied on by the incr. comp. engine to decode DepNodes and to
|
||||
// decode the on-disk cache.
|
||||
@ -1067,18 +1083,6 @@ pub fn create_def(
|
||||
// This is fine because:
|
||||
// - those queries are `eval_always` so we won't miss their result changing;
|
||||
// - 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);
|
||||
|
||||
// This function modifies `self.definitions` using a side-effect.
|
||||
@ -1098,7 +1102,7 @@ pub fn create_def(self, parent: LocalDefId, name: Symbol, def_kind: DefKind) ->
|
||||
feed.visibility(ty::Visibility::Restricted(parent_mod));
|
||||
}
|
||||
|
||||
def_id
|
||||
feed
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -1245,7 +1245,7 @@ fn 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.
|
||||
if expn_id != ExpnId::root() {
|
||||
|
@ -9,6 +9,7 @@ rustc_abi = { path = "../rustc_abi" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_hir = { path = "../rustc_hir" }
|
||||
rustc_middle = { path = "../rustc_middle" }
|
||||
rustc_session = { path = "../rustc_session" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
rustc_target = { path = "../rustc_target" }
|
||||
scoped-tls = "1.0"
|
||||
|
@ -85,6 +85,10 @@ pub fn adt_def(&mut self, did: DefId) -> stable_mir::ty::AdtDef {
|
||||
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 {
|
||||
stable_mir::ty::ForeignDef(self.create_def_id(did))
|
||||
}
|
||||
|
@ -22,10 +22,10 @@
|
||||
use stable_mir::mir::Body;
|
||||
use stable_mir::target::{MachineInfo, MachineSize};
|
||||
use stable_mir::ty::{
|
||||
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, GenericArgs,
|
||||
LineInfo, PolyFnSig, RigidTy, Span, Ty, TyKind, VariantDef,
|
||||
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, ForeignDef,
|
||||
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::iter;
|
||||
|
||||
@ -67,6 +67,39 @@ fn has_body(&self, def: DefId) -> bool {
|
||||
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 {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
tables.tcx.all_traits().map(|trait_def_id| tables.trait_def(trait_def_id)).collect()
|
||||
@ -225,6 +258,21 @@ fn is_foreign_item(&self, item: DefId) -> bool {
|
||||
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 {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let tcx = tables.tcx;
|
||||
|
@ -202,41 +202,13 @@ fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> {
|
||||
type T = stable_mir::ty::FnSig;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
use rustc_target::spec::abi;
|
||||
use stable_mir::ty::{Abi, FnSig};
|
||||
use stable_mir::ty::FnSig;
|
||||
|
||||
FnSig {
|
||||
inputs_and_output: self.inputs_and_output.iter().map(|ty| ty.stable(tables)).collect(),
|
||||
c_variadic: self.c_variadic,
|
||||
unsafety: self.unsafety.stable(tables),
|
||||
abi: match self.abi {
|
||||
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,
|
||||
},
|
||||
abi: self.abi.stable(tables),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -832,3 +804,51 @@ fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ fn process_obligation(
|
||||
ty::PredicateKind::AliasRelate(..) => {
|
||||
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`
|
||||
// and `process_projection_obligation` to handle checking for
|
||||
@ -650,18 +665,6 @@ fn process_obligation(
|
||||
}
|
||||
}
|
||||
}
|
||||
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::Body;
|
||||
use crate::target::MachineInfo;
|
||||
use crate::ty::{
|
||||
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, GenericArgs,
|
||||
GenericPredicates, Generics, ImplDef, ImplTrait, LineInfo, PolyFnSig, RigidTy, Span, TraitDecl,
|
||||
TraitDef, Ty, TyKind, VariantDef,
|
||||
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, ForeignDef,
|
||||
ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates, Generics,
|
||||
ImplDef, ImplTrait, LineInfo, PolyFnSig, RigidTy, Span, TraitDecl, TraitDef, Ty, TyKind,
|
||||
VariantDef,
|
||||
};
|
||||
use crate::{
|
||||
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;
|
||||
/// Check whether the body of a function is available.
|
||||
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 trait_decls(&self, crate_num: CrateNum) -> TraitDecls;
|
||||
fn trait_decl(&self, trait_def: &TraitDef) -> TraitDecl;
|
||||
@ -66,6 +70,9 @@ pub trait Context {
|
||||
/// Returns whether this is a foreign item.
|
||||
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
|
||||
fn adt_kind(&self, def: AdtDef) -> AdtKind;
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
use crate::mir::pretty::function_name;
|
||||
use crate::mir::Body;
|
||||
use crate::mir::Mutability;
|
||||
use crate::ty::{ImplDef, IndexedVal, Span, TraitDef, Ty};
|
||||
use crate::ty::{ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty};
|
||||
|
||||
pub mod abi;
|
||||
#[macro_use]
|
||||
@ -86,6 +86,11 @@ pub struct 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.
|
||||
pub fn trait_decls(&self) -> TraitDecls {
|
||||
with(|cx| cx.trait_decls(self.id))
|
||||
|
@ -4,9 +4,9 @@
|
||||
with, DefId, Error, Symbol,
|
||||
};
|
||||
use crate::abi::Layout;
|
||||
use crate::crate_def::CrateDef;
|
||||
use crate::mir::alloc::{read_target_int, read_target_uint, AllocId};
|
||||
use crate::target::MachineInfo;
|
||||
use crate::{crate_def::CrateDef, mir::mono::StaticDef};
|
||||
use crate::{Filename, Opaque};
|
||||
use std::fmt::{self, Debug, Display, Formatter};
|
||||
use std::ops::Range;
|
||||
@ -539,11 +539,45 @@ pub enum Movability {
|
||||
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! {
|
||||
/// Hold information about a ForeignItem in a crate.
|
||||
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! {
|
||||
/// Hold information about a function definition in a crate.
|
||||
pub FnDef;
|
||||
|
@ -969,6 +969,14 @@ macro_rules! compile_error {
|
||||
/// let s = fmt::format(format_args!("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")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "format_args_macro")]
|
||||
#[allow_internal_unsafe]
|
||||
|
@ -27,8 +27,9 @@
|
||||
//! 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
|
||||
//! 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*
|
||||
//! correspond to an "atomic object" in C++, since it can be accessed via non-atomic operations.)
|
||||
//! ends. A Rust atomic type that is exclusively owned or behind a mutable reference does *not*
|
||||
//! 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
|
||||
//!
|
||||
|
@ -94,7 +94,8 @@ unsafe fn __getit(
|
||||
if let $crate::option::Option::Some(init) = init {
|
||||
if let $crate::option::Option::Some(value) = init.take() {
|
||||
return value;
|
||||
} else if $crate::cfg!(debug_assertions) {
|
||||
}
|
||||
if $crate::cfg!(debug_assertions) {
|
||||
$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
|
||||
--config flatten std
|
||||
--filter
|
||||
// tidy-alphabetical-start
|
||||
!Windows.Win32.Foundation.INVALID_HANDLE_VALUE
|
||||
Windows.Wdk.Storage.FileSystem.FILE_COMPLETE_IF_OPLOCKED
|
||||
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.WindowsProgramming.PROGRESS_CONTINUE
|
||||
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
|
||||
|
||||
#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]
|
||||
@ -4351,3 +4345,4 @@ fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
// ignore-tidy-filelength
|
||||
|
@ -334,7 +334,7 @@ fn extract_for_generics(&self, pred: ty::Clause<'tcx>) -> FxHashSet<GenericParam
|
||||
match br {
|
||||
// We only care about named late bound regions, as we need to add them
|
||||
// to the 'for<>' section
|
||||
ty::BrNamed(_, name) => Some(GenericParamDef::lifetime(name)),
|
||||
ty::BrNamed(def_id, name) => Some(GenericParamDef::lifetime(def_id, name)),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
|
@ -18,8 +18,8 @@
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
|
||||
use crate::clean::{
|
||||
self, clean_bound_vars, clean_fn_decl_from_did_and_sig, clean_generics, clean_impl_item,
|
||||
clean_middle_assoc_item, clean_middle_field, clean_middle_ty, clean_trait_ref_with_bindings,
|
||||
self, clean_bound_vars, clean_generics, clean_impl_item, clean_middle_assoc_item,
|
||||
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,
|
||||
AttributesExt, ImplKind, ItemId, Type,
|
||||
};
|
||||
@ -72,7 +72,9 @@ pub(crate) fn try_inline(
|
||||
}
|
||||
Res::Def(DefKind::Fn, did) => {
|
||||
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) => {
|
||||
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 }
|
||||
}
|
||||
|
||||
fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> Box<clean::Function> {
|
||||
let sig = cx.tcx.fn_sig(did).instantiate_identity();
|
||||
let predicates = cx.tcx.explicit_predicates_of(did);
|
||||
pub(crate) fn build_function<'tcx>(
|
||||
cx: &mut DocContext<'tcx>,
|
||||
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 })
|
||||
}
|
||||
|
||||
|
@ -523,7 +523,6 @@ fn clean_generic_param_def<'tcx>(
|
||||
(
|
||||
def.name,
|
||||
GenericParamDefKind::Type {
|
||||
did: def.def_id,
|
||||
bounds: ThinVec::new(), // These are filled in from the where-clauses.
|
||||
default: default.map(Box::new),
|
||||
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>(
|
||||
@ -594,7 +593,6 @@ fn clean_generic_param<'tcx>(
|
||||
(
|
||||
param.name.ident().name,
|
||||
GenericParamDefKind::Type {
|
||||
did: param.def_id.to_def_id(),
|
||||
bounds,
|
||||
default: default.map(|t| clean_ty(t, cx)).map(Box::new),
|
||||
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.
|
||||
@ -644,8 +642,8 @@ pub(crate) fn clean_generics<'tcx>(
|
||||
let param = clean_generic_param(cx, Some(gens), param);
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime { .. } => unreachable!(),
|
||||
GenericParamDefKind::Type { did, ref bounds, .. } => {
|
||||
cx.impl_trait_bounds.insert(did.into(), bounds.to_vec());
|
||||
GenericParamDefKind::Type { ref bounds, .. } => {
|
||||
cx.impl_trait_bounds.insert(param.def_id.into(), bounds.to_vec());
|
||||
}
|
||||
GenericParamDefKind::Const { .. } => unreachable!(),
|
||||
}
|
||||
@ -1062,8 +1060,11 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attrib
|
||||
match literal.kind {
|
||||
ast::LitKind::Int(a, _) => {
|
||||
let gen = func.generics.params.remove(0);
|
||||
if let GenericParamDef { name, kind: GenericParamDefKind::Const { ty, .. } } =
|
||||
gen
|
||||
if let GenericParamDef {
|
||||
name,
|
||||
kind: GenericParamDefKind::Const { ty, .. },
|
||||
..
|
||||
} = gen
|
||||
{
|
||||
func.decl
|
||||
.inputs
|
||||
@ -1167,7 +1168,7 @@ fn clean_fn_decl_with_args<'tcx>(
|
||||
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>,
|
||||
did: Option<DefId>,
|
||||
sig: ty::PolyFnSig<'tcx>,
|
||||
@ -1357,16 +1358,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
|
||||
}
|
||||
}
|
||||
ty::AssocKind::Fn => {
|
||||
let sig = tcx.fn_sig(assoc_item.def_id).instantiate_identity();
|
||||
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);
|
||||
let mut item = inline::build_function(cx, assoc_item.def_id);
|
||||
|
||||
if assoc_item.fn_has_self_parameter {
|
||||
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,
|
||||
};
|
||||
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 {
|
||||
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() {
|
||||
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),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
@ -1397,9 +1390,9 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
|
||||
ty::ImplContainer => Some(assoc_item.defaultness(tcx)),
|
||||
ty::TraitContainer => None,
|
||||
};
|
||||
MethodItem(Box::new(Function { generics, decl }), defaultness)
|
||||
MethodItem(item, defaultness)
|
||||
} else {
|
||||
TyMethodItem(Box::new(Function { generics, decl }))
|
||||
TyMethodItem(item)
|
||||
}
|
||||
}
|
||||
ty::AssocKind::Type => {
|
||||
@ -2083,7 +2076,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
||||
// FIXME: should we merge the outer and inner binders somehow?
|
||||
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());
|
||||
|
||||
BareFunction(Box::new(BareFunctionDecl {
|
||||
@ -2166,10 +2159,10 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
||||
.iter()
|
||||
.flat_map(|pred| pred.bound_vars())
|
||||
.filter_map(|var| match var {
|
||||
ty::BoundVariableKind::Region(ty::BrNamed(_, name))
|
||||
ty::BoundVariableKind::Region(ty::BrNamed(def_id, name))
|
||||
if name != kw::UnderscoreLifetime =>
|
||||
{
|
||||
Some(GenericParamDef::lifetime(name))
|
||||
Some(GenericParamDef::lifetime(def_id, name))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
@ -3141,20 +3134,22 @@ fn clean_bound_vars<'tcx>(
|
||||
bound_vars
|
||||
.into_iter()
|
||||
.filter_map(|var| match var {
|
||||
ty::BoundVariableKind::Region(ty::BrNamed(_, name))
|
||||
ty::BoundVariableKind::Region(ty::BrNamed(def_id, name))
|
||||
if name != kw::UnderscoreLifetime =>
|
||||
{
|
||||
Some(GenericParamDef::lifetime(name))
|
||||
Some(GenericParamDef::lifetime(def_id, name))
|
||||
}
|
||||
ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(def_id, name)) => {
|
||||
Some(GenericParamDef {
|
||||
name,
|
||||
def_id,
|
||||
kind: GenericParamDefKind::Type {
|
||||
bounds: ThinVec::new(),
|
||||
default: None,
|
||||
synthetic: false,
|
||||
},
|
||||
})
|
||||
}
|
||||
ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(did, name)) => Some(GenericParamDef {
|
||||
name,
|
||||
kind: GenericParamDefKind::Type {
|
||||
did,
|
||||
bounds: ThinVec::new(),
|
||||
default: None,
|
||||
synthetic: false,
|
||||
},
|
||||
}),
|
||||
// FIXME(non_lifetime_binders): Support higher-ranked const parameters.
|
||||
ty::BoundVariableKind::Const => None,
|
||||
_ => None,
|
||||
|
@ -1326,7 +1326,7 @@ pub(crate) fn get_bounds(&self) -> Option<&[GenericBound]> {
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub(crate) enum GenericParamDefKind {
|
||||
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.
|
||||
Const { ty: Box<Type>, default: Option<Box<String>>, is_host_effect: bool },
|
||||
}
|
||||
@ -1340,12 +1340,13 @@ pub(crate) fn is_type(&self) -> bool {
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub(crate) struct GenericParamDef {
|
||||
pub(crate) name: Symbol,
|
||||
pub(crate) def_id: DefId,
|
||||
pub(crate) kind: GenericParamDefKind,
|
||||
}
|
||||
|
||||
impl GenericParamDef {
|
||||
pub(crate) fn lifetime(name: Symbol) -> Self {
|
||||
Self { name, kind: GenericParamDefKind::Lifetime { outlives: ThinVec::new() } }
|
||||
pub(crate) fn lifetime(def_id: DefId, name: Symbol) -> Self {
|
||||
Self { name, def_id, kind: GenericParamDefKind::Lifetime { outlives: ThinVec::new() } }
|
||||
}
|
||||
|
||||
pub(crate) fn is_synthetic_param(&self) -> bool {
|
||||
|
@ -456,7 +456,7 @@ fn from_tcx(kind: clean::GenericParamDefKind, tcx: TyCtxt<'_>) -> Self {
|
||||
Lifetime { outlives } => GenericParamDefKind::Lifetime {
|
||||
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),
|
||||
default: default.map(|x| (*x).into_tcx(tcx)),
|
||||
synthetic,
|
||||
@ -486,19 +486,16 @@ fn from_tcx(predicate: clean::WherePredicate, tcx: TyCtxt<'_>) -> Self {
|
||||
outlives: outlives.iter().map(|lt| lt.0.to_string()).collect(),
|
||||
}
|
||||
}
|
||||
clean::GenericParamDefKind::Type {
|
||||
did: _,
|
||||
bounds,
|
||||
default,
|
||||
synthetic,
|
||||
} => GenericParamDefKind::Type {
|
||||
bounds: bounds
|
||||
.into_iter()
|
||||
.map(|bound| bound.into_tcx(tcx))
|
||||
.collect(),
|
||||
default: default.map(|ty| (*ty).into_tcx(tcx)),
|
||||
synthetic,
|
||||
},
|
||||
clean::GenericParamDefKind::Type { bounds, default, synthetic } => {
|
||||
GenericParamDefKind::Type {
|
||||
bounds: bounds
|
||||
.into_iter()
|
||||
.map(|bound| bound.into_tcx(tcx))
|
||||
.collect(),
|
||||
default: default.map(|ty| (*ty).into_tcx(tcx)),
|
||||
synthetic,
|
||||
}
|
||||
}
|
||||
clean::GenericParamDefKind::Const {
|
||||
ty,
|
||||
default,
|
||||
|
@ -1,34 +1,49 @@
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::fs;
|
||||
use std::io::{self, Read, Seek, Write};
|
||||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
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>> {
|
||||
let mut path: PathBuf =
|
||||
env::args_os().nth(1).expect("a path to the rust repository is required").into();
|
||||
path.push("library/std/src/sys/pal/windows/c");
|
||||
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}");
|
||||
|
||||
// add some gunk to the output file.
|
||||
let mut f = fs::File::options().read(true).write(true).open("windows_sys.rs")?;
|
||||
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())?;
|
||||
let mut f = std::fs::File::options().append(true).open("windows_sys.rs")?;
|
||||
writeln!(&mut f, "// ignore-tidy-filelength")?;
|
||||
|
||||
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…
Reference in New Issue
Block a user