mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 23:34:48 +00:00
Auto merge of #91033 - JohnTitor:rollup-sr9zg6o, r=JohnTitor
Rollup of 8 pull requests Successful merges: - #89258 (Make char conversion functions unstably const) - #90578 (add const generics test) - #90633 (Refactor single variant `Candidate` enum into a struct) - #90800 (bootstap: create .cargo/config only if not present) - #90942 (windows: Return the "Not Found" error when a path is empty) - #90947 (Move some tests to more reasonable directories - 9.5) - #90961 (Suggest removal of arguments for unit variant, not replacement) - #90990 (Arenas cleanup) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
e8423e6c44
@ -111,7 +111,7 @@ impl<T> Default for TypedArena<T> {
|
||||
// alloc() will trigger a grow().
|
||||
ptr: Cell::new(ptr::null_mut()),
|
||||
end: Cell::new(ptr::null_mut()),
|
||||
chunks: RefCell::new(vec![]),
|
||||
chunks: Default::default(),
|
||||
_own: PhantomData,
|
||||
}
|
||||
}
|
||||
@ -325,13 +325,17 @@ unsafe impl<#[may_dangle] T> Drop for TypedArena<T> {
|
||||
|
||||
unsafe impl<T: Send> Send for TypedArena<T> {}
|
||||
|
||||
/// An arena that can hold objects of multiple different types that impl `Copy`
|
||||
/// and/or satisfy `!mem::needs_drop`.
|
||||
pub struct DroplessArena {
|
||||
/// A pointer to the start of the free space.
|
||||
start: Cell<*mut u8>,
|
||||
|
||||
/// A pointer to the end of free space.
|
||||
///
|
||||
/// The allocation proceeds from the end of the chunk towards the start.
|
||||
/// The allocation proceeds downwards from the end of the chunk towards the
|
||||
/// start. (This is slightly simpler and faster than allocating upwards,
|
||||
/// see <https://fitzgeraldnick.com/2019/11/01/always-bump-downwards.html>.)
|
||||
/// When this pointer crosses the start pointer, a new chunk is allocated.
|
||||
end: Cell<*mut u8>,
|
||||
|
||||
@ -516,10 +520,14 @@ impl DroplessArena {
|
||||
}
|
||||
}
|
||||
|
||||
// Declare an `Arena` containing one dropless arena and many typed arenas (the
|
||||
// types of the typed arenas are specified by the arguments). The dropless
|
||||
// arena will be used for any types that impl `Copy`, and also for any of the
|
||||
// specified types that satisfy `!mem::needs_drop`.
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
|
||||
pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) {
|
||||
#[derive(Default)]
|
||||
pub struct Arena<$tcx> {
|
||||
pub struct Arena<'tcx> {
|
||||
pub dropless: $crate::DroplessArena,
|
||||
$($name: $crate::TypedArena<$ty>,)*
|
||||
}
|
||||
@ -532,6 +540,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
|
||||
) -> &'a mut [Self];
|
||||
}
|
||||
|
||||
// Any type that impls `Copy` can be arena-allocated in the `DroplessArena`.
|
||||
impl<'tcx, T: Copy> ArenaAllocatable<'tcx, ()> for T {
|
||||
#[inline]
|
||||
fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self {
|
||||
@ -544,12 +553,11 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
|
||||
) -> &'a mut [Self] {
|
||||
arena.dropless.alloc_from_iter(iter)
|
||||
}
|
||||
|
||||
}
|
||||
$(
|
||||
impl<$tcx> ArenaAllocatable<$tcx, $ty> for $ty {
|
||||
impl<'tcx> ArenaAllocatable<'tcx, $ty> for $ty {
|
||||
#[inline]
|
||||
fn allocate_on<'a>(self, arena: &'a Arena<$tcx>) -> &'a mut Self {
|
||||
fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self {
|
||||
if !::std::mem::needs_drop::<Self>() {
|
||||
arena.dropless.alloc(self)
|
||||
} else {
|
||||
@ -559,7 +567,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
|
||||
|
||||
#[inline]
|
||||
fn allocate_from_iter<'a>(
|
||||
arena: &'a Arena<$tcx>,
|
||||
arena: &'a Arena<'tcx>,
|
||||
iter: impl ::std::iter::IntoIterator<Item = Self>,
|
||||
) -> &'a mut [Self] {
|
||||
if !::std::mem::needs_drop::<Self>() {
|
||||
@ -577,6 +585,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
|
||||
value.allocate_on(self)
|
||||
}
|
||||
|
||||
// Any type that impls `Copy` can have slices be arena-allocated in the `DroplessArena`.
|
||||
#[inline]
|
||||
pub fn alloc_slice<T: ::std::marker::Copy>(&self, value: &[T]) -> &mut [T] {
|
||||
if value.is_empty() {
|
||||
|
@ -84,7 +84,7 @@ mod item;
|
||||
mod pat;
|
||||
mod path;
|
||||
|
||||
rustc_hir::arena_types!(rustc_arena::declare_arena, 'tcx);
|
||||
rustc_hir::arena_types!(rustc_arena::declare_arena);
|
||||
|
||||
struct LoweringContext<'a, 'hir: 'a> {
|
||||
/// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
|
||||
|
@ -93,17 +93,8 @@ impl TempState {
|
||||
/// returned value in a promoted MIR, unless it's a subset
|
||||
/// of a larger candidate.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum Candidate {
|
||||
/// Borrow of a constant temporary, candidate for lifetime extension.
|
||||
Ref(Location),
|
||||
}
|
||||
|
||||
impl Candidate {
|
||||
fn source_info(&self, body: &Body<'_>) -> SourceInfo {
|
||||
match self {
|
||||
Candidate::Ref(location) => *body.source_info(*location),
|
||||
}
|
||||
}
|
||||
pub struct Candidate {
|
||||
location: Location,
|
||||
}
|
||||
|
||||
struct Collector<'a, 'tcx> {
|
||||
@ -167,7 +158,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
|
||||
|
||||
match *rvalue {
|
||||
Rvalue::Ref(..) => {
|
||||
self.candidates.push(Candidate::Ref(location));
|
||||
self.candidates.push(Candidate { location });
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -209,36 +200,33 @@ struct Unpromotable;
|
||||
|
||||
impl<'tcx> Validator<'_, 'tcx> {
|
||||
fn validate_candidate(&self, candidate: Candidate) -> Result<(), Unpromotable> {
|
||||
match candidate {
|
||||
Candidate::Ref(loc) => {
|
||||
let statement = &self.body[loc.block].statements[loc.statement_index];
|
||||
match &statement.kind {
|
||||
StatementKind::Assign(box (_, Rvalue::Ref(_, kind, place))) => {
|
||||
// We can only promote interior borrows of promotable temps (non-temps
|
||||
// don't get promoted anyway).
|
||||
self.validate_local(place.local)?;
|
||||
let loc = candidate.location;
|
||||
let statement = &self.body[loc.block].statements[loc.statement_index];
|
||||
match &statement.kind {
|
||||
StatementKind::Assign(box (_, Rvalue::Ref(_, kind, place))) => {
|
||||
// We can only promote interior borrows of promotable temps (non-temps
|
||||
// don't get promoted anyway).
|
||||
self.validate_local(place.local)?;
|
||||
|
||||
// The reference operation itself must be promotable.
|
||||
// (Needs to come after `validate_local` to avoid ICEs.)
|
||||
self.validate_ref(*kind, place)?;
|
||||
// The reference operation itself must be promotable.
|
||||
// (Needs to come after `validate_local` to avoid ICEs.)
|
||||
self.validate_ref(*kind, place)?;
|
||||
|
||||
// We do not check all the projections (they do not get promoted anyway),
|
||||
// but we do stay away from promoting anything involving a dereference.
|
||||
if place.projection.contains(&ProjectionElem::Deref) {
|
||||
return Err(Unpromotable);
|
||||
}
|
||||
|
||||
// We cannot promote things that need dropping, since the promoted value
|
||||
// would not get dropped.
|
||||
if self.qualif_local::<qualifs::NeedsDrop>(place.local) {
|
||||
return Err(Unpromotable);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
_ => bug!(),
|
||||
// We do not check all the projections (they do not get promoted anyway),
|
||||
// but we do stay away from promoting anything involving a dereference.
|
||||
if place.projection.contains(&ProjectionElem::Deref) {
|
||||
return Err(Unpromotable);
|
||||
}
|
||||
|
||||
// We cannot promote things that need dropping, since the promoted value
|
||||
// would not get dropped.
|
||||
if self.qualif_local::<qualifs::NeedsDrop>(place.local) {
|
||||
return Err(Unpromotable);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
_ => bug!(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -871,58 +859,55 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
||||
}))
|
||||
};
|
||||
let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut();
|
||||
match candidate {
|
||||
Candidate::Ref(loc) => {
|
||||
let statement = &mut blocks[loc.block].statements[loc.statement_index];
|
||||
match statement.kind {
|
||||
StatementKind::Assign(box (
|
||||
_,
|
||||
Rvalue::Ref(ref mut region, borrow_kind, ref mut place),
|
||||
)) => {
|
||||
// Use the underlying local for this (necessarily interior) borrow.
|
||||
let ty = local_decls.local_decls()[place.local].ty;
|
||||
let span = statement.source_info.span;
|
||||
let loc = candidate.location;
|
||||
let statement = &mut blocks[loc.block].statements[loc.statement_index];
|
||||
match statement.kind {
|
||||
StatementKind::Assign(box (
|
||||
_,
|
||||
Rvalue::Ref(ref mut region, borrow_kind, ref mut place),
|
||||
)) => {
|
||||
// Use the underlying local for this (necessarily interior) borrow.
|
||||
let ty = local_decls.local_decls()[place.local].ty;
|
||||
let span = statement.source_info.span;
|
||||
|
||||
let ref_ty = tcx.mk_ref(
|
||||
tcx.lifetimes.re_erased,
|
||||
ty::TypeAndMut { ty, mutbl: borrow_kind.to_mutbl_lossy() },
|
||||
);
|
||||
let ref_ty = tcx.mk_ref(
|
||||
tcx.lifetimes.re_erased,
|
||||
ty::TypeAndMut { ty, mutbl: borrow_kind.to_mutbl_lossy() },
|
||||
);
|
||||
|
||||
*region = tcx.lifetimes.re_erased;
|
||||
*region = tcx.lifetimes.re_erased;
|
||||
|
||||
let mut projection = vec![PlaceElem::Deref];
|
||||
projection.extend(place.projection);
|
||||
place.projection = tcx.intern_place_elems(&projection);
|
||||
let mut projection = vec![PlaceElem::Deref];
|
||||
projection.extend(place.projection);
|
||||
place.projection = tcx.intern_place_elems(&projection);
|
||||
|
||||
// Create a temp to hold the promoted reference.
|
||||
// This is because `*r` requires `r` to be a local,
|
||||
// otherwise we would use the `promoted` directly.
|
||||
let mut promoted_ref = LocalDecl::new(ref_ty, span);
|
||||
promoted_ref.source_info = statement.source_info;
|
||||
let promoted_ref = local_decls.push(promoted_ref);
|
||||
assert_eq!(self.temps.push(TempState::Unpromotable), promoted_ref);
|
||||
// Create a temp to hold the promoted reference.
|
||||
// This is because `*r` requires `r` to be a local,
|
||||
// otherwise we would use the `promoted` directly.
|
||||
let mut promoted_ref = LocalDecl::new(ref_ty, span);
|
||||
promoted_ref.source_info = statement.source_info;
|
||||
let promoted_ref = local_decls.push(promoted_ref);
|
||||
assert_eq!(self.temps.push(TempState::Unpromotable), promoted_ref);
|
||||
|
||||
let promoted_ref_statement = Statement {
|
||||
source_info: statement.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
Place::from(promoted_ref),
|
||||
Rvalue::Use(promoted_operand(ref_ty, span)),
|
||||
))),
|
||||
};
|
||||
self.extra_statements.push((loc, promoted_ref_statement));
|
||||
let promoted_ref_statement = Statement {
|
||||
source_info: statement.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
Place::from(promoted_ref),
|
||||
Rvalue::Use(promoted_operand(ref_ty, span)),
|
||||
))),
|
||||
};
|
||||
self.extra_statements.push((loc, promoted_ref_statement));
|
||||
|
||||
Rvalue::Ref(
|
||||
tcx.lifetimes.re_erased,
|
||||
borrow_kind,
|
||||
Place {
|
||||
local: mem::replace(&mut place.local, promoted_ref),
|
||||
projection: List::empty(),
|
||||
},
|
||||
)
|
||||
}
|
||||
_ => bug!(),
|
||||
}
|
||||
Rvalue::Ref(
|
||||
tcx.lifetimes.re_erased,
|
||||
borrow_kind,
|
||||
Place {
|
||||
local: mem::replace(&mut place.local, promoted_ref),
|
||||
projection: List::empty(),
|
||||
},
|
||||
)
|
||||
}
|
||||
_ => bug!(),
|
||||
}
|
||||
};
|
||||
|
||||
@ -964,17 +949,13 @@ pub fn promote_candidates<'tcx>(
|
||||
|
||||
let mut extra_statements = vec![];
|
||||
for candidate in candidates.into_iter().rev() {
|
||||
match candidate {
|
||||
Candidate::Ref(Location { block, statement_index }) => {
|
||||
if let StatementKind::Assign(box (place, _)) =
|
||||
&body[block].statements[statement_index].kind
|
||||
{
|
||||
if let Some(local) = place.as_local() {
|
||||
if temps[local] == TempState::PromotedOut {
|
||||
// Already promoted.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let Location { block, statement_index } = candidate.location;
|
||||
if let StatementKind::Assign(box (place, _)) = &body[block].statements[statement_index].kind
|
||||
{
|
||||
if let Some(local) = place.as_local() {
|
||||
if temps[local] == TempState::PromotedOut {
|
||||
// Already promoted.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -982,7 +963,7 @@ pub fn promote_candidates<'tcx>(
|
||||
// Declare return place local so that `mir::Body::new` doesn't complain.
|
||||
let initial_locals = iter::once(LocalDecl::new(tcx.types.never, body.span)).collect();
|
||||
|
||||
let mut scope = body.source_scopes[candidate.source_info(body).scope].clone();
|
||||
let mut scope = body.source_scopes[body.source_info(candidate.location).scope].clone();
|
||||
scope.parent_scope = None;
|
||||
|
||||
let promoted = Body::new(
|
||||
|
@ -1,52 +1,52 @@
|
||||
/// This declares a list of types which can be allocated by `Arena`.
|
||||
/// This higher-order macro declares a list of types which can be allocated by `Arena`.
|
||||
///
|
||||
/// Specifying the `decode` modifier will add decode impls for `&T` and `&[T]`,
|
||||
/// where `T` is the type listed. These impls will appear in the implement_ty_decoder! macro.
|
||||
#[macro_export]
|
||||
macro_rules! arena_types {
|
||||
($macro:path, $tcx:lifetime) => (
|
||||
($macro:path) => (
|
||||
$macro!([
|
||||
// HIR types
|
||||
[] hir_krate: rustc_hir::Crate<$tcx>,
|
||||
[] arm: rustc_hir::Arm<$tcx>,
|
||||
[] asm_operand: (rustc_hir::InlineAsmOperand<$tcx>, Span),
|
||||
[] hir_krate: rustc_hir::Crate<'tcx>,
|
||||
[] arm: rustc_hir::Arm<'tcx>,
|
||||
[] asm_operand: (rustc_hir::InlineAsmOperand<'tcx>, Span),
|
||||
[] asm_template: rustc_ast::InlineAsmTemplatePiece,
|
||||
[] attribute: rustc_ast::Attribute,
|
||||
[] block: rustc_hir::Block<$tcx>,
|
||||
[] bare_fn_ty: rustc_hir::BareFnTy<$tcx>,
|
||||
[] body: rustc_hir::Body<$tcx>,
|
||||
[] generic_arg: rustc_hir::GenericArg<$tcx>,
|
||||
[] generic_args: rustc_hir::GenericArgs<$tcx>,
|
||||
[] generic_bound: rustc_hir::GenericBound<$tcx>,
|
||||
[] generic_param: rustc_hir::GenericParam<$tcx>,
|
||||
[] expr: rustc_hir::Expr<$tcx>,
|
||||
[] expr_field: rustc_hir::ExprField<$tcx>,
|
||||
[] pat_field: rustc_hir::PatField<$tcx>,
|
||||
[] fn_decl: rustc_hir::FnDecl<$tcx>,
|
||||
[] foreign_item: rustc_hir::ForeignItem<$tcx>,
|
||||
[] block: rustc_hir::Block<'tcx>,
|
||||
[] bare_fn_ty: rustc_hir::BareFnTy<'tcx>,
|
||||
[] body: rustc_hir::Body<'tcx>,
|
||||
[] generic_arg: rustc_hir::GenericArg<'tcx>,
|
||||
[] generic_args: rustc_hir::GenericArgs<'tcx>,
|
||||
[] generic_bound: rustc_hir::GenericBound<'tcx>,
|
||||
[] generic_param: rustc_hir::GenericParam<'tcx>,
|
||||
[] expr: rustc_hir::Expr<'tcx>,
|
||||
[] expr_field: rustc_hir::ExprField<'tcx>,
|
||||
[] pat_field: rustc_hir::PatField<'tcx>,
|
||||
[] fn_decl: rustc_hir::FnDecl<'tcx>,
|
||||
[] foreign_item: rustc_hir::ForeignItem<'tcx>,
|
||||
[] foreign_item_ref: rustc_hir::ForeignItemRef,
|
||||
[] impl_item: rustc_hir::ImplItem<$tcx>,
|
||||
[] impl_item: rustc_hir::ImplItem<'tcx>,
|
||||
[] impl_item_ref: rustc_hir::ImplItemRef,
|
||||
[] item: rustc_hir::Item<$tcx>,
|
||||
[] inline_asm: rustc_hir::InlineAsm<$tcx>,
|
||||
[] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>,
|
||||
[] local: rustc_hir::Local<$tcx>,
|
||||
[] mod_: rustc_hir::Mod<$tcx>,
|
||||
[] owner_info: rustc_hir::OwnerInfo<$tcx>,
|
||||
[] param: rustc_hir::Param<$tcx>,
|
||||
[] pat: rustc_hir::Pat<$tcx>,
|
||||
[] path: rustc_hir::Path<$tcx>,
|
||||
[] path_segment: rustc_hir::PathSegment<$tcx>,
|
||||
[] poly_trait_ref: rustc_hir::PolyTraitRef<$tcx>,
|
||||
[] qpath: rustc_hir::QPath<$tcx>,
|
||||
[] stmt: rustc_hir::Stmt<$tcx>,
|
||||
[] field_def: rustc_hir::FieldDef<$tcx>,
|
||||
[] trait_item: rustc_hir::TraitItem<$tcx>,
|
||||
[] item: rustc_hir::Item<'tcx>,
|
||||
[] inline_asm: rustc_hir::InlineAsm<'tcx>,
|
||||
[] llvm_inline_asm: rustc_hir::LlvmInlineAsm<'tcx>,
|
||||
[] local: rustc_hir::Local<'tcx>,
|
||||
[] mod_: rustc_hir::Mod<'tcx>,
|
||||
[] owner_info: rustc_hir::OwnerInfo<'tcx>,
|
||||
[] param: rustc_hir::Param<'tcx>,
|
||||
[] pat: rustc_hir::Pat<'tcx>,
|
||||
[] path: rustc_hir::Path<'tcx>,
|
||||
[] path_segment: rustc_hir::PathSegment<'tcx>,
|
||||
[] poly_trait_ref: rustc_hir::PolyTraitRef<'tcx>,
|
||||
[] qpath: rustc_hir::QPath<'tcx>,
|
||||
[] stmt: rustc_hir::Stmt<'tcx>,
|
||||
[] field_def: rustc_hir::FieldDef<'tcx>,
|
||||
[] trait_item: rustc_hir::TraitItem<'tcx>,
|
||||
[] trait_item_ref: rustc_hir::TraitItemRef,
|
||||
[] ty: rustc_hir::Ty<$tcx>,
|
||||
[] type_binding: rustc_hir::TypeBinding<$tcx>,
|
||||
[] variant: rustc_hir::Variant<$tcx>,
|
||||
[] where_predicate: rustc_hir::WherePredicate<$tcx>,
|
||||
], $tcx);
|
||||
[] ty: rustc_hir::Ty<'tcx>,
|
||||
[] type_binding: rustc_hir::TypeBinding<'tcx>,
|
||||
[] variant: rustc_hir::Variant<'tcx>,
|
||||
[] where_predicate: rustc_hir::WherePredicate<'tcx>,
|
||||
]);
|
||||
)
|
||||
}
|
||||
|
@ -1,33 +1,33 @@
|
||||
/// This declares a list of types which can be allocated by `Arena`.
|
||||
/// This higher-order macro declares a list of types which can be allocated by `Arena`.
|
||||
///
|
||||
/// Specifying the `decode` modifier will add decode impls for `&T` and `&[T]` where `T` is the type
|
||||
/// listed. These impls will appear in the implement_ty_decoder! macro.
|
||||
#[macro_export]
|
||||
macro_rules! arena_types {
|
||||
($macro:path, $tcx:lifetime) => (
|
||||
($macro:path) => (
|
||||
$macro!([
|
||||
[] layout: rustc_target::abi::Layout,
|
||||
[] fn_abi: rustc_target::abi::call::FnAbi<$tcx, rustc_middle::ty::Ty<$tcx>>,
|
||||
[] fn_abi: rustc_target::abi::call::FnAbi<'tcx, rustc_middle::ty::Ty<'tcx>>,
|
||||
// AdtDef are interned and compared by address
|
||||
[] adt_def: rustc_middle::ty::AdtDef,
|
||||
[] steal_thir: rustc_data_structures::steal::Steal<rustc_middle::thir::Thir<$tcx>>,
|
||||
[] steal_mir: rustc_data_structures::steal::Steal<rustc_middle::mir::Body<$tcx>>,
|
||||
[decode] mir: rustc_middle::mir::Body<$tcx>,
|
||||
[] steal_thir: rustc_data_structures::steal::Steal<rustc_middle::thir::Thir<'tcx>>,
|
||||
[] steal_mir: rustc_data_structures::steal::Steal<rustc_middle::mir::Body<'tcx>>,
|
||||
[decode] mir: rustc_middle::mir::Body<'tcx>,
|
||||
[] steal_promoted:
|
||||
rustc_data_structures::steal::Steal<
|
||||
rustc_index::vec::IndexVec<
|
||||
rustc_middle::mir::Promoted,
|
||||
rustc_middle::mir::Body<$tcx>
|
||||
rustc_middle::mir::Body<'tcx>
|
||||
>
|
||||
>,
|
||||
[decode] promoted:
|
||||
rustc_index::vec::IndexVec<
|
||||
rustc_middle::mir::Promoted,
|
||||
rustc_middle::mir::Body<$tcx>
|
||||
rustc_middle::mir::Body<'tcx>
|
||||
>,
|
||||
[decode] typeck_results: rustc_middle::ty::TypeckResults<$tcx>,
|
||||
[decode] typeck_results: rustc_middle::ty::TypeckResults<'tcx>,
|
||||
[decode] borrowck_result:
|
||||
rustc_middle::mir::BorrowCheckResult<$tcx>,
|
||||
rustc_middle::mir::BorrowCheckResult<'tcx>,
|
||||
[decode] unsafety_check_result: rustc_middle::mir::UnsafetyCheckResult,
|
||||
[decode] code_region: rustc_middle::mir::coverage::CodeRegion,
|
||||
[] const_allocs: rustc_middle::mir::interpret::Allocation,
|
||||
@ -78,14 +78,14 @@ macro_rules! arena_types {
|
||||
[] foreign_modules: Vec<rustc_session::cstore::ForeignModule>,
|
||||
[] upvars_mentioned: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>,
|
||||
[] object_safety_violations: rustc_middle::traits::ObjectSafetyViolation,
|
||||
[] codegen_unit: rustc_middle::mir::mono::CodegenUnit<$tcx>,
|
||||
[] codegen_unit: rustc_middle::mir::mono::CodegenUnit<'tcx>,
|
||||
[] attribute: rustc_ast::Attribute,
|
||||
[] name_set: rustc_data_structures::fx::FxHashSet<rustc_span::symbol::Symbol>,
|
||||
[] hir_id_set: rustc_hir::HirIdSet,
|
||||
|
||||
// Interned types
|
||||
[] tys: rustc_middle::ty::TyS<$tcx>,
|
||||
[] predicates: rustc_middle::ty::PredicateInner<$tcx>,
|
||||
[] tys: rustc_middle::ty::TyS<'tcx>,
|
||||
[] predicates: rustc_middle::ty::PredicateInner<'tcx>,
|
||||
|
||||
// Note that this deliberately duplicates items in the `rustc_hir::arena`,
|
||||
// since we need to allocate this type on both the `rustc_hir` arena
|
||||
@ -97,8 +97,8 @@ macro_rules! arena_types {
|
||||
[decode] used_trait_imports: rustc_data_structures::fx::FxHashSet<rustc_hir::def_id::LocalDefId>,
|
||||
|
||||
[] dep_kind: rustc_middle::dep_graph::DepKindStruct,
|
||||
], $tcx);
|
||||
]);
|
||||
)
|
||||
}
|
||||
|
||||
arena_types!(rustc_arena::declare_arena, 'tcx);
|
||||
arena_types!(rustc_arena::declare_arena);
|
||||
|
@ -417,17 +417,17 @@ macro_rules! __impl_decoder_methods {
|
||||
macro_rules! impl_arena_allocatable_decoder {
|
||||
([]$args:tt) => {};
|
||||
([decode $(, $attrs:ident)*]
|
||||
[[$name:ident: $ty:ty], $tcx:lifetime]) => {
|
||||
impl<$tcx, D: TyDecoder<$tcx>> RefDecodable<$tcx, D> for $ty {
|
||||
[$name:ident: $ty:ty]) => {
|
||||
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for $ty {
|
||||
#[inline]
|
||||
fn decode(decoder: &mut D) -> Result<&$tcx Self, D::Error> {
|
||||
fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
|
||||
decode_arena_allocable(decoder)
|
||||
}
|
||||
}
|
||||
|
||||
impl<$tcx, D: TyDecoder<$tcx>> RefDecodable<$tcx, D> for [$ty] {
|
||||
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [$ty] {
|
||||
#[inline]
|
||||
fn decode(decoder: &mut D) -> Result<&$tcx Self, D::Error> {
|
||||
fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
|
||||
decode_arena_allocable_slice(decoder)
|
||||
}
|
||||
}
|
||||
@ -438,15 +438,15 @@ macro_rules! impl_arena_allocatable_decoder {
|
||||
}
|
||||
|
||||
macro_rules! impl_arena_allocatable_decoders {
|
||||
([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => {
|
||||
([$($a:tt $name:ident: $ty:ty,)*]) => {
|
||||
$(
|
||||
impl_arena_allocatable_decoder!($a [[$name: $ty], $tcx]);
|
||||
impl_arena_allocatable_decoder!($a [$name: $ty]);
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
rustc_hir::arena_types!(impl_arena_allocatable_decoders, 'tcx);
|
||||
arena_types!(impl_arena_allocatable_decoders, 'tcx);
|
||||
rustc_hir::arena_types!(impl_arena_allocatable_decoders);
|
||||
arena_types!(impl_arena_allocatable_decoders);
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! implement_ty_decoder {
|
||||
|
@ -349,9 +349,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ty::FnPtr(sig) => (sig, None),
|
||||
ref t => {
|
||||
let mut unit_variant = None;
|
||||
let mut removal_span = call_expr.span;
|
||||
if let ty::Adt(adt_def, ..) = t {
|
||||
if adt_def.is_enum() {
|
||||
if let hir::ExprKind::Call(expr, _) = call_expr.kind {
|
||||
removal_span =
|
||||
expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi());
|
||||
unit_variant =
|
||||
self.tcx.sess.source_map().span_to_snippet(expr.span).ok();
|
||||
}
|
||||
@ -379,14 +382,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
);
|
||||
|
||||
if let Some(ref path) = unit_variant {
|
||||
err.span_suggestion(
|
||||
call_expr.span,
|
||||
err.span_suggestion_verbose(
|
||||
removal_span,
|
||||
&format!(
|
||||
"`{}` is a unit variant, you need to write it \
|
||||
without the parentheses",
|
||||
"`{}` is a unit variant, you need to write it without the parentheses",
|
||||
path
|
||||
),
|
||||
path.to_string(),
|
||||
String::new(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
|
@ -51,8 +51,13 @@ use super::MAX;
|
||||
#[must_use]
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn from_u32(i: u32) -> Option<char> {
|
||||
char::try_from(i).ok()
|
||||
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
|
||||
pub const fn from_u32(i: u32) -> Option<char> {
|
||||
// FIXME: once Result::ok is const fn, use it here
|
||||
match char_try_from_u32(i) {
|
||||
Ok(c) => Some(c),
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a `u32` to a `char`, ignoring validity.
|
||||
@ -91,7 +96,8 @@ pub fn from_u32(i: u32) -> Option<char> {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "char_from_unchecked", since = "1.5.0")]
|
||||
pub unsafe fn from_u32_unchecked(i: u32) -> char {
|
||||
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
|
||||
pub const unsafe fn from_u32_unchecked(i: u32) -> char {
|
||||
// SAFETY: the caller must guarantee that `i` is a valid char value.
|
||||
if cfg!(debug_assertions) { char::from_u32(i).unwrap() } else { unsafe { transmute(i) } }
|
||||
}
|
||||
@ -248,18 +254,23 @@ impl FromStr for char {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
const fn char_try_from_u32(i: u32) -> Result<char, CharTryFromError> {
|
||||
if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) {
|
||||
Err(CharTryFromError(()))
|
||||
} else {
|
||||
// SAFETY: checked that it's a legal unicode value
|
||||
Ok(unsafe { transmute(i) })
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "try_from", since = "1.34.0")]
|
||||
impl TryFrom<u32> for char {
|
||||
type Error = CharTryFromError;
|
||||
|
||||
#[inline]
|
||||
fn try_from(i: u32) -> Result<Self, Self::Error> {
|
||||
if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) {
|
||||
Err(CharTryFromError(()))
|
||||
} else {
|
||||
// SAFETY: checked that it's a legal unicode value
|
||||
Ok(unsafe { transmute(i) })
|
||||
}
|
||||
char_try_from_u32(i)
|
||||
}
|
||||
}
|
||||
|
||||
@ -327,7 +338,8 @@ impl fmt::Display for CharTryFromError {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn from_digit(num: u32, radix: u32) -> Option<char> {
|
||||
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
|
||||
pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
|
||||
if radix > 36 {
|
||||
panic!("from_digit: radix is too high (maximum 36)");
|
||||
}
|
||||
|
@ -136,9 +136,10 @@ impl char {
|
||||
/// assert_eq!(None, c);
|
||||
/// ```
|
||||
#[stable(feature = "assoc_char_funcs", since = "1.52.0")]
|
||||
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub fn from_u32(i: u32) -> Option<char> {
|
||||
pub const fn from_u32(i: u32) -> Option<char> {
|
||||
super::convert::from_u32(i)
|
||||
}
|
||||
|
||||
@ -178,9 +179,10 @@ impl char {
|
||||
/// assert_eq!('❤', c);
|
||||
/// ```
|
||||
#[stable(feature = "assoc_char_funcs", since = "1.52.0")]
|
||||
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub unsafe fn from_u32_unchecked(i: u32) -> char {
|
||||
pub const unsafe fn from_u32_unchecked(i: u32) -> char {
|
||||
// SAFETY: the safety contract must be upheld by the caller.
|
||||
unsafe { super::convert::from_u32_unchecked(i) }
|
||||
}
|
||||
@ -235,9 +237,10 @@ impl char {
|
||||
/// let _c = char::from_digit(1, 37);
|
||||
/// ```
|
||||
#[stable(feature = "assoc_char_funcs", since = "1.52.0")]
|
||||
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub fn from_digit(num: u32, radix: u32) -> Option<char> {
|
||||
pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
|
||||
super::convert::from_digit(num, radix)
|
||||
}
|
||||
|
||||
@ -331,10 +334,11 @@ impl char {
|
||||
/// let _ = '1'.to_digit(37);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
pub fn to_digit(self, radix: u32) -> Option<u32> {
|
||||
pub const fn to_digit(self, radix: u32) -> Option<u32> {
|
||||
assert!(radix <= 36, "to_digit: radix is too high (maximum 36)");
|
||||
// If not a digit, a number greater than radix will be created.
|
||||
let mut digit = (self as u32).wrapping_sub('0' as u32);
|
||||
@ -345,7 +349,8 @@ impl char {
|
||||
// Force the 6th bit to be set to ensure ascii is lower case.
|
||||
digit = (self as u32 | 0b10_0000).wrapping_sub('a' as u32).saturating_add(10);
|
||||
}
|
||||
(digit < radix).then_some(digit)
|
||||
// FIXME: once then_some is const fn, use it here
|
||||
if digit < radix { Some(digit) } else { None }
|
||||
}
|
||||
|
||||
/// Returns an iterator that yields the hexadecimal Unicode escape of a
|
||||
|
@ -105,6 +105,7 @@
|
||||
#![feature(const_bigint_helper_methods)]
|
||||
#![feature(const_caller_location)]
|
||||
#![feature(const_cell_into_inner)]
|
||||
#![feature(const_char_convert)]
|
||||
#![feature(const_discriminant)]
|
||||
#![feature(const_eval_select)]
|
||||
#![feature(const_float_bits_conv)]
|
||||
|
@ -1430,4 +1430,8 @@ fn create_dir_long_paths() {
|
||||
// This will fail if the path isn't converted to verbatim.
|
||||
path.push("a");
|
||||
fs::create_dir(&path).unwrap();
|
||||
|
||||
// #90940: Ensure an empty path returns the "Not Found" error.
|
||||
let path = Path::new("");
|
||||
assert_eq!(path.canonicalize().unwrap_err().kind(), crate::io::ErrorKind::NotFound);
|
||||
}
|
||||
|
@ -174,8 +174,8 @@ pub(crate) fn maybe_verbatim(path: &Path) -> io::Result<Vec<u16>> {
|
||||
const UNC_PREFIX: &[u16] = &[SEP, SEP, QUERY, SEP, U, N, C, SEP];
|
||||
|
||||
let mut path = to_u16s(path)?;
|
||||
if path.starts_with(VERBATIM_PREFIX) || path.starts_with(NT_PREFIX) {
|
||||
// Early return for paths that are already verbatim.
|
||||
if path.starts_with(VERBATIM_PREFIX) || path.starts_with(NT_PREFIX) || path == &[0] {
|
||||
// Early return for paths that are already verbatim or empty.
|
||||
return Ok(path);
|
||||
} else if path.len() < LEGACY_MAX_PATH {
|
||||
// Early return if an absolute path is less < 260 UTF-16 code units.
|
||||
|
@ -91,7 +91,6 @@ fn verbatim() {
|
||||
// Make sure opening a drive will work.
|
||||
check("Z:", "Z:");
|
||||
|
||||
// An empty path or a path that contains null are not valid paths.
|
||||
assert!(maybe_verbatim(Path::new("")).is_err());
|
||||
// A path that contains null is not a valid path.
|
||||
assert!(maybe_verbatim(Path::new("\0")).is_err());
|
||||
}
|
||||
|
@ -1119,17 +1119,22 @@ class RustBuild(object):
|
||||
raise Exception("{} not found".format(vendor_dir))
|
||||
|
||||
if self.use_vendored_sources:
|
||||
config = ("[source.crates-io]\n"
|
||||
"replace-with = 'vendored-sources'\n"
|
||||
"registry = 'https://example.com'\n"
|
||||
"\n"
|
||||
"[source.vendored-sources]\n"
|
||||
"directory = '{}/vendor'\n"
|
||||
.format(self.rust_root))
|
||||
if not os.path.exists('.cargo'):
|
||||
os.makedirs('.cargo')
|
||||
with output('.cargo/config') as cargo_config:
|
||||
cargo_config.write(
|
||||
"[source.crates-io]\n"
|
||||
"replace-with = 'vendored-sources'\n"
|
||||
"registry = 'https://example.com'\n"
|
||||
"\n"
|
||||
"[source.vendored-sources]\n"
|
||||
"directory = '{}/vendor'\n"
|
||||
.format(self.rust_root))
|
||||
with output('.cargo/config') as cargo_config:
|
||||
cargo_config.write(config)
|
||||
else:
|
||||
print('info: using vendored source, but .cargo/config is already present.')
|
||||
print(' Reusing the current configuration file. But you may want to '
|
||||
'configure vendoring like this:')
|
||||
print(config)
|
||||
else:
|
||||
if os.path.exists('.cargo'):
|
||||
shutil.rmtree('.cargo')
|
||||
|
26
src/test/ui/const-generics/invariant.nll.stderr
Normal file
26
src/test/ui/const-generics/invariant.nll.stderr
Normal file
@ -0,0 +1,26 @@
|
||||
warning: conflicting implementations of trait `SadBee` for type `for<'a> fn(&'a ())`
|
||||
--> $DIR/invariant.rs:14:1
|
||||
|
|
||||
LL | impl SadBee for for<'a> fn(&'a ()) {
|
||||
| ---------------------------------- first implementation here
|
||||
...
|
||||
LL | impl SadBee for fn(&'static ()) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a> fn(&'a ())`
|
||||
|
|
||||
= note: `#[warn(coherence_leak_check)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>
|
||||
= note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/invariant.rs:27:5
|
||||
|
|
||||
LL | v
|
||||
| ^ one type is more general than the other
|
||||
|
|
||||
= note: expected reference `&Foo<fn(&())>`
|
||||
found reference `&Foo<for<'a> fn(&'a ())>`
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
33
src/test/ui/const-generics/invariant.rs
Normal file
33
src/test/ui/const-generics/invariant.rs
Normal file
@ -0,0 +1,33 @@
|
||||
#![feature(generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
use std::marker::PhantomData;
|
||||
|
||||
trait SadBee {
|
||||
const ASSOC: usize;
|
||||
}
|
||||
// fn(&'static ())` is a supertype of `for<'a> fn(&'a ())` while
|
||||
// we allow two different impls for these types, leading
|
||||
// to different const eval results.
|
||||
impl SadBee for for<'a> fn(&'a ()) {
|
||||
const ASSOC: usize = 0;
|
||||
}
|
||||
impl SadBee for fn(&'static ()) {
|
||||
//~^ WARNING conflicting implementations of trait
|
||||
//~| WARNING this was previously accepted
|
||||
const ASSOC: usize = 100;
|
||||
}
|
||||
|
||||
struct Foo<T: SadBee>([u8; <T as SadBee>::ASSOC], PhantomData<T>)
|
||||
where
|
||||
[(); <T as SadBee>::ASSOC]: ;
|
||||
|
||||
fn covariant(
|
||||
v: &'static Foo<for<'a> fn(&'a ())>
|
||||
) -> &'static Foo<fn(&'static ())> {
|
||||
v //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let y = covariant(&Foo([], PhantomData));
|
||||
println!("{:?}", y.0);
|
||||
}
|
26
src/test/ui/const-generics/invariant.stderr
Normal file
26
src/test/ui/const-generics/invariant.stderr
Normal file
@ -0,0 +1,26 @@
|
||||
warning: conflicting implementations of trait `SadBee` for type `for<'a> fn(&'a ())`
|
||||
--> $DIR/invariant.rs:14:1
|
||||
|
|
||||
LL | impl SadBee for for<'a> fn(&'a ()) {
|
||||
| ---------------------------------- first implementation here
|
||||
...
|
||||
LL | impl SadBee for fn(&'static ()) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a> fn(&'a ())`
|
||||
|
|
||||
= note: `#[warn(coherence_leak_check)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>
|
||||
= note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/invariant.rs:27:5
|
||||
|
|
||||
LL | v
|
||||
| ^ one type is more general than the other
|
||||
|
|
||||
= note: expected reference `&'static Foo<fn(&'static ())>`
|
||||
found reference `&'static Foo<for<'a> fn(&'a ())>`
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -22,8 +22,9 @@ LL | let e4 = E::Empty4();
|
||||
|
|
||||
help: `E::Empty4` is a unit variant, you need to write it without the parentheses
|
||||
|
|
||||
LL | let e4 = E::Empty4;
|
||||
| ~~~~~~~~~
|
||||
LL - let e4 = E::Empty4();
|
||||
LL + let e4 = E::Empty4;
|
||||
|
|
||||
|
||||
error[E0618]: expected function, found `empty_struct::XEmpty2`
|
||||
--> $DIR/empty-struct-unit-expr.rs:18:15
|
||||
@ -43,8 +44,9 @@ LL | let xe4 = XE::XEmpty4();
|
||||
|
|
||||
help: `XE::XEmpty4` is a unit variant, you need to write it without the parentheses
|
||||
|
|
||||
LL | let xe4 = XE::XEmpty4;
|
||||
| ~~~~~~~~~~~
|
||||
LL - let xe4 = XE::XEmpty4();
|
||||
LL + let xe4 = XE::XEmpty4;
|
||||
|
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -11,8 +11,9 @@ LL | X::Entry();
|
||||
|
|
||||
help: `X::Entry` is a unit variant, you need to write it without the parentheses
|
||||
|
|
||||
LL | X::Entry;
|
||||
| ~~~~~~~~
|
||||
LL - X::Entry();
|
||||
LL + X::Entry;
|
||||
|
|
||||
|
||||
error[E0618]: expected function, found `i32`
|
||||
--> $DIR/E0618.rs:9:5
|
||||
|
@ -1,10 +0,0 @@
|
||||
mod foo {
|
||||
pub fn x(y: isize) { log(debug, y); }
|
||||
//~^ ERROR cannot find function `log` in this scope
|
||||
//~| ERROR cannot find value `debug` in this scope
|
||||
fn z(y: isize) { log(debug, y); }
|
||||
//~^ ERROR cannot find function `log` in this scope
|
||||
//~| ERROR cannot find value `debug` in this scope
|
||||
}
|
||||
|
||||
fn main() { foo::z(10); } //~ ERROR function `z` is private
|
@ -1,40 +0,0 @@
|
||||
error[E0425]: cannot find function `log` in this scope
|
||||
--> $DIR/export.rs:2:26
|
||||
|
|
||||
LL | pub fn x(y: isize) { log(debug, y); }
|
||||
| ^^^ not found in this scope
|
||||
|
||||
error[E0425]: cannot find value `debug` in this scope
|
||||
--> $DIR/export.rs:2:30
|
||||
|
|
||||
LL | pub fn x(y: isize) { log(debug, y); }
|
||||
| ^^^^^ not found in this scope
|
||||
|
||||
error[E0425]: cannot find function `log` in this scope
|
||||
--> $DIR/export.rs:5:22
|
||||
|
|
||||
LL | fn z(y: isize) { log(debug, y); }
|
||||
| ^^^ not found in this scope
|
||||
|
||||
error[E0425]: cannot find value `debug` in this scope
|
||||
--> $DIR/export.rs:5:26
|
||||
|
|
||||
LL | fn z(y: isize) { log(debug, y); }
|
||||
| ^^^^^ not found in this scope
|
||||
|
||||
error[E0603]: function `z` is private
|
||||
--> $DIR/export.rs:10:18
|
||||
|
|
||||
LL | fn main() { foo::z(10); }
|
||||
| ^ private function
|
||||
|
|
||||
note: the function `z` is defined here
|
||||
--> $DIR/export.rs:5:5
|
||||
|
|
||||
LL | fn z(y: isize) { log(debug, y); }
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0425, E0603.
|
||||
For more information about an error, try `rustc --explain E0425`.
|
@ -1,13 +0,0 @@
|
||||
// run-pass
|
||||
// Regression test for issue #377
|
||||
|
||||
|
||||
struct A { a: isize }
|
||||
struct V { v: isize }
|
||||
|
||||
pub fn main() {
|
||||
let a = { let b = A {a: 3}; b };
|
||||
assert_eq!(a.a, 3);
|
||||
let c = { let d = V {v: 3}; d };
|
||||
assert_eq!(c.v, 3);
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
// run-pass
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
fn leaky<T>(_t: T) { }
|
||||
|
||||
pub fn main() {
|
||||
let x = Box::new(10);
|
||||
leaky::<Box<isize>>(x);
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
// run-pass
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
struct Foo(usize);
|
||||
|
||||
fn foo() -> Foo {
|
||||
Foo(42)
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
assert_eq!(foo(), Foo(42));
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
// run-pass
|
||||
|
||||
struct X {
|
||||
repr: isize
|
||||
}
|
||||
|
||||
fn apply<T, F>(x: T, f: F) where F: FnOnce(T) {
|
||||
f(x);
|
||||
}
|
||||
|
||||
fn check_int(x: isize) {
|
||||
assert_eq!(x, 22);
|
||||
}
|
||||
|
||||
fn check_struct(x: X) {
|
||||
check_int(x.repr);
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
apply(22, check_int);
|
||||
apply(X {repr: 22}, check_struct);
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
// run-pass
|
||||
|
||||
#![allow(dead_code)]
|
||||
// Check that functions can modify local state.
|
||||
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
fn sums_to(v: Vec<isize> , sum: isize) -> bool {
|
||||
let mut i = 0;
|
||||
let mut sum0 = 0;
|
||||
while i < v.len() {
|
||||
sum0 += v[i];
|
||||
i += 1;
|
||||
}
|
||||
return sum0 == sum;
|
||||
}
|
||||
|
||||
fn sums_to_using_uniq(v: Vec<isize> , sum: isize) -> bool {
|
||||
let mut i = 0;
|
||||
let mut sum0: Box<_> = 0.into();
|
||||
while i < v.len() {
|
||||
*sum0 += v[i];
|
||||
i += 1;
|
||||
}
|
||||
return *sum0 == sum;
|
||||
}
|
||||
|
||||
fn sums_to_using_rec(v: Vec<isize> , sum: isize) -> bool {
|
||||
let mut i = 0;
|
||||
let mut sum0 = F {f: 0};
|
||||
while i < v.len() {
|
||||
sum0.f += v[i];
|
||||
i += 1;
|
||||
}
|
||||
return sum0.f == sum;
|
||||
}
|
||||
|
||||
struct F<T> { f: T }
|
||||
|
||||
fn sums_to_using_uniq_rec(v: Vec<isize> , sum: isize) -> bool {
|
||||
let mut i = 0;
|
||||
let mut sum0 = F::<Box<_>> {f: 0.into() };
|
||||
while i < v.len() {
|
||||
*sum0.f += v[i];
|
||||
i += 1;
|
||||
}
|
||||
return *sum0.f == sum;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user