8000 Rollup of 11 pull requests by jonas-schievink · Pull Request #69056 · rust-lang/rust · GitHub
[go: up one dir, main page]

Skip to content

Rollup of 11 pull requests #69056

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 54 commits into from
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
91cf0e7
Don't requery the param_env of a union
matthewjasper Jan 30, 2020
570c161
Remove unnecessary features in rustc_ty
matthewjasper Jan 30, 2020
3973322
Add IS_MANUALLY_DROP to AdtFlags
matthewjasper Jan 30, 2020
d196521
Improve needs_drop query
matthewjasper Jan 30, 2020
d20646b
Address review comments
matthewjasper Jan 31, 2020
465b862
Use correct `ParamEnv` in `Instance::resolve`
matthewjasper Feb 1, 2020
6bf2cc2
Avoid instantiating many `Parser` structs in `generic_extension`.
nnethercote Feb 4, 2020
f840a95
Remove the `Cow` from `Directory`.
nnethercote Feb 5, 2020
2a13b24
Change condition ordering in `parse_tt`.
nnethercote Feb 5, 2020
3998249
remove unnecessary local variable assignment in context manager
chrissimpkins Feb 8, 2020
19aaf63
PEP8 format spacing
chrissimpkins Feb 8, 2020
6ce8d2b
PEP8 format spacing
chrissimpkins Feb 8, 2020
adde3d4
PEP8 format spacing
chrissimpkins Feb 8, 2020
60889d4
remove unnecessary semicolons
chrissimpkins Feb 8, 2020
e30dd86
PEP8 format spacing
chrissimpkins Feb 8, 2020
f38e270
remove unnecessary sys import
chrissimpkins Feb 8, 2020
d366343
PEP8 format spacing
chrissimpkins Feb 8, 2020
a53f45f
PEP8 format spacing, split import statements
chrissimpkins Feb 8, 2020
8d04b95
remove unnecessary import statement
chrissimpkins Feb 8, 2020
85e3661
PEP8 format spacing, remove unnecessary local variable assignment
chrissimpkins Feb 8, 2020
814aa06
PEP8 format spacing
chrissimpkins Feb 8, 2020
9b10fc4
remove unnecessary import statement, PEP8 format spacing
chrissimpkins Feb 8, 2020
77d158d
shorten comment blocks to < 100 characters
chrissimpkins Feb 8, 2020
3eb5241
Apply suggestions from code review
matthewjasper Feb 9, 2020
842938a
cache adt_drop_tys
matthewjasper Feb 9, 2020
202d401
miri: simplify singed operator overflow detection
RalfJung Feb 9, 2020
28f85c6
bring back extra check for int_min%-1
RalfJung Feb 9, 2020
7d2f6ae
miri: equip unary_op with overflow detection
RalfJung Feb 8, 2020
ae23f70
const-prop: use overflowing_unary_op for overflowing checking of unar…
RalfJung Feb 9, 2020
b434d7e
add test that checks overflows on arithmetic operators
RalfJung Feb 10, 2020
1ddb050
div/rem overflow tests: also test i128
RalfJung Feb 10, 2020
d6c5a04
some more tests for i128 oveflow behavior
RalfJung Feb 10, 2020
b8893df
preallocate 2 Vecs in traits; tweak WfPredicates::normalize
ljedrz Feb 10, 2020
9e78ce0
handle TerminatorKind::Yield by returning Err(Unpromotable)
chrissimpkins Feb 10, 2020
75afd0b
use `dyn Trait` more in tests
Centril Feb 10, 2020
fc3ecb2
add issue 69017 test
chrissimpkins Feb 10, 2020
8d79921
parser: Remove `Parser::prev_token_kind`
petrochenkov Feb 10, 2020
25de80a
Remove common usage pattern from `AllocRef`
TimDiekmann Feb 10, 2020
97d1f8d
Add missing `_zeroed` varants to `AllocRef`
TimDiekmann Feb 10, 2020
53b16fb
add main function to issue-69017 test
chrissimpkins Feb 10, 2020
c561d23
remove outdated comment
RalfJung Feb 10, 2020
c38b4b6
Specify opt-level in test
matthewjasper Feb 10, 2020
6575abc
Don't rustfmt the vendor directory.
ehuss Feb 11, 2020
98b3d21
Rollup merge of #68679 - matthewjasper:needs-type-op, r=varkor
jonas-schievink Feb 11, 2020
2125b06
Rollup merge of #68848 - nnethercote:hasten-macro-parsing, r=petroche…
jonas-schievink Feb 11, 2020
7b4772a
Rollup merge of #68947 - chrissimpkins:python-fmt, r=alexcrichton
jonas-schievink Feb 11, 2020
98e8d78
Rollup merge of #69002 - RalfJung:miri-op-overflow, r=oli-obk,wesleyw…
jonas-schievink Feb 11, 2020
cede9c1
Rollup merge of #69022 - ljedrz:traits_tweak_vecs, r=petrochenkov
jonas-schievink Feb 11, 2020
fc25e05
Rollup merge of #69026 - TimDiekmann:common-usage, r=Amanieu
jonas-schievink Feb 11, 2020
9e72cc8
Rollup merge of #69027 - TimDiekmann:zeroed-alloc, r=Amanieu
jonas-schievink Feb 11, 2020
ff8d628
Rollup merge of #69031 - Centril:dyntest, r=eddyb
jonas-schievink Feb 11, 2020
3cf7cd8
Rollup merge of #69032 - chrissimpkins:ice-yield-println-#69017, r=pe…
jonas-schievink Feb 11, 2020
8fcb1a3
Rollup merge of #69034 - petrochenkov:notokind, r=Centril
jonas-schievink Feb 11, 2020
4f1f2b5
Rollup merge of #69047 - ehuss:rustfmt-vendor, r=Centril
jonas-schievink Feb 11, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions src/librustc/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,26 +669,29 @@ rustc_queries! {
no_force
desc { "computing whether `{}` is `Copy`", env.value }
}
/// Query backing `TyS::is_sized`.
query is_sized_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
no_force
desc { "computing whether `{}` is `Sized`", env.value }
}
/// Query backing `TyS::is_freeze`.
query is_freeze_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
no_force
desc { "computing whether `{}` is freeze", env.value }
}

