rather than being implicit quasi-subtyping. Nothing good can come out
of quasi-subtyping.
if let Some(adjustment) = adj {
match adjustment {
adjustment::AdjustReifyFnPointer |
if let Some(adjustment) = adj {
match adjustment {
adjustment::AdjustReifyFnPointer |
- adjustment::AdjustUnsafeFnPointer => {
+ adjustment::AdjustUnsafeFnPointer |
+ adjustment::AdjustMutToConstPointer => {
// Creating a closure/fn-pointer or unsizing consumes
// the input and stores it into the resulting rvalue.
// Creating a closure/fn-pointer or unsizing consumes
// the input and stores it into the resulting rvalue.
- debug!("walk_adjustment(AdjustReifyFnPointer|AdjustUnsafeFnPointer)");
+ debug!("walk_adjustment: trivial adjustment");
let cmt_unadjusted =
return_if_err!(self.mc.cat_expr_unadjusted(expr));
self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
let cmt_unadjusted =
return_if_err!(self.mc.cat_expr_unadjusted(expr));
self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
adjustment::AdjustReifyFnPointer |
adjustment::AdjustUnsafeFnPointer |
adjustment::AdjustReifyFnPointer |
adjustment::AdjustUnsafeFnPointer |
+ adjustment::AdjustMutToConstPointer |
adjustment::AdjustDerefRef(_) => {
debug!("cat_expr({:?}): {:?}",
adjustment,
adjustment::AdjustDerefRef(_) => {
debug!("cat_expr({:?}): {:?}",
adjustment,
#[derive(Copy, Clone)]
pub enum AutoAdjustment<'tcx> {
#[derive(Copy, Clone)]
pub enum AutoAdjustment<'tcx> {
- AdjustReifyFnPointer, // go from a fn-item type to a fn-pointer type
- AdjustUnsafeFnPointer, // go from a safe fn pointer to an unsafe fn pointer
+ AdjustReifyFnPointer, // go from a fn-item type to a fn-pointer type
+ AdjustUnsafeFnPointer, // go from a safe fn pointer to an unsafe fn pointer
+ AdjustMutToConstPointer, // go from a mut raw pointer to a const raw pointer
AdjustDerefRef(AutoDerefRef<'tcx>),
}
AdjustDerefRef(AutoDerefRef<'tcx>),
}
pub fn is_identity(&self) -> bool {
match *self {
AdjustReifyFnPointer |
pub fn is_identity(&self) -> bool {
match *self {
AdjustReifyFnPointer |
- AdjustUnsafeFnPointer => false,
+ AdjustUnsafeFnPointer |
+ AdjustMutToConstPointer => false,
AdjustDerefRef(ref r) => r.is_identity(),
}
}
AdjustDerefRef(ref r) => r.is_identity(),
}
}
return match adjustment {
Some(adjustment) => {
match *adjustment {
return match adjustment {
Some(adjustment) => {
match *adjustment {
- AdjustReifyFnPointer => {
+ AdjustReifyFnPointer => {
match self.sty {
ty::TyBareFn(Some(_), b) => {
cx.mk_fn(None, b)
match self.sty {
ty::TyBareFn(Some(_), b) => {
cx.mk_fn(None, b)
- AdjustUnsafeFnPointer => {
+ AdjustUnsafeFnPointer => {
match self.sty {
ty::TyBareFn(None, b) => cx.safe_to_unsafe_fn_ty(b),
ref b => {
cx.sess.bug(
match self.sty {
ty::TyBareFn(None, b) => cx.safe_to_unsafe_fn_ty(b),
ref b => {
cx.sess.bug(
- &format!("AdjustReifyFnPointer adjustment on non-fn-item: \
+ &format!("AdjustUnsafeFnPointer adjustment on non-fn-ptr: \
+ }
+
+ AdjustMutToConstPointer => {
+ match self.sty {
+ ty::TyRawPtr(mt) => cx.mk_ptr(ty::TypeAndMut {
+ ty: mt.ty,
+ mutbl: hir::MutImmutable
+ }),
+ ref b => {
+ cx.sess.bug(
+ &format!("AdjustMutToConstPointer on non-raw-ptr: \
+ {:?}",
+ b));
+ }
+ }
+ }
AdjustDerefRef(ref adj) => {
let mut adjusted_ty = self;
AdjustDerefRef(ref adj) => {
let mut adjusted_ty = self;
ty::adjustment::AdjustUnsafeFnPointer => {
write!(f, "AdjustUnsafeFnPointer")
}
ty::adjustment::AdjustUnsafeFnPointer => {
write!(f, "AdjustUnsafeFnPointer")
}
+ ty::adjustment::AdjustMutToConstPointer => {
+ write!(f, "AdjustMutToConstPointer")
+ }
ty::adjustment::AdjustDerefRef(ref data) => {
write!(f, "{:?}", data)
}
ty::adjustment::AdjustDerefRef(ref data) => {
write!(f, "{:?}", data)
}
self.emit_enum("AutoAdjustment", |this| {
match *adj {
self.emit_enum("AutoAdjustment", |this| {
match *adj {
- adjustment::AdjustReifyFnPointer=> {
+ adjustment::AdjustReifyFnPointer => {
this.emit_enum_variant("AdjustReifyFnPointer", 1, 0, |_| Ok(()))
}
this.emit_enum_variant("AdjustReifyFnPointer", 1, 0, |_| Ok(()))
}
+ adjustment::AdjustMutToConstPointer => {
+ this.emit_enum_variant("AdjustMutToConstPointer", 3, 0, |_| {
+ Ok(())
+ })
+ }
+
adjustment::AdjustDerefRef(ref auto_deref_ref) => {
adjustment::AdjustDerefRef(ref auto_deref_ref) => {
- this.emit_enum_variant("AdjustDerefRef", 3, 2, |this| {
+ this.emit_enum_variant("AdjustDerefRef", 4, 2, |this| {
this.emit_enum_variant_arg(0,
|this| Ok(this.emit_auto_deref_ref(ecx, auto_deref_ref)))
})
this.emit_enum_variant_arg(0,
|this| Ok(this.emit_auto_deref_ref(ecx, auto_deref_ref)))
})
fn read_auto_adjustment<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-> adjustment::AutoAdjustment<'tcx> {
self.read_enum("AutoAdjustment", |this| {
fn read_auto_adjustment<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-> adjustment::AutoAdjustment<'tcx> {
self.read_enum("AutoAdjustment", |this| {
- let variants = ["AdjustReifyFnPointer", "AdjustUnsafeFnPointer", "AdjustDerefRef"];
+ let variants = ["AdjustReifyFnPointer", "AdjustUnsafeFnPointer",
+ "AdjustMutToConstPointer", "AdjustDerefRef"];
this.read_enum_variant(&variants, |this, i| {
Ok(match i {
1 => adjustment::AdjustReifyFnPointer,
2 => adjustment::AdjustUnsafeFnPointer,
this.read_enum_variant(&variants, |this, i| {
Ok(match i {
1 => adjustment::AdjustReifyFnPointer,
2 => adjustment::AdjustUnsafeFnPointer,
+ 3 => adjustment::AdjustMutToConstPointer,
+ 4 => {
let auto_deref_ref: adjustment::AutoDerefRef =
this.read_enum_variant_arg(0,
|this| Ok(this.read_auto_deref_ref(dcx))).unwrap();
let auto_deref_ref: adjustment::AutoDerefRef =
this.read_enum_variant_arg(0,
|this| Ok(this.read_auto_deref_ref(dcx))).unwrap();
+ debug!("unadjusted-expr={:?} applying adjustments={:?}",
+ expr, cx.tcx.tables.borrow().adjustments.get(&self.id));
+
// Now apply adjustments, if any.
match cx.tcx.tables.borrow().adjustments.get(&self.id) {
None => {}
// Now apply adjustments, if any.
match cx.tcx.tables.borrow().adjustments.get(&self.id) {
None => {}
kind: ExprKind::UnsafeFnPointer { source: expr.to_ref() },
};
}
kind: ExprKind::UnsafeFnPointer { source: expr.to_ref() },
};
}
+ Some(&ty::adjustment::AdjustMutToConstPointer) => {
+ let adjusted_ty = cx.tcx.expr_ty_adjusted(self);
+ expr = Expr {
+ temp_lifetime: temp_lifetime,
+ ty: adjusted_ty,
+ span: self.span,
+ kind: ExprKind::Cast { source: expr.to_ref() },
+ };
+ }
Some(&ty::adjustment::AdjustDerefRef(ref adj)) => {
for i in 0..adj.autoderefs {
let i = i as u32;
Some(&ty::adjustment::AdjustDerefRef(ref adj)) => {
for i in 0..adj.autoderefs {
let i = i as u32;
match v.tcx.tables.borrow().adjustments.get(&e.id) {
None |
Some(&ty::adjustment::AdjustReifyFnPointer) |
match v.tcx.tables.borrow().adjustments.get(&e.id) {
None |
Some(&ty::adjustment::AdjustReifyFnPointer) |
- Some(&ty::adjustment::AdjustUnsafeFnPointer) => {}
+ Some(&ty::adjustment::AdjustUnsafeFnPointer) |
+ Some(&ty::adjustment::AdjustMutToConstPointer) => {}
Some(&ty::adjustment::AdjustDerefRef(
ty::adjustment::AutoDerefRef { autoderefs, .. }
Some(&ty::adjustment::AdjustDerefRef(
ty::adjustment::AutoDerefRef { autoderefs, .. }
use trans::Disr;
use middle::subst::Substs;
use middle::ty::adjustment::{AdjustDerefRef, AdjustReifyFnPointer};
use trans::Disr;
use middle::subst::Substs;
use middle::ty::adjustment::{AdjustDerefRef, AdjustReifyFnPointer};
-use middle::ty::adjustment::AdjustUnsafeFnPointer;
+use middle::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer};
use middle::ty::{self, Ty};
use middle::ty::cast::{CastTy,IntTy};
use util::nodemap::NodeMap;
use middle::ty::{self, Ty};
use middle::ty::cast::{CastTy,IntTy};
use util::nodemap::NodeMap;
// FIXME(#19925) once fn item types are
// zero-sized, we'll need to do something here
}
// FIXME(#19925) once fn item types are
// zero-sized, we'll need to do something here
}
- Some(AdjustUnsafeFnPointer) => {
+ Some(AdjustUnsafeFnPointer) | Some(AdjustMutToConstPointer) => {
// purely a type-level thing
}
Some(AdjustDerefRef(adj)) => {
// purely a type-level thing
}
Some(AdjustDerefRef(adj)) => {
use trans::type_of;
use trans::Disr;
use middle::ty::adjustment::{AdjustDerefRef, AdjustReifyFnPointer};
use trans::type_of;
use trans::Disr;
use middle::ty::adjustment::{AdjustDerefRef, AdjustReifyFnPointer};
-use middle::ty::adjustment::{AdjustUnsafeFnPointer, CustomCoerceUnsized};
+use middle::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer};
+use middle::ty::adjustment::CustomCoerceUnsized;
use middle::ty::{self, Ty};
use middle::ty::MethodCall;
use middle::ty::cast::{CastKind, CastTy};
use middle::ty::{self, Ty};
use middle::ty::MethodCall;
use middle::ty::cast::{CastKind, CastTy};
// zero-sized, we'll need to return true here
false
}
// zero-sized, we'll need to return true here
false
}
- AdjustUnsafeFnPointer => {
+ AdjustUnsafeFnPointer | AdjustMutToConstPointer => {
// purely a type-level thing
false
}
// purely a type-level thing
false
}
// FIXME(#19925) once fn item types are
// zero-sized, we'll need to do something here
}
// FIXME(#19925) once fn item types are
// zero-sized, we'll need to do something here
}
- AdjustUnsafeFnPointer => {
+ AdjustUnsafeFnPointer | AdjustMutToConstPointer => {
// purely a type-level thing
}
AdjustDerefRef(ref adj) => {
// purely a type-level thing
}
AdjustDerefRef(ref adj) => {
use middle::traits::{predicate_for_trait_def, report_selection_error};
use middle::ty::adjustment::{AutoAdjustment, AutoDerefRef, AdjustDerefRef};
use middle::ty::adjustment::{AutoPtr, AutoUnsafe, AdjustReifyFnPointer};
use middle::traits::{predicate_for_trait_def, report_selection_error};
use middle::ty::adjustment::{AutoAdjustment, AutoDerefRef, AdjustDerefRef};
use middle::ty::adjustment::{AutoPtr, AutoUnsafe, AdjustReifyFnPointer};
-use middle::ty::adjustment::{AdjustUnsafeFnPointer};
+use middle::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer};
use middle::ty::{self, LvaluePreference, TypeAndMut, Ty};
use middle::ty::fold::TypeFoldable;
use middle::ty::error::TypeError;
use middle::ty::{self, LvaluePreference, TypeAndMut, Ty};
use middle::ty::fold::TypeFoldable;
use middle::ty::error::TypeError;
autoref: Some(AutoUnsafe(mutbl_b)),
unsize: None
})))
autoref: Some(AutoUnsafe(mutbl_b)),
unsize: None
})))
+ } else if mt_a.mutbl != mutbl_b {
+ Ok(Some(AdjustMutToConstPointer))
adjustment::AdjustReifyFnPointer
}
adjustment::AdjustReifyFnPointer
}
+ adjustment::AdjustMutToConstPointer => {
+ adjustment::AdjustMutToConstPointer
+ }
+
adjustment::AdjustUnsafeFnPointer => {
adjustment::AdjustUnsafeFnPointer
}
adjustment::AdjustUnsafeFnPointer => {
adjustment::AdjustUnsafeFnPointer
}