Skip to content

Implement unsafe trait and unsafe impl from the OIBIT RFC #19703

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

Merged
merged 5 commits into from
Dec 14, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1721,15 +1721,15 @@ impl LintPass for Stability {
if self.is_internal(cx, item.span) { return }

match item.node {
ast::ItemTrait(_, _, ref supertraits, _) => {
ast::ItemTrait(_, _, _, ref supertraits, _) => {
for t in supertraits.iter() {
if let ast::TraitTyParamBound(ref t) = *t {
let id = ty::trait_ref_to_def_id(cx.tcx, &t.trait_ref);
self.lint(cx, id, t.trait_ref.path.span);
}
}
}
ast::ItemImpl(_, Some(ref t), _, _) => {
ast::ItemImpl(_, _, Some(ref t), _, _) => {
let id = ty::trait_ref_to_def_id(cx.tcx, t);
self.lint(cx, id, t.path.span);
}
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/metadata/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,5 @@ pub const tag_method_ty_generics: uint = 0xa7;
pub const tag_predicate: uint = 0xa8;
pub const tag_predicate_space: uint = 0xa9;
pub const tag_predicate_data: uint = 0xb0;

pub const tag_unsafety: uint = 0xb1;
11 changes: 11 additions & 0 deletions src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,15 +361,26 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
}
}

fn parse_unsafety(item_doc: rbml::Doc) -> ast::Unsafety {
let unsafety_doc = reader::get_doc(item_doc, tag_unsafety);
if reader::doc_as_u8(unsafety_doc) != 0 {
ast::Unsafety::Unsafe
} else {
ast::Unsafety::Normal
}
}

pub fn get_trait_def<'tcx>(cdata: Cmd,
item_id: ast::NodeId,
tcx: &ty::ctxt<'tcx>) -> ty::TraitDef<'tcx>
{
let item_doc = lookup_item(item_id, cdata.data());
let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
let bounds = trait_def_bounds(item_doc, tcx, cdata);
let unsafety = parse_unsafety(item_doc);

ty::TraitDef {
unsafety: unsafety,
generics: generics,
bounds: bounds,
trait_ref: Rc::new(item_trait_ref(item_doc, tcx, cdata))
Expand Down
16 changes: 13 additions & 3 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1205,7 +1205,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
None => {}
}
}
ast::ItemImpl(_, ref opt_trait, ref ty, ref ast_items) => {
ast::ItemImpl(unsafety, _, ref opt_trait, ref ty, ref ast_items) => {
// We need to encode information about the default methods we
// have inherited, so we drive this based on the impl structure.
let impl_items = tcx.impl_items.borrow();
Expand All @@ -1218,6 +1218,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id));
encode_name(rbml_w, item.ident.name);
encode_attributes(rbml_w, item.attrs.as_slice());
encode_unsafety(rbml_w, unsafety);
match ty.node {
ast::TyPath(ref path, _) if path.segments
.len() == 1 => {
Expand Down Expand Up @@ -1308,13 +1309,14 @@ fn encode_info_for_item(ecx: &EncodeContext,
}
}
}
ast::ItemTrait(_, _, _, ref ms) => {
ast::ItemTrait(_, _, _, _, ref ms) => {
add_to_index(item, rbml_w, index);
rbml_w.start_tag(tag_items_data_item);
encode_def_id(rbml_w, def_id);
encode_family(rbml_w, 'I');
encode_item_variances(rbml_w, ecx, item.id);
let trait_def = ty::lookup_trait_def(tcx, def_id);
encode_unsafety(rbml_w, trait_def.unsafety);
encode_generics(rbml_w, ecx, &trait_def.generics, tag_item_generics);
encode_trait_ref(rbml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
encode_name(rbml_w, item.ident.name);
Expand Down Expand Up @@ -1674,6 +1676,14 @@ fn encode_attributes(rbml_w: &mut Encoder, attrs: &[ast::Attribute]) {
rbml_w.end_tag();
}

fn encode_unsafety(rbml_w: &mut Encoder, unsafety: ast::Unsafety) {
let byte: u8 = match unsafety {
ast::Unsafety::Normal => 0,
ast::Unsafety::Unsafe => 1,
};
rbml_w.wr_tagged_u8(tag_unsafety, byte);
}

fn encode_crate_deps(rbml_w: &mut Encoder, cstore: &cstore::CStore) {
fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> {
// Pull the cnums and name,vers,hash out of cstore
Expand Down Expand Up @@ -1855,7 +1865,7 @@ struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {

impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'b, 'c, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
if let ast::ItemImpl(_, Some(ref trait_ref), _, _) = item.node {
if let ast::ItemImpl(_, _, Some(ref trait_ref), _, _) = item.node {
let def_map = &self.ecx.tcx.def_map;
let trait_def = def_map.borrow()[trait_ref.ref_id].clone();
let def_id = trait_def.def_id();
Expand Down
16 changes: 8 additions & 8 deletions src/librustc/metadata/tydecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,11 +549,11 @@ fn parse_hex(st: &mut PState) -> uint {
};
}

fn parse_fn_style(c: char) -> ast::FnStyle {
fn parse_unsafety(c: char) -> ast::Unsafety {
match c {
'u' => ast::UnsafeFn,
'n' => ast::NormalFn,
_ => panic!("parse_fn_style: bad fn_style {}", c)
'u' => ast::Unsafety::Unsafe,
'n' => ast::Unsafety::Normal,
_ => panic!("parse_unsafety: bad unsafety {}", c)
}
}

Expand All @@ -575,14 +575,14 @@ fn parse_onceness(c: char) -> ast::Onceness {

fn parse_closure_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>,
conv: conv_did) -> ty::ClosureTy<'tcx> {
let fn_style = parse_fn_style(next(st));
let unsafety = parse_unsafety(next(st));
let onceness = parse_onceness(next(st));
let store = parse_trait_store(st, |x,y| conv(x,y));
let bounds = parse_existential_bounds(st, |x,y| conv(x,y));
let sig = parse_sig(st, |x,y| conv(x,y));
let abi = parse_abi_set(st);
ty::ClosureTy {
fn_style: fn_style,
unsafety: unsafety,
onceness: onceness,
store: store,
bounds: bounds,
Expand All @@ -593,11 +593,11 @@ fn parse_closure_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>,

fn parse_bare_fn_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>,
conv: conv_did) -> ty::BareFnTy<'tcx> {
let fn_style = parse_fn_style(next(st));
let unsafety = parse_unsafety(next(st));
let abi = parse_abi_set(st);
let sig = parse_sig(st, |x,y| conv(x,y));
ty::BareFnTy {
fn_style: fn_style,
unsafety: unsafety,
abi: abi,
sig: sig
}
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/metadata/tyencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,10 @@ fn enc_sty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
}
}

fn enc_fn_style(w: &mut SeekableMemWriter, p: ast::FnStyle) {
fn enc_unsafety(w: &mut SeekableMemWriter, p: ast::Unsafety) {
match p {
ast::NormalFn => mywrite!(w, "n"),
ast::UnsafeFn => mywrite!(w, "u"),
ast::Unsafety::Normal => mywrite!(w, "n"),
ast::Unsafety::Unsafe => mywrite!(w, "u"),
}
}

Expand All @@ -335,14 +335,14 @@ fn enc_onceness(w: &mut SeekableMemWriter, o: ast::Onceness) {

pub fn enc_bare_fn_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
ft: &ty::BareFnTy<'tcx>) {
enc_fn_style(w, ft.fn_style);
enc_unsafety(w, ft.unsafety);
enc_abi(w, ft.abi);
enc_fn_sig(w, cx, &ft.sig);
}

pub fn enc_closure_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
ft: &ty::ClosureTy<'tcx>) {
enc_fn_style(w, ft.fn_style);
enc_unsafety(w, ft.unsafety);
enc_onceness(w, ft.onceness);
enc_trait_store(w, cx, ft.store);
enc_existential_bounds(w, cx, &ft.bounds);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ impl<'v> Visitor<'v> for LifeSeeder {
ast::ItemEnum(ref enum_def, _) if allow_dead_code => {
self.worklist.extend(enum_def.variants.iter().map(|variant| variant.node.id));
}
ast::ItemImpl(_, Some(ref _trait_ref), _, ref impl_items) => {
ast::ItemImpl(_, _, Some(ref _trait_ref), _, ref impl_items) => {
for impl_item in impl_items.iter() {
match *impl_item {
ast::MethodImplItem(ref method) => {
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/effect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ impl Copy for UnsafeContext {}

fn type_is_unsafe_function(ty: Ty) -> bool {
match ty.sty {
ty::ty_bare_fn(ref f) => f.fn_style == ast::UnsafeFn,
ty::ty_closure(ref f) => f.fn_style == ast::UnsafeFn,
ty::ty_bare_fn(ref f) => f.unsafety == ast::Unsafety::Unsafe,
ty::ty_closure(ref f) => f.unsafety == ast::Unsafety::Unsafe,
_ => false,
}
}
Expand Down Expand Up @@ -92,9 +92,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {

let (is_item_fn, is_unsafe_fn) = match fn_kind {
visit::FkItemFn(_, _, fn_style, _) =>
(true, fn_style == ast::UnsafeFn),
(true, fn_style == ast::Unsafety::Unsafe),
visit::FkMethod(_, _, method) =>
(true, method.pe_fn_style() == ast::UnsafeFn),
(true, method.pe_unsafety() == ast::Unsafety::Unsafe),
_ => (false, false),
};

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/infer/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
debug!("coerce_from_bare_fn(a={}, b={})",
a.repr(self.get_ref().infcx.tcx), b.repr(self.get_ref().infcx.tcx));

if fn_ty_a.abi != abi::Rust || fn_ty_a.fn_style != ast::NormalFn {
if fn_ty_a.abi != abi::Rust || fn_ty_a.unsafety != ast::Unsafety::Normal {
return self.subtype(a, b);
}

Expand Down
16 changes: 8 additions & 8 deletions src/librustc/middle/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ use middle::ty_fold;
use middle::ty_fold::{TypeFoldable};
use util::ppaux::Repr;

use syntax::ast::{Onceness, FnStyle};
use syntax::ast::{Onceness, Unsafety};
use syntax::ast;
use syntax::abi;
use syntax::codemap::Span;
Expand Down Expand Up @@ -193,12 +193,12 @@ pub trait Combine<'tcx> {

fn bare_fn_tys(&self, a: &ty::BareFnTy<'tcx>,
b: &ty::BareFnTy<'tcx>) -> cres<'tcx, ty::BareFnTy<'tcx>> {
let fn_style = try!(self.fn_styles(a.fn_style, b.fn_style));
let unsafety = try!(self.unsafeties(a.unsafety, b.unsafety));
let abi = try!(self.abi(a.abi, b.abi));
let sig = try!(self.fn_sigs(&a.sig, &b.sig));
Ok(ty::BareFnTy {fn_style: fn_style,
abi: abi,
sig: sig})
Ok(ty::BareFnTy {unsafety: unsafety,
abi: abi,
sig: sig})
}

fn closure_tys(&self, a: &ty::ClosureTy<'tcx>,
Expand All @@ -219,13 +219,13 @@ pub trait Combine<'tcx> {
return Err(ty::terr_sigil_mismatch(expected_found(self, a.store, b.store)))
}
};
let fn_style = try!(self.fn_styles(a.fn_style, b.fn_style));
let unsafety = try!(self.unsafeties(a.unsafety, b.unsafety));
let onceness = try!(self.oncenesses(a.onceness, b.onceness));
let bounds = try!(self.existential_bounds(a.bounds, b.bounds));
let sig = try!(self.fn_sigs(&a.sig, &b.sig));
let abi = try!(self.abi(a.abi, b.abi));
Ok(ty::ClosureTy {
fn_style: fn_style,
unsafety: unsafety,
onceness: onceness,
store: store,
bounds: bounds,
Expand All @@ -240,7 +240,7 @@ pub trait Combine<'tcx> {
self.contratys(a, b).and_then(|t| Ok(t))
}

fn fn_styles(&self, a: FnStyle, b: FnStyle) -> cres<'tcx, FnStyle>;
fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety>;

fn abi(&self, a: abi::Abi, b: abi::Abi) -> cres<'tcx, abi::Abi> {
if a == b {
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/infer/equate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use middle::infer::{TypeTrace, Subtype};
use middle::infer::type_variable::{EqTo};
use util::ppaux::{Repr};

use syntax::ast::{Onceness, FnStyle};
use syntax::ast::{Onceness, Unsafety};

pub struct Equate<'f, 'tcx: 'f> {
fields: CombineFields<'f, 'tcx>
Expand Down Expand Up @@ -70,9 +70,9 @@ impl<'f, 'tcx> Combine<'tcx> for Equate<'f, 'tcx> {
Ok(ty::mt { mutbl: a.mutbl, ty: t })
}

fn fn_styles(&self, a: FnStyle, b: FnStyle) -> cres<'tcx, FnStyle> {
fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> {
if a != b {
Err(ty::terr_fn_style_mismatch(expected_found(self, a, b)))
Err(ty::terr_unsafety_mismatch(expected_found(self, a, b)))
} else {
Ok(a)
}
Expand Down
16 changes: 8 additions & 8 deletions src/librustc/middle/infer/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ trait ErrorReportingHelpers<'tcx> {

fn give_expl_lifetime_param(&self,
decl: &ast::FnDecl,
fn_style: ast::FnStyle,
unsafety: ast::Unsafety,
ident: ast::Ident,
opt_explicit_self: Option<&ast::ExplicitSelf_>,
generics: &ast::Generics,
Expand Down Expand Up @@ -828,7 +828,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
ast::MethodImplItem(ref m) => {
Some((m.pe_fn_decl(),
m.pe_generics(),
m.pe_fn_style(),
m.pe_unsafety(),
m.pe_ident(),
Some(&m.pe_explicit_self().node),
m.span))
Expand All @@ -841,7 +841,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
ast::ProvidedMethod(ref m) => {
Some((m.pe_fn_decl(),
m.pe_generics(),
m.pe_fn_style(),
m.pe_unsafety(),
m.pe_ident(),
Some(&m.pe_explicit_self().node),
m.span))
Expand All @@ -853,14 +853,14 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
},
None => None
};
let (fn_decl, generics, fn_style, ident, expl_self, span)
let (fn_decl, generics, unsafety, ident, expl_self, span)
= node_inner.expect("expect item fn");
let taken = lifetimes_in_scope(self.tcx, scope_id);
let life_giver = LifeGiver::with_taken(taken.as_slice());
let rebuilder = Rebuilder::new(self.tcx, fn_decl, expl_self,
generics, same_regions, &life_giver);
let (fn_decl, expl_self, generics) = rebuilder.rebuild();
self.give_expl_lifetime_param(&fn_decl, fn_style, ident,
self.give_expl_lifetime_param(&fn_decl, unsafety, ident,
expl_self.as_ref(), &generics, span);
}
}
Expand Down Expand Up @@ -1407,12 +1407,12 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
fn give_expl_lifetime_param(&self,
decl: &ast::FnDecl,
fn_style: ast::FnStyle,
unsafety: ast::Unsafety,
ident: ast::Ident,
opt_explicit_self: Option<&ast::ExplicitSelf_>,
generics: &ast::Generics,
span: codemap::Span) {
let suggested_fn = pprust::fun_to_string(decl, fn_style, ident,
let suggested_fn = pprust::fun_to_string(decl, unsafety, ident,
opt_explicit_self, generics);
let msg = format!("consider using an explicit lifetime \
parameter as shown: {}", suggested_fn);
Expand Down Expand Up @@ -1690,7 +1690,7 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
match tcx.map.find(parent) {
Some(node) => match node {
ast_map::NodeItem(item) => match item.node {
ast::ItemImpl(ref gen, _, _, _) => {
ast::ItemImpl(_, ref gen, _, _, _) => {
taken.push_all(gen.lifetimes.as_slice());
}
_ => ()
Expand Down
9 changes: 4 additions & 5 deletions src/librustc/middle/infer/glb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ use super::{TypeTrace, Subtype};
use middle::ty::{BuiltinBounds};
use middle::ty::{mod, Ty};
use syntax::ast::{Many, Once, MutImmutable, MutMutable};
use syntax::ast::{NormalFn, UnsafeFn};
use syntax::ast::{Onceness, FnStyle};
use syntax::ast::{Onceness, Unsafety};
use util::ppaux::mt_to_string;
use util::ppaux::Repr;

Expand Down Expand Up @@ -81,10 +80,10 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
self.lub().tys(a, b)
}

fn fn_styles(&self, a: FnStyle, b: FnStyle) -> cres<'tcx, FnStyle> {
fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> {
match (a, b) {
(NormalFn, _) | (_, NormalFn) => Ok(NormalFn),
(UnsafeFn, UnsafeFn) => Ok(UnsafeFn)
(Unsafety::Normal, _) | (_, Unsafety::Normal) => Ok(Unsafety::Normal),
(Unsafety::Unsafe, Unsafety::Unsafe) => Ok(Unsafety::Unsafe)
}
}

Expand Down
Loading