// The cycle error here should be reported as an error by `check_representable`.
// We consider the type as not needing drop in the meanwhile to avoid
// further errors (done in impl Value for NeedsDrop).
// Use `cycle_delay_bug` to delay the cycle error here to be emitted later
// in case we accidentally otherwise don't emit an error.
query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> NeedsDrop {
cycle_delay_bug
/// Query backing `TyS::needs_drop`.
query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
no_force
desc { "computing whether `{}` needs drop", env.value }
}

/// A list of types where the ADT requires drop if and only if any of
/// those types require drop. If the ADT is known to always need drop
/// then `Err(AlwaysRequiresDrop)` is returned.
query adt_drop_tys(_: DefId) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> {
cache_on_disk_if { true }
}

query layout_raw(
env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
) -> Result<&'tcx ty::layout::LayoutDetails, ty::layout::LayoutError<'tcx>> {
Expand Down
132 changes: 0 additions & 132 deletions src/librustc/traits/misc.rs
8000
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
//! Miscellaneous type-system utilities that are too small to deserve their own modules.
use crate::middle::lang_items;
use crate::traits::{self, ObligationCause};
use crate::ty::util::NeedsDrop;
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};

use rustc_hir as hir;
use rustc_span::DUMMY_SP;

#[derive(Clone)]
pub enum CopyImplementationError<'tcx> {
Expand Down Expand Up @@ -71,132 +68,3 @@ pub fn can_type_implement_copy(
Ok(())
})
}

fn is_copy_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
is_item_raw(tcx, query, lang_items::CopyTraitLangItem)
}

fn is_sized_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
is_item_raw(tcx, query, lang_items::SizedTraitLangItem)
}

fn is_freeze_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
is_item_raw(tcx, query, lang_items::FreezeTraitLangItem)
}

