Skip to content

Commit

Permalink
Rollup merge of rust-lang#69146 - matthewjasper:literal-qualif, r=eddyb
Browse files Browse the repository at this point in the history
Always const qualify literals by type

r? @eddyb
  • Loading branch information
Centril authored Feb 18, 2020
2 parents e620d0f + f2980e7 commit 5e2a095
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 23 deletions.
40 changes: 38 additions & 2 deletions src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ impl<'tcx> ty::TyS<'tcx> {
/// strange rules like `<T as Foo<'static>>::Bar: Sized` that
/// actually carry lifetime requirements.
pub fn is_sized(&'tcx self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
tcx_at.is_sized_raw(param_env.and(self))
self.is_trivially_sized(tcx_at.tcx) || tcx_at.is_sized_raw(param_env.and(self))
}

/// Checks whether values of this type `T` implement the `Freeze`
Expand All @@ -713,7 +713,43 @@ impl<'tcx> ty::TyS<'tcx> {
param_env: ty::ParamEnv<'tcx>,
span: Span,
) -> bool {
tcx.at(span).is_freeze_raw(param_env.and(self))
self.is_trivially_freeze() || tcx.at(span).is_freeze_raw(param_env.and(self))
}

/// Fast path helper for testing if a type is `Freeze`.
///
/// Returning true means the type is known to be `Freeze`. Returning
/// `false` means nothing -- could be `Freeze`, might not be.
fn is_trivially_freeze(&self) -> bool {
match self.kind {
ty::Int(_)
| ty::Uint(_)
| ty::Float(_)
| ty::Bool
| ty::Char
| ty::Str
| ty::Never
| ty::Ref(..)
| ty::RawPtr(_)
| ty::FnDef(..)
| ty::Error
| ty::FnPtr(_) => true,
ty::Tuple(_) => self.tuple_fields().all(Self::is_trivially_freeze),
ty::Slice(elem_ty) | ty::Array(elem_ty, _) => elem_ty.is_trivially_freeze(),
ty::Adt(..)
| ty::Bound(..)
| ty::Closure(..)
| ty::Dynamic(..)
| ty::Foreign(_)
| ty::Generator(..)
| ty::GeneratorWitness(_)
| ty::Infer(_)
| ty::Opaque(..)
| ty::Param(_)
| ty::Placeholder(_)
| ty::Projection(_)
| ty::UnnormalizedProjection(_) => false,
}
}

/// If `ty.needs_drop(...)` returns `true`, then `ty` is definitely
Expand Down
25 changes: 8 additions & 17 deletions src/librustc_mir/transform/check_consts/qualifs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,32 +94,23 @@ pub trait Qualif {
}

Operand::Constant(ref constant) => {
if constant.check_static_ptr(cx.tcx).is_some() {
// `mir_const_qualif` does return the qualifs in the final value of a `static`,
// so we could use value-based qualification here, but we shouldn't do this
// without a good reason.
//
// Note: this uses `constant.literal.ty` which is a reference or pointer to the
// type of the actual `static` item.
Self::in_any_value_of_ty(cx, constant.literal.ty)
} else if let ty::ConstKind::Unevaluated(def_id, _, promoted) = constant.literal.val
{
// Check the qualifs of the value of `const` items.
if let ty::ConstKind::Unevaluated(def_id, _, promoted) = constant.literal.val {
assert!(promoted.is_none());
// Don't peek inside trait associated constants.
if cx.tcx.trait_of_item(def_id).is_some() {
Self::in_any_value_of_ty(cx, constant.literal.ty)
} else {
if cx.tcx.trait_of_item(def_id).is_none() {
let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def_id);
let qualif = Self::in_qualifs(&qualifs);
if !Self::in_qualifs(&qualifs) {
return false;
}

// Just in case the type is more specific than
// the definition, e.g., impl associated const
// with type parameters, take it into account.
qualif && Self::in_any_value_of_ty(cx, constant.literal.ty)
}
} else {
false
}
// Otherwise use the qualifs of the type.
Self::in_any_value_of_ty(cx, constant.literal.ty)
}
}
}
Expand Down
10 changes: 6 additions & 4 deletions src/test/run-make-fulldeps/min-global-align/min_global_align.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![feature(no_core, lang_items)]
#![crate_type="rlib"]
#![crate_type = "rlib"]
#![no_core]

pub static STATIC_BOOL: bool = true;
Expand All @@ -9,7 +9,6 @@ pub static mut STATIC_MUT_BOOL: bool = true;
const CONST_BOOL: bool = true;
pub static CONST_BOOL_REF: &'static bool = &CONST_BOOL;


#[lang = "sized"]
trait Sized {}

Expand All @@ -19,10 +18,13 @@ trait Copy {}
#[lang = "freeze"]
trait Freeze {}

// No `UnsafeCell`, so everything is `Freeze`.
impl<T: ?Sized> Freeze for T {}

#[lang = "sync"]
trait Sync {}
impl Sync for bool {}
impl Sync for &'static bool {}

#[lang="drop_in_place"]
pub unsafe fn drop_in_place<T: ?Sized>(_: *mut T) { }
#[lang = "drop_in_place"]
pub unsafe fn drop_in_place<T: ?Sized>(_: *mut T) {}

0 comments on commit 5e2a095

Please sign in to comment.