Skip to content
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

Rollup of 3 pull requests #63200

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
87e73c1
Remove redundant method with const variable resolution
varkor Jul 31, 2019
804f0f3
Unify spanned and non-spanned Attribute ctors
Mark-Simulacrum Jul 30, 2019
0a42bad
Remove AttrId from Attribute constructors
Mark-Simulacrum Jul 30, 2019
b2c5065
Remove Span argument from ExtCtxt::attribute
Mark-Simulacrum Jul 30, 2019
f78bf50
Remove span argument from mk_attr_{inner,outer}
Mark-Simulacrum Jul 30, 2019
c9bd4a0
Replace a few Attribute constructors with mk_attr
Mark-Simulacrum Jul 30, 2019
0f98581
Replace AstBuilder with inherent methods
Mark-Simulacrum Jul 31, 2019
d4227f6
Use Ident::new over setting span position via builder
Mark-Simulacrum Jul 31, 2019
c146344
Decode AttrId via mk_attr_id
Mark-Simulacrum Jul 30, 2019
c34466c
cast: no need to catch errors any more, force_bits should succeed
RalfJung Jul 24, 2019
4a55c46
operator: implement binary_op strictly by first checking the type, th…
RalfJung Jul 24, 2019
ecc0f4c
turn cast_immediate into its own function
RalfJung Jul 24, 2019
479200b
refactor cast_immediate to dispatch on the type first, and on the val…
RalfJung Jul 24, 2019
c79f222
use From to convert scalars to immediates
RalfJung Jul 24, 2019
f5f0ce9
fix casts from fat pointers
RalfJung Jul 24, 2019
9cfda48
improve error when CTFE does ptr-int-cast; update tests
RalfJung Jul 24, 2019
b0b2a2f
get rid of some remaining type-based dispatching in cast code
RalfJung Jul 24, 2019
3bf7377
add is_any_ptr type test; this also helps pacify tidy
RalfJung Jul 24, 2019
b4372e4
trailing full stops
RalfJung Jul 25, 2019
c05155e
bless all the things
RalfJung Jul 25, 2019
42aedec
const_prop no longer does ptr-to-int casts
RalfJung Jul 25, 2019
12a29d9
fix rebase fallout
RalfJung Aug 1, 2019
47f6b0d
Rollup merge of #62946 - RalfJung:miri_type_dispatch_first, r=oli-obk
Centril Aug 1, 2019
53d5464
Rollup merge of #63146 - Mark-Simulacrum:clean-attr, r=petrochenkov
Centril Aug 1, 2019
3faef22
Rollup merge of #63153 - varkor:remove-resolve_const_var, r=cramertj
Centril Aug 1, 2019
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
8 changes: 0 additions & 8 deletions src/doc/unstable-book/src/language-features/plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ extern crate rustc_plugin;
use syntax::parse::token::{self, Token};
use syntax::tokenstream::TokenTree;
use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
use syntax::ext::build::AstBuilder; // A trait for expr_usize.
use syntax_pos::Span;
use rustc_plugin::Registry;

Expand Down Expand Up @@ -164,13 +163,6 @@ can continue and find further errors.
To print syntax fragments for debugging, you can use `span_note` together with
`syntax::print::pprust::*_to_string`.

The example above produced an integer literal using `AstBuilder::expr_usize`.
As an alternative to the `AstBuilder` trait, `libsyntax` provides a set of
quasiquote macros. They are undocumented and very rough around the edges.
However, the implementation may be a good starting point for an improved
quasiquote as an ordinary plugin library.


# Lint plugins