fn is_item_raw<'tcx>(
tcx: TyCtxt<'tcx>,
query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
item: lang_items::LangItem,
) -> bool {
let (param_env, ty) = query.into_parts();
let trait_def_id = tcx.require_lang_item(item, None);
tcx.infer_ctxt().enter(|infcx| {
traits::type_known_to_meet_bound_modulo_regions(
&infcx,
param_env,
ty,
trait_def_id,
DUMMY_SP,
)
})
}

fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> NeedsDrop {
let (param_env, ty) = query.into_parts();

let needs_drop = |ty: Ty<'tcx>| -> bool { tcx.needs_drop_raw(param_env.and(ty)).0 };

assert!(!ty.needs_infer());

NeedsDrop(match ty.kind {
// Fast-path for primitive types
ty::Infer(ty::FreshIntTy(_))
| ty::Infer(ty::FreshFloatTy(_))
| ty::Bool
| ty::Int(_)
| ty::Uint(_)
| ty::Float(_)
| ty::Never
| ty::FnDef(..)
| ty::FnPtr(_)
| ty::Char
| ty::GeneratorWitness(..)
| ty::RawPtr(_)
| ty::Ref(..)
| ty::Str => false,

// Foreign types can never have destructors
ty::Foreign(..) => false,

// `ManuallyDrop` doesn't have a destructor regardless of field types.
ty::Adt(def, _) if Some(def.did) == tcx.lang_items().manually_drop() => false,

// Issue #22536: We first query `is_copy_modulo_regions`. It sees a
// normalized version of the type, and therefore will definitely
// know whether the type implements Copy (and thus needs no
// cleanup/drop/zeroing) ...
_ if ty.is_copy_modulo_regions(tcx, param_env, DUMMY_SP) => false,

// ... (issue #22536 continued) but as an optimization, still use
// prior logic of asking for the structural "may drop".

// FIXME(#22815): Note that this is a conservative heuristic;
// it may report that the type "may drop" when actual type does
// not actually have a destructor associated with it. But since
// the type absolutely did not have the `Copy` bound attached
// (see above), it is sound to treat it as having a destructor.

// User destructors are the only way to have concrete drop types.
ty::Adt(def, _) if def.has_dtor(tcx) => true,

// Can refer to a type which may drop.
// FIXME(eddyb) check this against a ParamEnv.
ty::Dynamic(..)
| ty::Projection(..)
| ty::Param(_)
| ty::Bound(..)
| ty::Placeholder(..)
| ty::Opaque(..)
| ty::Infer(_)
| ty::Error => true,

ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),

// Zero-length arrays never contain anything to drop.
ty::Array(_, len) if len.try_eval_usize(tcx, param_env) == Some(0) => false,

// Structural recursion.
ty::Array(ty, _) | ty::Slice(ty) => needs_drop(ty),

ty::Closure(def_id, ref substs) => {
substs.as_closure().upvar_tys(def_id, tcx).any(needs_drop)
}

// Pessimistically assume that all generators will require destructors
// as we don't know if a destructor is a noop or not until after the MIR
// state transformation pass
ty::Generator(..) => true,

ty::Tuple(..) => ty.tuple_fields().any(needs_drop),

// unions don't have destructors because of the child types,
// only if they manually implement `Drop` (handled above).
ty::Adt(def, _) if def.is_union() => false,

ty::Adt(def, substs) => def
.variants
.iter()
.any(|variant| variant.fields.iter().any(|field| needs_drop(field.ty(tcx, substs)))),
})
}

pub fn provide(providers: &mut ty::query::Providers<'_>) {
*providers = ty::query::Providers {
is_copy_raw,
is_sized_raw,
is_freeze_raw,
needs_drop_raw,
..*providers
};
}
1 change: 0 additions & 1 deletion src/librustc/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,6 @@ impl<'tcx> TraitObligation<'tcx> {
}

