Change:
In the following, the does the wrong thing: it shallow copies the pointer when the semantics mean it should be making a new allocation and copying the data; there's no indication of this until runtime double-frees/segfaults. Some possible resolutions: do nothing: unsafe code is unsafe have lints for + unsafe pointers have completely disabled on unsafe pointers remove the trait impls for raw pointers
I favor a lint.
(I'm happy to mentor this.)
I'm interested in doing this. I'll find on IRC.

Discussion:
DeprecatedOwnedVector, Warnings, <ins> RawPointerDeriving, </ins> } pub fn level_to_str(lv: level) -> &'static str {

desc: "use of a `~[T]` vector", default: allow, }), <ins> ("raw_pointer_deriving", LintSpec { lint: RawPointerDeriving, desc: "uses of #[deriving] with raw pointers are rarely correct", default: warn, }), </ins> ]; /*

} } <ins> struct RawPtrDerivingVisitor<'a> { cx: &'a Context<'a> } impl<'a> Visitor<()> for RawPtrDerivingVisitor<'a> { fn visit_ty(&mut self, ty: &ast::Ty, _: ()) { static MSG: &'static str = "use of `#[deriving]` with a raw pointer"; match ty.node { ast::TyPtr(..) => self.cx.span_lint(RawPointerDeriving, ty.span, MSG), _ => {} } visit::walk_ty(self, ty, ()); } // explicit override to a no-op to reduce code bloat fn visit_expr(&mut self, _: &ast::Expr, _: ()) {} fn visit_block(&mut self, _: &ast::Block, _: ()) {} } fn check_raw_ptr_deriving(cx: &Context, item: &ast::Item) { if !attr::contains_name(item.attrs.as_slice(), "deriving") { return } match item.node { ast::ItemStruct(..) | ast::ItemEnum(..) => { let mut visitor = RawPtrDerivingVisitor { cx: cx }; visit::walk_item(&mut visitor, item, ()); } _ => {} } } </ins> static crate_attrs: &'static [&'static str] = &[ "crate_type", "feature", "no_start", "no_main", "no_std", "crate_id", "desc", "comment", "license", "copyright", // not used in rustc now

check_heap_item(cx, it); check_missing_doc_item(cx, it); check_attrs_usage(cx, it.attrs.as_slice()); <ins> check_raw_ptr_deriving(cx, it); </ins> cx.visit_ids(|v| v.visit_item(it, ()));

// alive, and using ty::get is unsafe when the ctxt is no longer alive. enum t_opaque {} <ins> #[allow(raw_pointer_deriving)] </ins> #[deriving(Clone, Eq, TotalEq, Hash)] pub struct t { priv inner: *t_opaque }

<ins> // Copyright 2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #[feature(struct_variant)]; #[allow(dead_code)]; #[deny(raw_pointer_deriving)]; #[deriving(Clone)] struct Foo { x: *int //~ ERROR use of `#[deriving]` with a raw pointer } #[deriving(Clone)] struct Bar(*mut int); //~ ERROR use of `#[deriving]` with a raw pointer #[deriving(Clone)] enum Baz { A(*int), //~ ERROR use of `#[deriving]` with a raw pointer B { x: *mut int } //~ ERROR use of `#[deriving]` with a raw pointer } #[deriving(Clone)] struct Buzz { x: (*int, //~ ERROR use of `#[deriving]` with a raw pointer *uint) //~ ERROR use of `#[deriving]` with a raw pointer } fn main() {} </ins>