Plugins can extend [Rust's lint
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5168,7 +5168,7 @@ impl<'a> LoweringContext<'a> {
let uc_nested = attr::mk_nested_word_item(uc_ident);
attr::mk_list_item(e.span, allow_ident, vec![uc_nested])
};
attr::mk_spanned_attr_outer(e.span, attr::mk_attr_id(), allow)
attr::mk_attr_outer(allow)
};
let attrs = vec![attr];

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/infer/canonical/canonicalizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
const_var: &'tcx ty::Const<'tcx>
) -> &'tcx ty::Const<'tcx> {
let infcx = self.infcx.expect("encountered const-var without infcx");
let bound_to = infcx.resolve_const_var(const_var);
let bound_to = infcx.shallow_resolve(const_var);
if bound_to != const_var {
self.fold_const(bound_to)
} else {
Expand Down
27 changes: 4 additions & 23 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1351,23 +1351,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
}

pub fn resolve_const_var(
&self,
ct: &'tcx ty::Const<'tcx>
) -> &'tcx ty::Const<'tcx> {
if let ty::Const { val: ConstValue::Infer(InferConst::Var(v)), .. } = ct {
self.const_unification_table
.borrow_mut()
.probe_value(*v)
.val
.known()
.map(|c| self.resolve_const_var(c))
.unwrap_or(ct)
} else {
ct
}
}

pub fn fully_resolve<T: TypeFoldable<'tcx>>(&self, value: &T) -> FixupResult<'tcx, T> {
/*!
* Attempts to resolve all type/region/const variables in
Expand Down Expand Up @@ -1586,7 +1569,7 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
// it can be resolved to an int/float variable, which
// can then be recursively resolved, hence the
// recursion. Note though that we prevent type
// variables from unifyxing to other type variables
// variables from unifying to other type variables
// directly (though they may be embedded
// structurally), and we prevent cycles in any case,
// so this recursion should always be of very limited
Expand Down Expand Up @@ -1626,17 +1609,15 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
}

fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
match ct {
ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } => {
if let ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } = ct {
self.infcx.const_unification_table
.borrow_mut()
.probe_value(*vid)
.val
.known()
.map(|c| self.fold_const(c))
.unwrap_or(ct)
}
_ => ct,
} else {
ct
}
}
}
Expand Down
12 changes: 5 additions & 7 deletions src/librustc/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -594,13 +594,11 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
ty: a.ty,
}))
}
(ConstValue::ByRef { .. }, _) => {
bug!(
"non-Scalar ConstValue encountered in super_relate_consts {:?} {:?}",
a,
b,
);
}

// FIXME(const_generics): we should either handle `Scalar::Ptr` or add a comment
// saying that we're not handling it intentionally.

// FIXME(const_generics): handle `ConstValue::ByRef` and `ConstValue::Slice`.

// FIXME(const_generics): this is wrong, as it is a projection
(ConstValue::Unevaluated(a_def_id, a_substs),
Expand Down
6 changes: 6 additions & 0 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1863,6 +1863,12 @@ impl<'tcx> TyS<'tcx> {
}
}

/// Tests if this is any kind of primitive pointer type (reference, raw pointer, fn pointer).
#[inline]
pub fn is_any_ptr(&self) -> bool {
self.is_region_ptr() || self.is_unsafe_ptr() || self.is_fn_ptr()
}

/// Returns `true` if this type is an `Arc<T>`.
#[inline]
pub fn is_arc(&self) -> bool {
Expand Down
9 changes: 1 addition & 8 deletions src/librustc_metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -980,14 +980,7 @@ impl<'a, 'tcx> CrateMetadata {
}

fn get_attributes(&self, item: &Entry<'tcx>, sess: &Session) -> Vec<ast::Attribute> {
item.attributes
.decode((self, sess))
.map(|mut attr| {
// Need new unique IDs: old thread-local IDs won't map to new threads.
attr.id = attr::mk_attr_id();
attr
})
.collect()
item.attributes.decode((self, sess)).collect()
}

// Translate a DefId from the current compilation environment to a DefId
Expand Down
15 changes: 12 additions & 3 deletions src/librustc_mir/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ use rustc_data_structures::fx::FxHashMap;
use syntax::source_map::{Span, DUMMY_SP};

use crate::interpret::{self,
PlaceTy, MPlaceTy, OpTy, ImmTy, Immediate, Scalar,
PlaceTy, MPlaceTy, OpTy, ImmTy, Immediate, Scalar, Pointer,
RawConst, ConstValue,
InterpResult, InterpErrorInfo, InterpError, GlobalId, InterpCx, StackPopCleanup,
Allocation, AllocId, MemoryKind,
Allocation, AllocId, MemoryKind, Memory,
snapshot, RefTracking, intern_const_alloc_recursive,
};

Expand Down Expand Up @@ -397,7 +397,16 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
)
}

fn ptr_op(
fn ptr_to_int(
_mem: &Memory<'mir, 'tcx, Self>,
_ptr: Pointer,
) -> InterpResult<'tcx, u64> {
Err(
ConstEvalError::NeedsRfc("pointer-to-integer cast".to_string()).into(),
)
}

fn binary_ptr_op(
_ecx: &InterpCx<'mir, 'tcx, Self>,
_bin_op: mir::BinOp,
_left: ImmTy<'tcx>,
Expand Down
156 changes: 65 additions & 91 deletions src/librustc_mir/interpret/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,13 @@ use syntax::symbol::sym;
use rustc_apfloat::ieee::{Single, Double};
use rustc_apfloat::{Float, FloatConvert};
use rustc::mir::interpret::{
Scalar, InterpResult, Pointer, PointerArithmetic, InterpError,
Scalar, InterpResult, PointerArithmetic, InterpError,
};
use rustc::mir::CastKind;

use super::{InterpCx, Machine, PlaceTy, OpTy, Immediate, FnVal};
use super::{InterpCx, Machine, PlaceTy, OpTy, ImmTy, Immediate, FnVal};

impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
fn type_is_fat_ptr(&self, ty: Ty<'tcx>) -> bool {
match ty.sty {
ty::RawPtr(ty::TypeAndMut { ty, .. }) |
ty::Ref(_, ty, _) => !self.type_is_sized(ty),
ty::Adt(def, _) if def.is_box() => !self.type_is_sized(ty.boxed_ty()),
_ => false,
}
}

pub fn cast(
&mut self,
src: OpTy<'tcx, M::PointerTag>,
Expand All @@ -37,40 +28,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {

Misc | Pointer(PointerCast::MutToConstPointer) => {
let src = self.read_immediate(src)?;

if self.type_is_fat_ptr(src.layout.ty) {
match (*src, self.type_is_fat_ptr(dest.layout.ty)) {
// pointers to extern types
(Immediate::Scalar(_),_) |
// slices and trait objects to other slices/trait objects
(Immediate::ScalarPair(..), true) => {
// No change to immediate
self.write_immediate(*src, dest)?;
}
// slices and trait objects to thin pointers (dropping the metadata)
(Immediate::ScalarPair(data, _), false) => {
self.write_scalar(data, dest)?;
}
}
} else {
match src.layout.variants {
layout::Variants::Single { index } => {
if let Some(discr) =
src.layout.ty.discriminant_for_variant(*self.tcx, index)
{
// Cast from a univariant enum
assert!(src.layout.is_zst());
return self.write_scalar(
Scalar::from_uint(discr.val, dest.layout.size),
dest);
}
}
layout::Variants::Multiple { .. } => {},
}

let dest_val = self.cast_scalar(src.to_scalar()?, src.layout, dest.layout)?;
self.write_scalar(dest_val, dest)?;
}
let res = self.cast_immediate(src, dest.layout)?;
self.write_immediate(res, dest)?;
}

Pointer(PointerCast::ReifyFnPointer) => {
Expand Down Expand Up @@ -126,36 +85,76 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Ok(())
}

fn cast_scalar(
fn cast_immediate(
&self,
val: Scalar<M::PointerTag>,
src_layout: TyLayout<'tcx>,
src: ImmTy<'tcx, M::PointerTag>,
dest_layout: TyLayout<'tcx>,
) -> InterpResult<'tcx, Scalar<M::PointerTag>> {
) -> InterpResult<'tcx, Immediate<M::PointerTag>> {
use rustc::ty::TyKind::*;
trace!("Casting {:?}: {:?} to {:?}", val, src_layout.ty, dest_layout.ty);
trace!("Casting {:?}: {:?} to {:?}", *src, src.layout.ty, dest_layout.ty);

match src_layout.ty.sty {
match src.layout.ty.sty {
// Floating point
Float(FloatTy::F32) => self.cast_from_float(val.to_f32()?, dest_layout.ty),
Float(FloatTy::F64) => self.cast_from_float(val.to_f64()?, dest_layout.ty),
// Integer(-like), including fn ptr casts and casts from enums that
// are represented as integers (this excludes univariant enums, which
// are handled in `cast` directly).
_ => {
Float(FloatTy::F32) =>
return Ok(self.cast_from_float(src.to_scalar()?.to_f32()?, dest_layout.ty)?.into()),
Float(FloatTy::F64) =>
return Ok(self.cast_from_float(src.to_scalar()?.to_f64()?, dest_layout.ty)?.into()),
// The rest is integer/pointer-"like", including fn ptr casts and casts from enums that
// are represented as integers.
_ =>
assert!(
src_layout.ty.is_bool() || src_layout.ty.is_char() ||
src_layout.ty.is_enum() || src_layout.ty.is_integral() ||
src_layout.ty.is_unsafe_ptr() || src_layout.ty.is_fn_ptr() ||
src_layout.ty.is_region_ptr(),
"Unexpected cast from type {:?}", src_layout.ty
);
match val.to_bits_or_ptr(src_layout.size, self) {
Err(ptr) => self.cast_from_ptr(ptr, src_layout, dest_layout),
Ok(data) => self.cast_from_int(data, src_layout, dest_layout),
src.layout.ty.is_bool() || src.layout.ty.is_char() ||
src.layout.ty.is_enum() || src.layout.ty.is_integral() ||
src.layout.ty.is_any_ptr(),
"Unexpected cast from type {:?}", src.layout.ty
)
}

// Handle cast from a univariant (ZST) enum.
match src.layout.variants {
layout::Variants::Single { index } => {
if let Some(discr) =
src.layout.ty.discriminant_for_variant(*self.tcx, index)
{
assert!(src.layout.is_zst());
return Ok(Scalar::from_uint(discr.val, dest_layout.size).into());
}
}
layout::Variants::Multiple { .. } => {},
}

// Handle casting the metadata away from a fat pointer.
if src.layout.ty.is_unsafe_ptr() && dest_layout.ty.is_unsafe_ptr() &&
dest_layout.size != src.layout.size
{
assert_eq!(src.layout.size, 2*self.memory.pointer_size());
assert_eq!(dest_layout.size, self.memory.pointer_size());
assert!(dest_layout.ty.is_unsafe_ptr());
match *src {
Immediate::ScalarPair(data, _) =>
return Ok(data.into()),
Immediate::Scalar(..) =>
bug!(
"{:?} input to a fat-to-thin cast ({:?} -> {:?})",
*src, src.layout.ty, dest_layout.ty
),
};
}

// Handle casting any ptr to raw ptr (might be a fat ptr).
if src.layout.ty.is_any_ptr() && dest_layout.ty.is_unsafe_ptr()
{
// The only possible size-unequal case was handled above.
assert_eq!(src.layout.size, dest_layout.size);
return Ok(*src);
}

// For all remaining casts, we either
// (a) cast a raw ptr to usize, or
// (b) cast from an integer-like (including bool, char, enums).
// In both cases we want the bits.
let bits = self.force_bits(src.to_scalar()?, src.layout.size)?;
Ok(self.cast_from_int(bits, src.layout, dest_layout)?.into())
}

fn cast_from_int(
Expand Down Expand Up @@ -236,31 +235,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
}

fn cast_from_ptr(
&self,
ptr: Pointer<M::PointerTag>,
src_layout: TyLayout<'tcx>,
dest_layout: TyLayout<'tcx>,
) -> InterpResult<'tcx, Scalar<M::PointerTag>> {
use rustc::ty::TyKind::*;

match dest_layout.ty.sty {
// Casting to a reference or fn pointer is not permitted by rustc,
// no need to support it here.
RawPtr(_) => Ok(ptr.into()),
Int(_) | Uint(_) => {
let size = self.memory.pointer_size();

match self.force_bits(Scalar::Ptr(ptr), size) {
Ok(bits) => self.cast_from_int(bits, src_layout, dest_layout),
Err(_) if dest_layout.size == size => Ok(ptr.into()),
Err(e) => Err(e),
}
}
_ => bug!("invalid MIR: ptr to {:?} cast", dest_layout.ty)
}
}

fn unsize_into_ptr(
&mut self,
src: OpTy<'tcx, M::PointerTag>,
Expand Down
Loading