pub fn provide(providers: &mut ty::query::Providers<'_>) {
misc::provide(providers);
*providers = ty::query::Providers {
is_object_safe: object_safety::is_object_safe_provider,
specialization_graph_of: specialize::specialization_graph_provider,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ impl<'tcx> Instance<'tcx> {
_ => {
if Some(def_id) == tcx.lang_items().drop_in_place_fn() {
let ty = substs.type_at(0);
if ty.needs_drop(tcx, ty::ParamEnv::reveal_all()) {
if ty.needs_drop(tcx, param_env.with_reveal_all()) {
debug!(" => nontrivial drop glue");
ty::InstanceDef::DropGlue(def_id, Some(ty))
} else {
Expand Down
22 changes: 17 additions & 5 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1796,19 +1796,22 @@ bitflags! {
const IS_STRUCT = 1 << 2;
/// Indicates whether the ADT is a struct and has a constructor.
const HAS_CTOR = 1 << 3;
/// Indicates whether the type is a `PhantomData`.
/// Indicates whether the type is `PhantomData`.
const IS_PHANTOM_DATA = 1 << 4;
/// Indicates whether the type has a `#[fundamental]` attribute.
const IS_FUNDAMENTAL = 1 << 5;
/// Indicates whether the type is a `Box`.
/// Indicates whether the type is `Box`.
const IS_BOX = 1 << 6;
/// Indicates whether the type is `ManuallyDrop`.
const IS_MANUALLY_DROP = 1 << 7;
// FIXME(matthewjasper) replace these with diagnostic items
/// Indicates whether the type is an `Arc`.
const IS_ARC = 1 << 7;
const IS_ARC = 1 << 8;
/// Indicates whether the type is an `Rc`.
const IS_RC = 1 << 8;
const IS_RC = 1 << 9;
/// Indicates whether the variant list of this ADT is `#[non_exhaustive]`.
/// (i.e., this flag is never set unless this ADT is an enum).
const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 9;
const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 10;
}
}

Expand Down Expand Up @@ -2184,6 +2187,9 @@ impl<'tcx> AdtDef {
if Some(did) == tcx.lang_items().owned_box() {
flags |= AdtFlags::IS_BOX;
}
if Some(did) == tcx.lang_items().manually_drop() {
flags |= AdtFlags::IS_MANUALLY_DROP;
}
if Some(did) == tcx.lang_items().arc() {
flags |= AdtFlags::IS_ARC;
}
Expand Down Expand Up @@ -2284,6 +2290,12 @@ impl<'tcx> AdtDef {
self.flags.contains(AdtFlags::IS_BOX)
}

/// Returns `true` if this is `ManuallyDrop<T>`.
#[inline]
pub fn is_manually_drop(&self) -> bool {
self.flags.contains(AdtFlags::IS_MANUALLY_DROP)
}

/// Returns `true` if this type has a destructor.
pub fn has_dtor(&self, tcx: TyCtxt<'tcx>) -> bool {
self.destructor(tcx).is_some()
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use crate::traits::Clauses;
use crate::traits::{self, Vtable};
use crate::ty::steal::Steal;
use crate::ty::subst::SubstsRef;
use crate::ty::util::NeedsDrop;
use crate::ty::util::AlwaysRequiresDrop;
use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
use crate::util::common::ErrorReported;
use rustc_data_structures::fingerprint::Fingerprint;
Expand Down
7 changes: 0 additions & 7 deletions src/librustc/ty/query/values.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::ty::util::NeedsDrop;
use crate::ty::{self, AdtSizedConstraint, Ty, TyCtxt};

use rustc_span::symbol::Symbol;
Expand Down Expand Up @@ -26,12 +25,6 @@ impl<'tcx> Value<'tcx> for ty::SymbolName {
}
}

impl<'tcx> Value<'tcx> for NeedsDrop {
fn from_cycle_error(_: TyCtxt<'tcx>) -> Self {
NeedsDrop(false)
}
}

impl<'tcx> Value<'tcx> for AdtSizedConstraint<'tcx> {
fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self {
AdtSizedConstraint(tcx.intern_type_list(&[tcx.types.err]))
Expand Down
92 changes: 88 additions & 4 deletions src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_macros::HashStable;
use rustc_span::Span;
use rustc_target::abi::TargetDataLayout;
use smallvec::SmallVec;
use std::{cmp, fmt};
use syntax::ast;

Expand Down Expand Up @@ -724,7 +726,23 @@ impl<'tcx> ty::TyS<'tcx> {
/// Note that this method is used to check eligible types in unions.
#[inline]
pub fn needs_drop(&'tcx self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
tcx.needs_drop_raw(param_env.and(self)).0
// Avoid querying in simple cases.
match needs_drop_components(self, &tcx.data_layout) {
Err(AlwaysRequiresDrop) => true,
Ok(components) => {
let query_ty = match *components {
[] => return false,
// If we've got a single component, call the query with that
// to increase the chance that we hit the query cache.
[component_ty] => component_ty,
_ => self,
};
// This doesn't depend on regions, so try to minimize distinct
// query keys used.
let erased = tcx.normalize_erasing_regions(param_env, query_ty);
tcx.needs_drop_raw(param_env.and(erased))
}
}
}

pub fn same_type(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
Expand Down Expand Up @@ -923,9 +941,6 @@ impl<'tcx> ty::TyS<'tcx> {
}
}

#[derive(Clone, HashStable)]
pub struct NeedsDrop(pub bool);

pub enum ExplicitSelf<'tcx> {
ByValue,
ByReference(ty::Region<'tcx>, hir::Mutability),
Expand Down Expand Up @@ -974,3 +989,72 @@ impl<'tcx> ExplicitSelf<'tcx> {
}
}
}

/// Returns a list of types such that the given type needs drop if and only if
/// *any* of the returned types need drop. Returns `Err(AlwaysRequiresDrop)` if
/// this type always needs drop.
pub fn needs_drop_components(
ty: Ty<'tcx>,
target_layout: &TargetDataLayout,
) -> Result<SmallVec<[Ty<'tcx>; 2]>, AlwaysRequiresDrop> {
match ty.kind {
ty::Infer(ty::FreshIntTy(_))
| ty::Infer(ty::FreshFloatTy(_))
| ty::Bool
| ty::Int(_)
| ty::Uint(_)
| ty::Float(_)
| ty::Never
| ty::FnDef(..)
| ty::FnPtr(_)
| ty::Char
| ty::GeneratorWitness(..)
| ty::RawPtr(_)
| ty::Ref(..)
| ty::Str => Ok(SmallVec::new()),

// Foreign types can never have destructors.
ty::Foreign(..) => Ok(SmallVec::new()),

// Pessimistically assume that all generators will require destructors
// as we don't know if a destructor is a noop or not until after the MIR
// state transformation pass.
ty::Generator(..) | ty::Dynamic(..) | ty::Error => Err(AlwaysRequiresDrop),

ty::Slice(ty) => needs_drop_components(ty, target_layout),
ty::Array(elem_ty, size) => {
match needs_drop_components(elem_ty, target_layout) {
Ok(v) if v.is_empty() => Ok(v),
res => match size.val.try_to_bits(target_layout.pointer_size) {
// Arrays of size zero don't need drop, even if their element
// type does.
Some(0) => Ok(SmallVec::new()),
Some(_) => res,
// We don't know which of the cases above we are in, so
// return the whole type and let the caller decide what to
// do.
None => Ok(smallvec![ty]),
},
}
}
// If any field needs drop, then the whole tuple does.
ty::Tuple(..) => ty.tuple_fields().try_fold(SmallVec::new(), move |mut acc, elem| {
acc.extend(needs_drop_components(elem, target_layout)?);
Ok(acc)
}),

// These require checking for `Copy` bounds or `Adt` destructors.
ty::Adt(..)
| ty::Projection(..)
| ty::UnnormalizedProjection(..)
| ty::Param(_)
| ty::Bound(..)
| ty::Placeholder(..)
| ty::Opaque(..)
| ty::Infer(_)
| ty::Closure(..) => Ok(smallvec![ty]),
}
}

#[derive(Copy, Clone, Debug, HashStable, RustcEncodable, RustcDecodable)]
pub struct AlwaysRequiresDrop;
Loading
0