Auto merge of #33965 - Manishearth:rollup, r=Manishearth
Rollup of 5 pull requests - Successful merges: #33867, #33926, #33942, #33958, #33964 - Failed merges:
This commit is contained in:
commit
f3bfa313ec
@ -117,6 +117,7 @@ from xml.etree import cElementTree as ET
|
||||
from htmlentitydefs import entitydefs
|
||||
entitydefs['larrb'] = u'\u21e4'
|
||||
entitydefs['rarrb'] = u'\u21e5'
|
||||
entitydefs['nbsp'] = ' '
|
||||
|
||||
# "void elements" (no closing tag) from the HTML Standard section 12.1.2
|
||||
VOID_ELEMENTS = set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen',
|
||||
|
@ -63,7 +63,7 @@
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Resolutions {
|
||||
pub def_map: RefCell<DefMap>,
|
||||
pub def_map: DefMap,
|
||||
pub freevars: FreevarMap,
|
||||
pub trait_map: TraitMap,
|
||||
pub maybe_unused_trait_imports: NodeSet,
|
||||
@ -818,7 +818,7 @@ pub fn lower_and_resolve<'a>(sess: &Session,
|
||||
name: &id,
|
||||
glob_map: if resolver.make_glob_map { Some(resolver.glob_map) } else { None },
|
||||
}, Resolutions {
|
||||
def_map: RefCell::new(resolver.def_map),
|
||||
def_map: resolver.def_map,
|
||||
freevars: resolver.freevars,
|
||||
trait_map: resolver.trait_map,
|
||||
maybe_unused_trait_imports: resolver.maybe_unused_trait_imports,
|
||||
@ -866,7 +866,7 @@ macro_rules! try_with_f {
|
||||
"lifetime resolution",
|
||||
|| middle::resolve_lifetime::krate(sess,
|
||||
&hir_map,
|
||||
&resolutions.def_map.borrow()))?;
|
||||
&resolutions.def_map))?;
|
||||
|
||||
time(time_passes,
|
||||
"looking for entry point",
|
||||
@ -886,14 +886,14 @@ macro_rules! try_with_f {
|
||||
|
||||
time(time_passes,
|
||||
"static item recursion checking",
|
||||
|| static_recursion::check_crate(sess, &resolutions.def_map.borrow(), &hir_map))?;
|
||||
|| static_recursion::check_crate(sess, &resolutions.def_map, &hir_map))?;
|
||||
|
||||
let index = stability::Index::new(&hir_map);
|
||||
|
||||
let trait_map = resolutions.trait_map;
|
||||
TyCtxt::create_and_enter(sess,
|
||||
arenas,
|
||||
resolutions.def_map,
|
||||
RefCell::new(resolutions.def_map),
|
||||
named_region_map,
|
||||
hir_map,
|
||||
resolutions.freevars,
|
||||
|
@ -29,6 +29,7 @@
|
||||
use rustc_metadata::creader::read_local_crates;
|
||||
use rustc::hir::map as hir_map;
|
||||
use rustc::session::{self, config};
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use syntax::ast;
|
||||
use syntax::abi::Abi;
|
||||
@ -134,12 +135,12 @@ fn test_env<F>(source_string: &str,
|
||||
|
||||
// run just enough stuff to build a tcx:
|
||||
let lang_items = lang_items::collect_language_items(&sess, &ast_map);
|
||||
let named_region_map = resolve_lifetime::krate(&sess, &ast_map, &resolutions.def_map.borrow());
|
||||
let named_region_map = resolve_lifetime::krate(&sess, &ast_map, &resolutions.def_map);
|
||||
let region_map = region::resolve_crate(&sess, &ast_map);
|
||||
let index = stability::Index::new(&ast_map);
|
||||
TyCtxt::create_and_enter(&sess,
|
||||
&arenas,
|
||||
resolutions.def_map,
|
||||
RefCell::new(resolutions.def_map),
|
||||
named_region_map.unwrap(),
|
||||
ast_map,
|
||||
resolutions.freevars,
|
||||
|
@ -18,7 +18,9 @@
|
||||
use std::slice;
|
||||
use std::str;
|
||||
|
||||
pub struct ArchiveRO { ptr: ArchiveRef }
|
||||
pub struct ArchiveRO {
|
||||
ptr: ArchiveRef,
|
||||
}
|
||||
|
||||
pub struct Iter<'a> {
|
||||
archive: &'a ArchiveRO,
|
||||
@ -61,11 +63,16 @@ fn path2cstr(p: &Path) -> CString {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> ArchiveRef { self.ptr }
|
||||
pub fn raw(&self) -> ArchiveRef {
|
||||
self.ptr
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> Iter {
|
||||
unsafe {
|
||||
Iter { ptr: ::LLVMRustArchiveIteratorNew(self.ptr), archive: self }
|
||||
Iter {
|
||||
ptr: ::LLVMRustArchiveIteratorNew(self.ptr),
|
||||
archive: self,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -86,7 +93,10 @@ fn next(&mut self) -> Option<Result<Child<'a>, String>> {
|
||||
if ptr.is_null() {
|
||||
::last_error().map(Err)
|
||||
} else {
|
||||
Some(Ok(Child { ptr: ptr, _data: marker::PhantomData }))
|
||||
Some(Ok(Child {
|
||||
ptr: ptr,
|
||||
_data: marker::PhantomData,
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -107,8 +117,7 @@ pub fn name(&self) -> Option<&'a str> {
|
||||
if name_ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
let name = slice::from_raw_parts(name_ptr as *const u8,
|
||||
name_len as usize);
|
||||
let name = slice::from_raw_parts(name_ptr as *const u8, name_len as usize);
|
||||
str::from_utf8(name).ok().map(|s| s.trim())
|
||||
}
|
||||
}
|
||||
@ -125,11 +134,15 @@ pub fn data(&self) -> &'a [u8] {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> ::ArchiveChildRef { self.ptr }
|
||||
pub fn raw(&self) -> ::ArchiveChildRef {
|
||||
self.ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for Child<'a> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { ::LLVMRustArchiveChildFree(self.ptr); }
|
||||
unsafe {
|
||||
::LLVMRustArchiveChildFree(self.ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,20 +21,25 @@ fn main() {
|
||||
println!("cargo:rustc-cfg=cargobuild");
|
||||
|
||||
let target = env::var("TARGET").unwrap();
|
||||
let llvm_config = env::var_os("LLVM_CONFIG").map(PathBuf::from)
|
||||
.unwrap_or_else(|| {
|
||||
match env::var_os("CARGO_TARGET_DIR").map(PathBuf::from) {
|
||||
Some(dir) => {
|
||||
let to_test = dir.parent().unwrap().parent().unwrap()
|
||||
.join(&target).join("llvm/bin/llvm-config");
|
||||
if Command::new(&to_test).output().is_ok() {
|
||||
return to_test
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
PathBuf::from("llvm-config")
|
||||
});
|
||||
let llvm_config = env::var_os("LLVM_CONFIG")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| {
|
||||
match env::var_os("CARGO_TARGET_DIR").map(PathBuf::from) {
|
||||
Some(dir) => {
|
||||
let to_test = dir.parent()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join(&target)
|
||||
.join("llvm/bin/llvm-config");
|
||||
if Command::new(&to_test).output().is_ok() {
|
||||
return to_test;
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
PathBuf::from("llvm-config")
|
||||
});
|
||||
|
||||
println!("cargo:rerun-if-changed={}", llvm_config.display());
|
||||
|
||||
@ -63,20 +68,22 @@ fn main() {
|
||||
let host = env::var("HOST").unwrap();
|
||||
let is_crossed = target != host;
|
||||
|
||||
let optional_components = ["x86", "arm", "aarch64", "mips", "powerpc",
|
||||
"pnacl"];
|
||||
let optional_components = ["x86", "arm", "aarch64", "mips", "powerpc", "pnacl"];
|
||||
|
||||
// FIXME: surely we don't need all these components, right? Stuff like mcjit
|
||||
// or interpreter the compiler itself never uses.
|
||||
let required_components = &["ipo", "bitreader", "bitwriter", "linker",
|
||||
"asmparser", "mcjit", "interpreter",
|
||||
let required_components = &["ipo",
|
||||
"bitreader",
|
||||
"bitwriter",
|
||||
"linker",
|
||||
"asmparser",
|
||||
"mcjit",
|
||||
"interpreter",
|
||||
"instrumentation"];
|
||||
|
||||
let components = output(Command::new(&llvm_config).arg("--components"));
|
||||
let mut components = components.split_whitespace().collect::<Vec<_>>();
|
||||
components.retain(|c| {
|
||||
optional_components.contains(c) || required_components.contains(c)
|
||||
});
|
||||
components.retain(|c| optional_components.contains(c) || required_components.contains(c));
|
||||
|
||||
for component in required_components {
|
||||
if !components.contains(component) {
|
||||
@ -96,7 +103,7 @@ fn main() {
|
||||
for flag in cxxflags.split_whitespace() {
|
||||
// Ignore flags like `-m64` when we're doing a cross build
|
||||
if is_crossed && flag.starts_with("-m") {
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
cfg.flag(flag);
|
||||
}
|
||||
@ -131,7 +138,7 @@ fn main() {
|
||||
} else if lib.starts_with("-") {
|
||||
&lib[1..]
|
||||
} else {
|
||||
continue
|
||||
continue;
|
||||
};
|
||||
|
||||
// Don't need or want this library, but LLVM's CMake build system
|
||||
@ -140,10 +147,14 @@ fn main() {
|
||||
// library and it otherwise may just pull in extra dependencies on
|
||||
// libedit which we don't want
|
||||
if name == "LLVMLineEditor" {
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
|
||||
let kind = if name.starts_with("LLVM") {"static"} else {"dylib"};
|
||||
let kind = if name.starts_with("LLVM") {
|
||||
"static"
|
||||
} else {
|
||||
"dylib"
|
||||
};
|
||||
println!("cargo:rustc-link-lib={}={}", kind, name);
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
use libc::{c_char, c_uint};
|
||||
use std::ptr;
|
||||
|
||||
use {ValueRef, TwineRef, DebugLocRef, DiagnosticInfoRef};
|
||||
use {DebugLocRef, DiagnosticInfoRef, TwineRef, ValueRef};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum OptimizationDiagnosticKind {
|
||||
@ -46,8 +46,9 @@ pub struct OptimizationDiagnostic {
|
||||
}
|
||||
|
||||
impl OptimizationDiagnostic {
|
||||
unsafe fn unpack(kind: OptimizationDiagnosticKind, di: DiagnosticInfoRef)
|
||||
-> OptimizationDiagnostic {
|
||||
unsafe fn unpack(kind: OptimizationDiagnosticKind,
|
||||
di: DiagnosticInfoRef)
|
||||
-> OptimizationDiagnostic {
|
||||
|
||||
let mut opt = OptimizationDiagnostic {
|
||||
kind: kind,
|
||||
@ -58,10 +59,10 @@ unsafe fn unpack(kind: OptimizationDiagnosticKind, di: DiagnosticInfoRef)
|
||||
};
|
||||
|
||||
super::LLVMUnpackOptimizationDiagnostic(di,
|
||||
&mut opt.pass_name,
|
||||
&mut opt.function,
|
||||
&mut opt.debug_loc,
|
||||
&mut opt.message);
|
||||
&mut opt.pass_name,
|
||||
&mut opt.function,
|
||||
&mut opt.debug_loc,
|
||||
&mut opt.message);
|
||||
|
||||
opt
|
||||
}
|
||||
@ -75,8 +76,7 @@ pub struct InlineAsmDiagnostic {
|
||||
}
|
||||
|
||||
impl InlineAsmDiagnostic {
|
||||
unsafe fn unpack(di: DiagnosticInfoRef)
|
||||
-> InlineAsmDiagnostic {
|
||||
unsafe fn unpack(di: DiagnosticInfoRef) -> InlineAsmDiagnostic {
|
||||
|
||||
let mut opt = InlineAsmDiagnostic {
|
||||
cookie: 0,
|
||||
@ -85,9 +85,9 @@ unsafe fn unpack(di: DiagnosticInfoRef)
|
||||
};
|
||||
|
||||
super::LLVMUnpackInlineAsmDiagnostic(di,
|
||||
&mut opt.cookie,
|
||||
&mut opt.message,
|
||||
&mut opt.instruction);
|
||||
&mut opt.cookie,
|
||||
&mut opt.message,
|
||||
&mut opt.instruction);
|
||||
|
||||
opt
|
||||
}
|
||||
@ -106,22 +106,25 @@ pub unsafe fn unpack(di: DiagnosticInfoRef) -> Diagnostic {
|
||||
let kind = super::LLVMGetDiagInfoKind(di);
|
||||
|
||||
match kind {
|
||||
super::DK_InlineAsm
|
||||
=> InlineAsm(InlineAsmDiagnostic::unpack(di)),
|
||||
super::DK_InlineAsm => InlineAsm(InlineAsmDiagnostic::unpack(di)),
|
||||
|
||||
super::DK_OptimizationRemark
|
||||
=> Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di)),
|
||||
super::DK_OptimizationRemark => {
|
||||
Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di))
|
||||
}
|
||||
|
||||
super::DK_OptimizationRemarkMissed
|
||||
=> Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di)),
|
||||
super::DK_OptimizationRemarkMissed => {
|
||||
Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di))
|
||||
}
|
||||
|
||||
super::DK_OptimizationRemarkAnalysis
|
||||
=> Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di)),
|
||||
super::DK_OptimizationRemarkAnalysis => {
|
||||
Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di))
|
||||
}
|
||||
|
||||
super::DK_OptimizationFailure
|
||||
=> Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di)),
|
||||
super::DK_OptimizationFailure => {
|
||||
Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di))
|
||||
}
|
||||
|
||||
_ => UnknownDiagnostic(di)
|
||||
_ => UnknownDiagnostic(di),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,27 +111,27 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
||||
for (i, life) in self.lifetimes.iter().enumerate() {
|
||||
if i > 0 {
|
||||
f.write_str(", ")?;
|
||||
f.write_str(", ")?;
|
||||
}
|
||||
write!(f, "{}", *life)?;
|
||||
}
|
||||
|
||||
if !self.type_params.is_empty() {
|
||||
if !self.lifetimes.is_empty() {
|
||||
f.write_str(", ")?;
|
||||
f.write_str(", ")?;
|
||||
}
|
||||
for (i, tp) in self.type_params.iter().enumerate() {
|
||||
if i > 0 {
|
||||
f.write_str(", ")?
|
||||
f.write_str(", ")?
|
||||
}
|
||||
f.write_str(&tp.name)?;
|
||||
|
||||
if !tp.bounds.is_empty() {
|
||||
write!(f, ": {}", TyParamBounds(&tp.bounds))?;
|
||||
write!(f, ": {}", TyParamBounds(&tp.bounds))?;
|
||||
}
|
||||
|
||||
match tp.default {
|
||||
Some(ref ty) => { write!(f, " = {}", ty)?; },
|
||||
Some(ref ty) => { write!(f, " = {}", ty)?; },
|
||||
None => {}
|
||||
};
|
||||
}
|
||||
@ -229,21 +229,21 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut comma = false;
|
||||
for lifetime in lifetimes {
|
||||
if comma {
|
||||
f.write_str(", ")?;
|
||||
f.write_str(", ")?;
|
||||
}
|
||||
comma = true;
|
||||
write!(f, "{}", *lifetime)?;
|
||||
}
|
||||
for ty in types {
|
||||
if comma {
|
||||
f.write_str(", ")?;
|
||||
f.write_str(", ")?;
|
||||
}
|
||||
comma = true;
|
||||
write!(f, "{}", *ty)?;
|
||||
}
|
||||
for binding in bindings {
|
||||
if comma {
|
||||
f.write_str(", ")?;
|
||||
f.write_str(", ")?;
|
||||
}
|
||||
comma = true;
|
||||
write!(f, "{}", *binding)?;
|
||||
|
@ -2243,26 +2243,24 @@ fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||
write!(w, "</pre>")?;
|
||||
|
||||
document(w, cx, it)?;
|
||||
let mut fields = s.fields.iter().filter(|f| {
|
||||
let mut fields = s.fields.iter().filter_map(|f| {
|
||||
match f.inner {
|
||||
clean::StructFieldItem(..) => true,
|
||||
_ => false,
|
||||
clean::StructFieldItem(ref ty) => Some((f, ty)),
|
||||
_ => None,
|
||||
}
|
||||
}).peekable();
|
||||
if let doctree::Plain = s.struct_type {
|
||||
if fields.peek().is_some() {
|
||||
write!(w, "<h2 class='fields'>Fields</h2>\n<table>")?;
|
||||
for field in fields {
|
||||
write!(w, "<tr class='stab {stab}'>
|
||||
<td id='{shortty}.{name}'>\
|
||||
<code>{name}</code></td><td>",
|
||||
write!(w, "<h2 class='fields'>Fields</h2>")?;
|
||||
for (field, ty) in fields {
|
||||
write!(w, "<span id='{shortty}.{name}'><code>{name}: {ty}</code></span>
|
||||
<span class='stab {stab}'></span>",
|
||||
shortty = ItemType::StructField,
|
||||
stab = field.stability_class(),
|
||||
name = field.name.as_ref().unwrap())?;
|
||||
name = field.name.as_ref().unwrap(),
|
||||
ty = ty)?;
|
||||
document(w, cx, field)?;
|
||||
write!(w, "</td></tr>")?;
|
||||
}
|
||||
write!(w, "</table>")?;
|
||||
}
|
||||
}
|
||||
render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
|
||||
@ -2292,7 +2290,7 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||
write!(w, "{}(", name)?;
|
||||
for (i, ty) in tys.iter().enumerate() {
|
||||
if i > 0 {
|
||||
write!(w, ", ")?
|
||||
write!(w, ", ")?
|
||||
}
|
||||
write!(w, "{}", *ty)?;
|
||||
}
|
||||
@ -2324,40 +2322,47 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||
|
||||
document(w, cx, it)?;
|
||||
if !e.variants.is_empty() {
|
||||
write!(w, "<h2 class='variants'>Variants</h2>\n<table class='variants_table'>")?;
|
||||
write!(w, "<h2 class='variants'>Variants</h2>\n")?;
|
||||
for variant in &e.variants {
|
||||
write!(w, "<tr><td id='{shortty}.{name}'><code>{name}</code></td><td>",
|
||||
write!(w, "<span id='{shortty}.{name}' class='variant'><code>{name}",
|
||||
shortty = ItemType::Variant,
|
||||
name = variant.name.as_ref().unwrap())?;
|
||||
if let clean::VariantItem(ref var) = variant.inner {
|
||||
if let clean::TupleVariant(ref tys) = var.kind {
|
||||
write!(w, "(")?;
|
||||
for (i, ty) in tys.iter().enumerate() {
|
||||
if i > 0 {
|
||||
write!(w, ", ")?;
|
||||
}
|
||||
write!(w, "{}", *ty)?;
|
||||
}
|
||||
write!(w, ")")?;
|
||||
}
|
||||
}
|
||||
write!(w, "</code></span>")?;
|
||||
document(w, cx, variant)?;
|
||||
|
||||
use clean::{Variant, StructVariant};
|
||||
if let clean::VariantItem( Variant { kind: StructVariant(ref s) } ) = variant.inner {
|
||||
let fields = s.fields.iter().filter(|f| {
|
||||
match f.inner {
|
||||
clean::StructFieldItem(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
});
|
||||
write!(w, "<h3 class='fields'>Fields</h3>\n
|
||||
<table>")?;
|
||||
for field in fields {
|
||||
write!(w, "<tr><td \
|
||||
id='{shortty}.{v}.field.{f}'>\
|
||||
<code>{f}</code></td><td>",
|
||||
shortty = ItemType::Variant,
|
||||
v = variant.name.as_ref().unwrap(),
|
||||
f = field.name.as_ref().unwrap())?;
|
||||
document(w, cx, field)?;
|
||||
write!(w, "</td></tr>")?;
|
||||
for field in &s.fields {
|
||||
use clean::StructFieldItem;
|
||||
if let StructFieldItem(ref ty) = field.inner {
|
||||
write!(w, "<tr><td \
|
||||
id='variant.{v}.field.{f}'>\
|
||||
<code>{f}: {t}</code></td><td>",
|
||||
v = variant.name.as_ref().unwrap(),
|
||||
f = field.name.as_ref().unwrap(),
|
||||
t = *ty)?;
|
||||
document(w, cx, field)?;
|
||||
write!(w, "</td></tr>")?;
|
||||
}
|
||||
}
|
||||
write!(w, "</table>")?;
|
||||
}
|
||||
write!(w, "</td><td>")?;
|
||||
render_stability_since(w, variant, it)?;
|
||||
write!(w, "</td></tr>")?;
|
||||
}
|
||||
write!(w, "</table>")?;
|
||||
}
|
||||
render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)?;
|
||||
Ok(())
|
||||
|
@ -265,6 +265,10 @@ nav.sub {
|
||||
.docblock h2 { font-size: 1.15em; }
|
||||
.docblock h3, .docblock h4, .docblock h5 { font-size: 1em; }
|
||||
|
||||
.docblock {
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
.content .out-of-band {
|
||||
font-size: 23px;
|
||||
margin: 0px;
|
||||
@ -640,6 +644,21 @@ span.since {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.enum > .toggle-wrapper > .collapse-toggle, .struct > .toggle-wrapper > .collapse-toggle {
|
||||
left: 0;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.enum > .toggle-wrapper + .docblock, .struct > .toggle-wrapper + .docblock {
|
||||
margin-left: 30px;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.enum > .collapsed, .struct > .collapsed {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
:target > code {
|
||||
background: #FDFFD3;
|
||||
}
|
||||
|
@ -1338,10 +1338,10 @@ pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
|
||||
///
|
||||
/// // one possible implementation of walking a directory only visiting files
|
||||
/// fn visit_dirs(dir: &Path, cb: &Fn(&DirEntry)) -> io::Result<()> {
|
||||
/// if try!(fs::metadata(dir)).is_dir() {
|
||||
/// if dir.is_dir() {
|
||||
/// for entry in try!(fs::read_dir(dir)) {
|
||||
/// let entry = try!(entry);
|
||||
/// if try!(fs::metadata(entry.path())).is_dir() {
|
||||
/// if try!(entry.file_type()).is_dir() {
|
||||
/// try!(visit_dirs(&entry.path(), cb));
|
||||
/// } else {
|
||||
/// cb(&entry);
|
||||
|
@ -201,7 +201,7 @@
|
||||
use syntax::codemap::Span;
|
||||
use syntax::errors::Handler;
|
||||
use syntax::util::move_map::MoveMap;
|
||||
use syntax::parse::token::{intern, keywords, InternedString};
|
||||
use syntax::parse::token::{keywords, InternedString};
|
||||
use syntax::ptr::P;
|
||||
|
||||
use self::ty::{LifetimeBounds, Path, Ptr, PtrTy, Self_, Ty};
|
||||
@ -1420,31 +1420,13 @@ fn expand_static_enum_method_body(&self,
|
||||
|
||||
// general helper methods.
|
||||
impl<'a> TraitDef<'a> {
|
||||
fn set_expn_info(&self,
|
||||
cx: &mut ExtCtxt,
|
||||
mut to_set: Span) -> Span {
|
||||
let trait_name = match self.path.path.last() {
|
||||
None => cx.span_bug(self.span, "trait with empty path in generic `derive`"),
|
||||
Some(name) => *name
|
||||
};
|
||||
to_set.expn_id = cx.codemap().record_expansion(codemap::ExpnInfo {
|
||||
call_site: to_set,
|
||||
callee: codemap::NameAndSpan {
|
||||
format: codemap::MacroAttribute(intern(&format!("derive({})", trait_name))),
|
||||
span: Some(self.span),
|
||||
allow_internal_unstable: false,
|
||||
}
|
||||
});
|
||||
to_set
|
||||
}
|
||||
|
||||
fn summarise_struct(&self,
|
||||
cx: &mut ExtCtxt,
|
||||
struct_def: &VariantData) -> StaticFields {
|
||||
let mut named_idents = Vec::new();
|
||||
let mut just_spans = Vec::new();
|
||||
for field in struct_def.fields(){
|
||||
let sp = self.set_expn_info(cx, field.span);
|
||||
let sp = Span { expn_id: self.span.expn_id, ..field.span };
|
||||
match field.ident {
|
||||
Some(ident) => named_idents.push((ident, sp)),
|
||||
_ => just_spans.push(sp),
|
||||
@ -1486,7 +1468,7 @@ fn create_struct_pattern(&self,
|
||||
let mut paths = Vec::new();
|
||||
let mut ident_exprs = Vec::new();
|
||||
for (i, struct_field) in struct_def.fields().iter().enumerate() {
|
||||
let sp = self.set_expn_info(cx, struct_field.span);
|
||||
let sp = Span { expn_id: self.span.expn_id, ..struct_field.span };
|
||||
let ident = cx.ident_of(&format!("{}_{}", prefix, i));
|
||||
paths.push(codemap::Spanned{span: sp, node: ident});
|
||||
let val = cx.expr_deref(sp, cx.expr_path(cx.path_ident(sp,ident)));
|
||||
|
@ -16,7 +16,7 @@
|
||||
use syntax::ext::base::{MultiDecorator, MultiItemDecorator, MultiModifier};
|
||||
use syntax::ext::build::AstBuilder;
|
||||
use syntax::feature_gate;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::codemap::{self, Span};
|
||||
use syntax::parse::token::{intern, intern_and_get_ident};
|
||||
use syntax::ptr::P;
|
||||
|
||||
@ -94,37 +94,7 @@ fn expand_derive(cx: &mut ExtCtxt,
|
||||
}
|
||||
|
||||
let mut found_partial_eq = false;
|
||||
let mut found_eq = false;
|
||||
|
||||
// This span is **very** sensitive and crucial to
|
||||
// getting the stability behavior we want. What we are
|
||||
// doing is marking the generated `#[derive_*]` with the
|
||||
// span of the `#[deriving(...)]` attribute (the
|
||||
// entire attribute, not just the `PartialEq` or `Eq`
|
||||
// part), but with the current backtrace. The current
|
||||
// backtrace will contain a topmost entry that IS this
|
||||
// `#[deriving(...)]` attribute and with the
|
||||
// "allow-unstable" flag set to true.
|
||||
//
|
||||
// Note that we do NOT use the span of the `Eq`
|
||||
// text itself. You might think this is
|
||||
// equivalent, because the `Eq` appears within the
|
||||
// `#[deriving(Eq)]` attribute, and hence we would
|
||||
// inherit the "allows unstable" from the
|
||||
// backtrace. But in fact this is not always the
|
||||
// case. The actual source text that led to
|
||||
// deriving can be `#[$attr]`, for example, where
|
||||
// `$attr == deriving(Eq)`. In that case, the
|
||||
// "#[derive_*]" would be considered to
|
||||
// originate not from the deriving call but from
|
||||
// text outside the deriving call, and hence would
|
||||
// be forbidden from using unstable
|
||||
// content.
|
||||
//
|
||||
// See tests src/run-pass/rfc1445 for
|
||||
// examples. --nmatsakis
|
||||
let span = Span { expn_id: cx.backtrace(), .. span };
|
||||
assert!(cx.parse_sess.codemap().span_allows_unstable(span));
|
||||
let mut eq_span = None;
|
||||
|
||||
for titem in traits.iter().rev() {
|
||||
let tname = match titem.node {
|
||||
@ -144,8 +114,19 @@ fn expand_derive(cx: &mut ExtCtxt,
|
||||
continue;
|
||||
}
|
||||
|
||||
let span = Span {
|
||||
expn_id: cx.codemap().record_expansion(codemap::ExpnInfo {
|
||||
call_site: titem.span,
|
||||
callee: codemap::NameAndSpan {
|
||||
format: codemap::MacroAttribute(intern(&format!("derive({})", tname))),
|
||||
span: Some(titem.span),
|
||||
allow_internal_unstable: true,
|
||||
},
|
||||
}), ..titem.span
|
||||
};
|
||||
|
||||
if &tname[..] == "Eq" {
|
||||
found_eq = true;
|
||||
eq_span = Some(span);
|
||||
} else if &tname[..] == "PartialEq" {
|
||||
found_partial_eq = true;
|
||||
}
|
||||
@ -157,12 +138,13 @@ fn expand_derive(cx: &mut ExtCtxt,
|
||||
|
||||
// RFC #1445. `#[derive(PartialEq, Eq)]` adds a (trusted)
|
||||
// `#[structural_match]` attribute.
|
||||
if found_partial_eq && found_eq {
|
||||
debug!("inserting structural_match with span {:?}", span);
|
||||
let structural_match = intern_and_get_ident("structural_match");
|
||||
item.attrs.push(cx.attribute(span,
|
||||
cx.meta_word(span,
|
||||
structural_match)));
|
||||
if let Some(eq_span) = eq_span {
|
||||
if found_partial_eq {
|
||||
let structural_match = intern_and_get_ident("structural_match");
|
||||
item.attrs.push(cx.attribute(eq_span,
|
||||
cx.meta_word(eq_span,
|
||||
structural_match)));
|
||||
}
|
||||
}
|
||||
|
||||
item
|
||||
|
14
src/test/compile-fail/issue-33571.rs
Normal file
14
src/test/compile-fail/issue-33571.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
#[derive(Clone,
|
||||
Sync, //~ ERROR this unsafe trait should be implemented explicitly
|
||||
Copy)]
|
||||
enum Foo {}
|
Loading…
Reference in New Issue
Block a user