if [ "$module" = src/llvm ]; then
commit="$(git ls-tree HEAD src/llvm | awk '{print $3}')"
git rm src/llvm
- curl -sSL -O "https://github.com/rust-lang/llvm/archive/$commit.tar.gz"
+ retry sh -c "rm -f $commit.tar.gz && \
+ curl -sSL -O https://github.com/rust-lang/llvm/archive/$commit.tar.gz"
tar -C src/ -xf "$commit.tar.gz"
rm "$commit.tar.gz"
mv "src/llvm-$commit" src/llvm
let mut info = cx.current_expansion.mark.expn_info().unwrap();
info.callee.allow_internal_unstable = true;
cx.current_expansion.mark.set_expn_info(info);
- ::__internal::set_sess(cx, || quote!(::TokenStream((quote stream))))
+ ::__internal::set_sess(cx, || quote!(::TokenStream { 0: (quote stream) }))
}
}
-> io::Result<()> {
use std::borrow::Borrow;
- let primary_span = suggestion.substitution_spans().next().unwrap();
+ let primary_sub = &suggestion.substitution_parts[0];
if let Some(ref cm) = self.cm {
let mut buffer = StyledBuffer::new();
- let lines = cm.span_to_lines(primary_span).unwrap();
+ let lines = cm.span_to_lines(primary_sub.span).unwrap();
assert!(!lines.lines.is_empty());
buffer.append(0, &level.to_string(), Style::Level(level.clone()));
buffer.append(0, ": ", Style::HeaderMsg);
self.msg_to_buffer(&mut buffer,
- &[(suggestion.msg.to_owned(), Style::NoStyle)],
- max_line_num_len,
- "suggestion",
- Some(Style::HeaderMsg));
+ &[(suggestion.msg.to_owned(), Style::NoStyle)],
+ max_line_num_len,
+ "suggestion",
+ Some(Style::HeaderMsg));
let suggestions = suggestion.splice_lines(cm.borrow());
- let mut row_num = 1;
- for complete in suggestions.iter().take(MAX_SUGGESTIONS) {
-
- // print the suggestion without any line numbers, but leave
- // space for them. This helps with lining up with previous
- // snippets from the actual error being reported.
+ let span_start_pos = cm.lookup_char_pos(primary_sub.span.lo);
+ let line_start = span_start_pos.line;
+ draw_col_separator_no_space(&mut buffer, 1, max_line_num_len + 1);
+ let mut row_num = 2;
+ for (&(ref complete, show_underline), ref sub) in suggestions
+ .iter().zip(primary_sub.substitutions.iter()).take(MAX_SUGGESTIONS)
+ {
+ let mut line_pos = 0;
+ // Only show underline if there's a single suggestion and it is a single line
let mut lines = complete.lines();
for line in lines.by_ref().take(MAX_HIGHLIGHT_LINES) {
+ // Print the span column to avoid confusion
+ buffer.puts(row_num,
+ 0,
+ &((line_start + line_pos).to_string()),
+ Style::LineNumber);
+ // print the suggestion
draw_col_separator(&mut buffer, row_num, max_line_num_len + 1);
buffer.append(row_num, line, Style::NoStyle);
+ line_pos += 1;
row_num += 1;
+ // Only show an underline in the suggestions if the suggestion is not the
+ // entirety of the code being shown and the displayed code is not multiline.
+ if show_underline {
+ draw_col_separator(&mut buffer, row_num, max_line_num_len + 1);
+ let sub_len = sub.trim_right().len();
+ let underline_start = span_start_pos.col.0;
+ let underline_end = span_start_pos.col.0 + sub_len;
+ for p in underline_start..underline_end {
+ buffer.putc(row_num,
+ max_line_num_len + 3 + p,
+ '^',
+ Style::UnderlinePrimary);
+ }
+ row_num += 1;
+ }
}
// if we elided some lines, add an ellipsis
if let Some(_) = lines.next() {
- buffer.append(row_num, "...", Style::NoStyle);
+ buffer.puts(row_num, max_line_num_len - 1, "...", Style::LineNumber);
+ } else if !show_underline {
+ draw_col_separator_no_space(&mut buffer, row_num, max_line_num_len + 1);
+ row_num += 1;
}
}
if suggestions.len() > MAX_SUGGESTIONS {
let msg = format!("and {} other candidates", suggestions.len() - MAX_SUGGESTIONS);
- buffer.append(row_num, &msg, Style::NoStyle);
+ buffer.puts(row_num, 0, &msg, Style::NoStyle);
}
emit_to_destination(&buffer.render(), level, &mut self.dst)?;
}
self.substitution_parts.iter().map(|sub| sub.span)
}
- /// Returns the assembled code suggestions.
- pub fn splice_lines(&self, cm: &CodeMapper) -> Vec<String> {
+ /// Returns the assembled code suggestions and wether they should be shown with an underline.
+ pub fn splice_lines(&self, cm: &CodeMapper) -> Vec<(String, bool)> {
use syntax_pos::{CharPos, Loc, Pos};
fn push_trailing(buf: &mut String,
}
if self.substitution_parts.is_empty() {
- return vec![String::new()];
+ return vec![(String::new(), false)];
}
let mut primary_spans: Vec<_> = self.substitution_parts
prev_hi.col = CharPos::from_usize(0);
let mut prev_line = fm.get_line(lines.lines[0].line_index);
- let mut bufs = vec![String::new(); self.substitutions()];
+ let mut bufs = vec![(String::new(), false); self.substitutions()];
for (sp, substitutes) in primary_spans {
let cur_lo = cm.lookup_char_pos(sp.lo);
- for (buf, substitute) in bufs.iter_mut().zip(substitutes) {
+ for (&mut (ref mut buf, ref mut underline), substitute) in bufs.iter_mut()
+ .zip(substitutes) {
if prev_hi.line == cur_lo.line {
push_trailing(buf, prev_line.as_ref(), &prev_hi, Some(&cur_lo));
+
+ // Only show an underline in the suggestions if the suggestion is not the
+ // entirety of the code being shown and the displayed code is not multiline.
+ if prev_line.as_ref().unwrap().trim().len() > 0
+ && !substitute.ends_with('\n')
+ && substitute.lines().count() == 1
+ {
+ *underline = true;
+ }
} else {
+ *underline = false;
push_trailing(buf, prev_line.as_ref(), &prev_hi, None);
// push lines between the previous and current span (if any)
for idx in prev_hi.line..(cur_lo.line - 1) {
prev_hi = cm.lookup_char_pos(sp.hi);
prev_line = fm.get_line(prev_hi.line - 1);
}
- for buf in &mut bufs {
+ for &mut (ref mut buf, _) in &mut bufs {
// if the replacement already ends with a newline, don't print the next line
if !buf.ends_with('\n') {
push_trailing(buf, prev_line.as_ref(), &prev_hi, None);
#![feature(rustc_diagnostic_macros)]
-extern crate rustc;
+#[macro_use] extern crate rustc;
#[macro_use] extern crate syntax;
extern crate syntax_pos;
use rustc::hir::{self, PatKind};
use rustc::hir::def::Def;
-use rustc::hir::def_id::{LOCAL_CRATE, CrateNum, DefId};
+use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir::itemlikevisit::DeepVisitor;
use rustc::lint;
}
}
+////////////////////////////////////////////////////////////////////////////////////////////
+/// Type privacy visitor, checks types for privacy and reports violations.
+/// Both explicitly written types and inferred types of expressions and patters are checked.
+/// Checks are performed on "semantic" types regardless of names and their hygiene.
+////////////////////////////////////////////////////////////////////////////////////////////
+
+struct TypePrivacyVisitor<'a, 'tcx: 'a> {
+ tcx: TyCtxt<'a, 'tcx, 'tcx>,
+ tables: &'a ty::TypeckTables<'tcx>,
+ current_item: DefId,
+ span: Span,
+}
+
+impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> {
+ fn def_id_visibility(&self, did: DefId) -> ty::Visibility {
+ match self.tcx.hir.as_local_node_id(did) {
+ Some(node_id) => {
+ let vis = match self.tcx.hir.get(node_id) {
+ hir::map::NodeItem(item) => &item.vis,
+ hir::map::NodeForeignItem(foreign_item) => &foreign_item.vis,
+ hir::map::NodeImplItem(impl_item) => &impl_item.vis,
+ hir::map::NodeTraitItem(..) |
+ hir::map::NodeVariant(..) => {
+ return self.def_id_visibility(self.tcx.hir.get_parent_did(node_id));
+ }
+ hir::map::NodeStructCtor(vdata) => {
+ let struct_node_id = self.tcx.hir.get_parent(node_id);
+ let struct_vis = match self.tcx.hir.get(struct_node_id) {
+ hir::map::NodeItem(item) => &item.vis,
+ node => bug!("unexpected node kind: {:?}", node),
+ };
+ let mut ctor_vis
+ = ty::Visibility::from_hir(struct_vis, struct_node_id, self.tcx);
+ for field in vdata.fields() {
+ let field_vis = ty::Visibility::from_hir(&field.vis, node_id, self.tcx);
+ if ctor_vis.is_at_least(field_vis, self.tcx) {
+ ctor_vis = field_vis;
+ }
+ }
+ return ctor_vis;
+ }
+ node => bug!("unexpected node kind: {:?}", node)
+ };
+ ty::Visibility::from_hir(vis, node_id, self.tcx)
+ }
+ None => self.tcx.sess.cstore.visibility(did),
+ }
+ }
+
+ fn item_is_accessible(&self, did: DefId) -> bool {
+ self.def_id_visibility(did).is_accessible_from(self.current_item, self.tcx)
+ }
+
+ // Take node ID of an expression or pattern and check its type for privacy.
+ fn check_expr_pat_type(&mut self, id: ast::NodeId, span: Span) -> bool {
+ self.span = span;
+ if let Some(ty) = self.tables.node_id_to_type_opt(id) {
+ if ty.visit_with(self) {
+ return true;
+ }
+ }
+ if self.tables.node_substs(id).visit_with(self) {
+ return true;
+ }
+ if let Some(adjustments) = self.tables.adjustments.get(&id) {
+ for adjustment in adjustments {
+ if adjustment.target.visit_with(self) {
+ return true;
+ }
+ }
+ }
+ false
+ }
+
+ fn check_item(&mut self, item_id: ast::NodeId) -> &mut Self {
+ self.current_item = self.tcx.hir.local_def_id(item_id);
+ self.span = self.tcx.hir.span(item_id);
+ self
+ }
+
+ // Convenience methods for checking item interfaces
+ fn ty(&mut self) -> &mut Self {
+ self.tcx.type_of(self.current_item).visit_with(self);
+ self
+ }
+
+ fn generics(&mut self) -> &mut Self {
+ for def in &self.tcx.generics_of(self.current_item).types {
+ if def.has_default {
+ self.tcx.type_of(def.def_id).visit_with(self);
+ }
+ }
+ self
+ }
+
+ fn predicates(&mut self) -> &mut Self {
+ self.tcx.predicates_of(self.current_item).visit_with(self);
+ self
+ }
+
+ fn impl_trait_ref(&mut self) -> &mut Self {
+ self.tcx.impl_trait_ref(self.current_item).visit_with(self);
+ self
+ }
+}
+
+impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
+ /// We want to visit items in the context of their containing
+ /// module and so forth, so supply a crate for doing a deep walk.
+ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
+ NestedVisitorMap::All(&self.tcx.hir)
+ }
+
+ fn visit_nested_body(&mut self, body: hir::BodyId) {
+ let orig_tables = replace(&mut self.tables, self.tcx.body_tables(body));
+ let body = self.tcx.hir.body(body);
+ self.visit_body(body);
+ self.tables = orig_tables;
+ }
+
+ // Check types of expressions
+ fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
+ if self.check_expr_pat_type(expr.id, expr.span) {
+ // Do not check nested expressions if the error already happened.
+ return;
+ }
+ match expr.node {
+ hir::ExprAssign(.., ref rhs) | hir::ExprMatch(ref rhs, ..) => {
+ // Do not report duplicate errors for `x = y` and `match x { ... }`.
+ if self.check_expr_pat_type(rhs.id, rhs.span) {
+ return;
+ }
+ }
+ hir::ExprMethodCall(name, ..) => {
+ // Method calls have to be checked specially.
+ let def_id = self.tables.type_dependent_defs[&expr.id].def_id();
+ self.span = name.span;
+ if self.tcx.type_of(def_id).visit_with(self) {
+ return;
+ }
+ }
+ _ => {}
+ }
+
+ intravisit::walk_expr(self, expr);
+ }
+
+ fn visit_qpath(&mut self, qpath: &'tcx hir::QPath, id: ast::NodeId, span: Span) {
+ // Inherent associated constants don't have self type in substs,
+ // we have to check it additionally.
+ if let hir::QPath::TypeRelative(..) = *qpath {
+ if let Some(def) = self.tables.type_dependent_defs.get(&id).cloned() {
+ if let Some(assoc_item) = self.tcx.opt_associated_item(def.def_id()) {
+ if let ty::ImplContainer(impl_def_id) = assoc_item.container {
+ if self.tcx.type_of(impl_def_id).visit_with(self) {
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ intravisit::walk_qpath(self, qpath, id, span);
+ }
+
+ // Check types of patterns
+ fn visit_pat(&mut self, pattern: &'tcx hir::Pat) {
+ if self.check_expr_pat_type(pattern.id, pattern.span) {
+ // Do not check nested patterns if the error already happened.
+ return;
+ }
+
+ intravisit::walk_pat(self, pattern);
+ }
+
+ fn visit_local(&mut self, local: &'tcx hir::Local) {
+ if let Some(ref init) = local.init {
+ if self.check_expr_pat_type(init.id, init.span) {
+ // Do not report duplicate errors for `let x = y`.
+ return;
+ }
+ }
+
+ intravisit::walk_local(self, local);
+ }
+
+ // Check types in item interfaces
+ fn visit_item(&mut self, item: &'tcx hir::Item) {
+ let orig_current_item = self.current_item;
+
+ match item.node {
+ hir::ItemExternCrate(..) | hir::ItemMod(..) |
+ hir::ItemUse(..) | hir::ItemGlobalAsm(..) => {}
+ hir::ItemConst(..) | hir::ItemStatic(..) |
+ hir::ItemTy(..) | hir::ItemFn(..) => {
+ self.check_item(item.id).generics().predicates().ty();
+ }
+ hir::ItemTrait(.., ref trait_item_refs) => {
+ self.check_item(item.id).generics().predicates();
+ for trait_item_ref in trait_item_refs {
+ let mut check = self.check_item(trait_item_ref.id.node_id);
+ check.generics().predicates();
+ if trait_item_ref.kind != hir::AssociatedItemKind::Type ||
+ trait_item_ref.defaultness.has_value() {
+ check.ty();
+ }
+ }
+ }
+ hir::ItemEnum(ref def, _) => {
+ self.check_item(item.id).generics().predicates();
+ for variant in &def.variants {
+ for field in variant.node.data.fields() {
+ self.check_item(field.id).ty();
+ }
+ }
+ }
+ hir::ItemForeignMod(ref foreign_mod) => {
+ for foreign_item in &foreign_mod.items {
+ self.check_item(foreign_item.id).generics().predicates().ty();
+ }
+ }
+ hir::ItemStruct(ref struct_def, _) |
+ hir::ItemUnion(ref struct_def, _) => {
+ self.check_item(item.id).generics().predicates();
+ for field in struct_def.fields() {
+ self.check_item(field.id).ty();
+ }
+ }
+ hir::ItemDefaultImpl(..) => {
+ self.check_item(item.id).impl_trait_ref();
+ }
+ hir::ItemImpl(.., ref trait_ref, _, ref impl_item_refs) => {
+ {
+ let mut check = self.check_item(item.id);
+ check.ty().generics().predicates();
+ if trait_ref.is_some() {
+ check.impl_trait_ref();
+ }
+ }
+ for impl_item_ref in impl_item_refs {
+ let impl_item = self.tcx.hir.impl_item(impl_item_ref.id);
+ self.check_item(impl_item.id).generics().predicates().ty();
+ }
+ }
+ }
+
+ self.current_item = self.tcx.hir.local_def_id(item.id);
+ intravisit::walk_item(self, item);
+ self.current_item = orig_current_item;
+ }
+}
+
+impl<'a, 'tcx> TypeVisitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
+ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
+ match ty.sty {
+ ty::TyAdt(&ty::AdtDef { did: def_id, .. }, ..) | ty::TyFnDef(def_id, ..) => {
+ if !self.item_is_accessible(def_id) {
+ let msg = format!("type `{}` is private", ty);
+ self.tcx.sess.span_err(self.span, &msg);
+ return true;
+ }
+ if let ty::TyFnDef(..) = ty.sty {
+ if self.tcx.fn_sig(def_id).visit_with(self) {
+ return true;
+ }
+ }
+ // Inherent static methods don't have self type in substs,
+ // we have to check it additionally.
+ if let Some(assoc_item) = self.tcx.opt_associated_item(def_id) {
+ if let ty::ImplContainer(impl_def_id) = assoc_item.container {
+ if self.tcx.type_of(impl_def_id).visit_with(self) {
+ return true;
+ }
+ }
+ }
+ }
+ ty::TyDynamic(ref predicates, ..) => {
+ let is_private = predicates.skip_binder().iter().any(|predicate| {
+ let def_id = match *predicate {
+ ty::ExistentialPredicate::Trait(trait_ref) => trait_ref.def_id,
+ ty::ExistentialPredicate::Projection(proj) => proj.trait_ref.def_id,
+ ty::ExistentialPredicate::AutoTrait(def_id) => def_id,
+ };
+ !self.item_is_accessible(def_id)
+ });
+ if is_private {
+ let msg = format!("type `{}` is private", ty);
+ self.tcx.sess.span_err(self.span, &msg);
+ return true;
+ }
+ }
+ ty::TyAnon(def_id, ..) => {
+ for predicate in &self.tcx.predicates_of(def_id).predicates {
+ let trait_ref = match *predicate {
+ ty::Predicate::Trait(ref poly_trait_predicate) => {
+ Some(poly_trait_predicate.skip_binder().trait_ref)
+ }
+ ty::Predicate::Projection(ref poly_projection_predicate) => {
+ if poly_projection_predicate.skip_binder().ty.visit_with(self) {
+ return true;
+ }
+ Some(poly_projection_predicate.skip_binder().projection_ty.trait_ref)
+ }
+ ty::Predicate::TypeOutlives(..) => None,
+ _ => bug!("unexpected predicate: {:?}", predicate),
+ };
+ if let Some(trait_ref) = trait_ref {
+ if !self.item_is_accessible(trait_ref.def_id) {
+ let msg = format!("trait `{}` is private", trait_ref);
+ self.tcx.sess.span_err(self.span, &msg);
+ return true;
+ }
+ // `Self` here is the same `TyAnon`, so skip it to avoid infinite recursion
+ for subst in trait_ref.substs.iter().skip(1) {
+ if subst.visit_with(self) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ _ => {}
+ }
+
+ ty.super_visit_with(self)
+ }
+
+ fn visit_trait_ref(&mut self, trait_ref: ty::TraitRef<'tcx>) -> bool {
+ if !self.item_is_accessible(trait_ref.def_id) {
+ let msg = format!("trait `{}` is private", trait_ref);
+ self.tcx.sess.span_err(self.span, &msg);
+ return true;
+ }
+
+ trait_ref.super_visit_with(self)
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
/// Obsolete visitors for checking for private items in public interfaces.
/// These visitors are supposed to be kept in frozen state and produce an
};
intravisit::walk_crate(&mut visitor, krate);
+ // Check privacy of explicitly written types and traits as well as
+ // inferred types of expressions and patterns.
+ let mut visitor = TypePrivacyVisitor {
+ tcx: tcx,
+ tables: &ty::TypeckTables::empty(),
+ current_item: DefId::local(CRATE_DEF_INDEX),
+ span: krate.span,
+ };
+ intravisit::walk_crate(&mut visitor, krate);
+
// Build up a set of all exported items in the AST. This is a set of all
// items which are reachable from external crates based on visibility.
let mut visitor = EmbargoVisitor {
true, opts, maybe_sysroot, None,
Some(input.to_owned()),
render_type);
- old_find_testable_code(&input_str, &mut collector, DUMMY_SP);
- find_testable_code(&input_str, &mut collector, DUMMY_SP);
+ if render_type == RenderType::Pulldown {
+ old_find_testable_code(&input_str, &mut collector, DUMMY_SP);
+ find_testable_code(&input_str, &mut collector, DUMMY_SP);
+ } else {
+ old_find_testable_code(&input_str, &mut collector, DUMMY_SP);
+ }
test_args.insert(0, "rustdoctest".to_string());
testing::test_main(&test_args, collector.tests,
testing::Options::new().display_output(display_warnings));
super::each_addr(addr, net_imp::TcpStream::connect).map(TcpStream)
}
+ /// Opens a TCP connection to a remote host with a timeout.
+ ///
+ /// Unlike `connect`, `connect_timeout` takes a single [`SocketAddr`] since
+ /// timeout must be applied to individual addresses.
+ ///
+ /// It is an error to pass a zero `Duration` to this function.
+ ///
+ /// Unlike other methods on `TcpStream`, this does not correspond to a
+ /// single system call. It instead calls `connect` in nonblocking mode and
+ /// then uses an OS-specific mechanism to await the completion of the
+ /// connection request.
+ ///
+ /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
+ #[unstable(feature = "tcpstream_connect_timeout", issue = "43709")]
+ pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result<TcpStream> {
+ net_imp::TcpStream::connect_timeout(addr, timeout).map(TcpStream)
+ }
+
/// Returns the socket address of the remote peer of this TCP connection.
///
/// # Examples
t!(txdone.send(()));
})
}
+
+ #[test]
+ fn connect_timeout_unroutable() {
+ // this IP is unroutable, so connections should always time out.
+ let addr = "10.255.255.1:80".parse().unwrap();
+ let e = TcpStream::connect_timeout(&addr, Duration::from_millis(250)).unwrap_err();
+ assert_eq!(e.kind(), io::ErrorKind::TimedOut);
+ }
+
+ #[test]
+ fn connect_timeout_valid() {
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
+ let addr = listener.local_addr().unwrap();
+ TcpStream::connect_timeout(&addr, Duration::from_secs(2)).unwrap();
+ }
}
Ok(TcpStream(File::open(&Path::new(path.as_str()), &options)?))
}
+ pub fn connect_timeout(_addr: &SocketAddr, _timeout: Duration) -> Result<()> {
+ Err(Error::new(ErrorKind::Other, "TcpStream::connect_timeout not implemented"))
+ }
+
pub fn duplicate(&self) -> Result<TcpStream> {
Ok(TcpStream(self.0.dup(&[])?))
}
use sys::fd::FileDesc;
use sys_common::{AsInner, FromInner, IntoInner};
use sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr};
-use time::Duration;
+use time::{Duration, Instant};
+use cmp;
pub use sys::{cvt, cvt_r};
pub extern crate libc as netc;
}
}
+ pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> {
+ self.set_nonblocking(true)?;
+ let r = unsafe {
+ let (addrp, len) = addr.into_inner();
+ cvt(libc::connect(self.0.raw(), addrp, len))
+ };
+ self.set_nonblocking(false)?;
+
+ match r {
+ Ok(_) => return Ok(()),
+ // there's no ErrorKind for EINPROGRESS :(
+ Err(ref e) if e.raw_os_error() == Some(libc::EINPROGRESS) => {}
+ Err(e) => return Err(e),
+ }
+
+ let mut pollfd = libc::pollfd {
+ fd: self.0.raw(),
+ events: libc::POLLOUT,
+ revents: 0,
+ };
+
+ if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
+ return Err(io::Error::new(io::ErrorKind::InvalidInput,
+ "cannot set a 0 duration timeout"));
+ }
+
+ let start = Instant::now();
+
+ loop {
+ let elapsed = start.elapsed();
+ if elapsed >= timeout {
+ return Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out"));
+ }
+
+ let timeout = timeout - elapsed;
+ let mut timeout = timeout.as_secs()
+ .saturating_mul(1_000)
+ .saturating_add(timeout.subsec_nanos() as u64 / 1_000_000);
+ if timeout == 0 {
+ timeout = 1;
+ }
+
+ let timeout = cmp::min(timeout, c_int::max_value() as u64) as c_int;
+
+ match unsafe { libc::poll(&mut pollfd, 1, timeout) } {
+ -1 => {
+ let err = io::Error::last_os_error();
+ if err.kind() != io::ErrorKind::Interrupted {
+ return Err(err);
+ }
+ }
+ 0 => {}
+ _ => {
+ if pollfd.revents & libc::POLLOUT == 0 {
+ if let Some(e) = self.take_error()? {
+ return Err(e);
+ }
+ }
+ return Ok(());
+ }
+ }
+ }
+ }
+
pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t)
-> io::Result<Socket> {
// Unfortunately the only known way right now to accept a socket and
pub const PIPE_REJECT_REMOTE_CLIENTS: DWORD = 0x00000008;
pub const PIPE_READMODE_BYTE: DWORD = 0x00000000;
+pub const FD_SETSIZE: usize = 64;
+
#[repr(C)]
#[cfg(target_arch = "x86")]
pub struct WSADATA {
}
pub type PCONSOLE_READCONSOLE_CONTROL = *mut CONSOLE_READCONSOLE_CONTROL;
+#[repr(C)]
+#[derive(Copy)]
+pub struct fd_set {
+ pub fd_count: c_uint,
+ pub fd_array: [SOCKET; FD_SETSIZE],
+}
+
+impl Clone for fd_set {
+ fn clone(&self) -> fd_set {
+ *self
+ }
+}
+
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct timeval {
+ pub tv_sec: c_long,
+ pub tv_usec: c_long,
+}
+
extern "system" {
pub fn WSAStartup(wVersionRequested: WORD,
lpWSAData: LPWSADATA) -> c_int;
lpOverlapped: LPOVERLAPPED,
lpNumberOfBytesTransferred: LPDWORD,
bWait: BOOL) -> BOOL;
+ pub fn select(nfds: c_int,
+ readfds: *mut fd_set,
+ writefds: *mut fd_set,
+ exceptfds: *mut fd_set,
+ timeout: *const timeval) -> c_int;
}
// Functions that aren't available on Windows XP, but we still use them and just
use cmp;
use io::{self, Read};
-use libc::{c_int, c_void, c_ulong};
+use libc::{c_int, c_void, c_ulong, c_long};
use mem;
use net::{SocketAddr, Shutdown};
use ptr;
Ok(socket)
}
+ pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> {
+ self.set_nonblocking(true)?;
+ let r = unsafe {
+ let (addrp, len) = addr.into_inner();
+ cvt(c::connect(self.0, addrp, len))
+ };
+ self.set_nonblocking(false)?;
+
+ match r {
+ Ok(_) => return Ok(()),
+ Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
+ Err(e) => return Err(e),
+ }
+
+ if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
+ return Err(io::Error::new(io::ErrorKind::InvalidInput,
+ "cannot set a 0 duration timeout"));
+ }
+
+ let mut timeout = c::timeval {
+ tv_sec: timeout.as_secs() as c_long,
+ tv_usec: (timeout.subsec_nanos() / 1000) as c_long,
+ };
+ if timeout.tv_sec == 0 && timeout.tv_usec == 0 {
+ timeout.tv_usec = 1;
+ }
+
+ let fds = unsafe {
+ let mut fds = mem::zeroed::<c::fd_set>();
+ fds.fd_count = 1;
+ fds.fd_array[0] = self.0;
+ fds
+ };
+
+ let mut writefds = fds;
+ let mut errorfds = fds;
+
+ let n = unsafe {
+ cvt(c::select(1, ptr::null_mut(), &mut writefds, &mut errorfds, &timeout))?
+ };
+
+ match n {
+ 0 => Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out")),
+ _ => {
+ if writefds.fd_count != 1 {
+ if let Some(e) = self.take_error()? {
+ return Err(e);
+ }
+ }
+ Ok(())
+ }
+ }
+ }
+
pub fn accept(&self, storage: *mut c::SOCKADDR,
len: *mut c_int) -> io::Result<Socket> {
let socket = unsafe {
Ok(TcpStream { inner: sock })
}
+ pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result<TcpStream> {
+ init();
+
+ let sock = Socket::new(addr, c::SOCK_STREAM)?;
+ sock.connect_timeout(addr, timeout)?;
+ Ok(TcpStream { inner: sock })
+ }
+
pub fn socket(&self) -> &Socket { &self.inner }
pub fn into_socket(self) -> Socket { self.inner }
impl JsonEmitter {
fn render(&self, suggestion: &CodeSuggestion) -> Vec<String> {
- suggestion.splice_lines(&*self.cm)
+ suggestion.splice_lines(&*self.cm).iter().map(|line| line.0.to_owned()).collect()
}
}
err.cancel();
let codemap = self.sess.codemap();
let suggestion_span = lhs_span.to(self.prev_span);
- let suggestion = match codemap.span_to_snippet(suggestion_span) {
- Ok(lstring) => format!("({})", lstring),
- _ => format!("(<expression> as <type>)")
- };
let warn_message = match codemap.span_to_snippet(self.prev_span) {
Ok(lstring) => format!("`{}`", lstring),
_ => "a type".to_string(),
let mut err = self.sess.span_diagnostic.struct_span_err(sp, &msg);
err.span_label(sp, "interpreted as generic argument");
err.span_label(self.span, "not interpreted as comparison");
+ let suggestion = match codemap.span_to_snippet(suggestion_span) {
+ Ok(lstring) => format!("({})", lstring),
+ _ => format!("(<expression> as <type>)")
+ };
err.span_suggestion(suggestion_span,
"if you want to compare the casted value then write:",
suggestion);
--- /dev/null
+// Copyright 2017 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(decl_macro)]
+
+fn priv_fn() {}
+enum PrivEnum { Variant }
+pub enum PubEnum { Variant }
+trait PrivTrait { fn method() {} }
+impl PrivTrait for u8 {}
+pub trait PubTrait { fn method() {} }
+impl PubTrait for u8 {}
+struct PrivTupleStruct(u8);
+pub struct PubTupleStruct(u8);
+impl PubTupleStruct { fn method() {} }
+
+struct Priv;
+pub type Alias = Priv;
+pub struct Pub<T = Alias>(pub T);
+
+impl Pub<Priv> {
+ pub fn static_method() {}
+}
+impl Pub<u8> {
+ fn priv_method(&self) {}
+}
+
+pub macro m() {
+ priv_fn;
+ PrivEnum::Variant;
+ PubEnum::Variant;
+ <u8 as PrivTrait>::method;
+ <u8 as PubTrait>::method;
+ PrivTupleStruct;
+ PubTupleStruct;
+ Pub(0u8).priv_method();
+}
--- /dev/null
+// Copyright 2017 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(decl_macro)]
+
+pub mod foo {
+ pub use self::bar::m;
+ mod bar {
+ fn f() -> u32 { 1 }
+ pub macro m() {
+ f();
+ }
+ }
+}
--- /dev/null
+// Copyright 2017 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.
+
+// ignore-pretty pretty-printing is unhygienic
+
+#![feature(decl_macro)]
+
+mod foo {
+ struct S { x: u32 }
+ struct T(u32);
+
+ pub macro m($S:ident, $x:ident) {{
+ struct $S {
+ $x: u32,
+ x: i32,
+ }
+
+ let s = S { x: 0 }; //~ ERROR type `foo::S` is private
+ let _ = s.x; //~ ERROR type `foo::S` is private
+
+ let t = T(0); //~ ERROR type `foo::T` is private
+ let _ = t.0; //~ ERROR type `foo::T` is private
+
+ let s = $S { $x: 0, x: 1 };
+ assert_eq!((s.$x, s.x), (0, 1));
+ s
+ }}
+}
+
+fn main() {
+ let s = foo::m!(S, x);
+ assert_eq!(s.x, 0);
+}
--- /dev/null
+// Copyright 2017 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.
+
+// ignore-pretty pretty-printing is unhygienic
+
+#![feature(decl_macro)]
+
+mod foo {
+ struct S;
+ impl S {
+ fn f(&self) {}
+ }
+
+ pub macro m() {
+ let _: () = S.f(); //~ ERROR type `fn(&foo::S) {foo::S::f}` is private
+ }
+}
+
+struct S;
+
+macro m($f:ident) {
+ impl S {
+ fn f(&self) -> u32 { 0 }
+ fn $f(&self) -> i32 { 0 }
+ }
+ fn f() {
+ let _: u32 = S.f();
+ let _: i32 = S.$f();
+ }
+}
+
+m!(f);
+
+fn main() {
+ let _: i32 = S.f();
+ foo::m!();
+}
--- /dev/null
+// Copyright 2017 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.
+
+// ignore-pretty pretty-printing is unhygienic
+
+// aux-build:intercrate.rs
+
+// error-pattern:type `fn() -> u32 {intercrate::foo::bar::f}` is private
+
+#![feature(decl_macro)]
+
+extern crate intercrate;
+
+fn main() {
+ assert_eq!(intercrate::foo::m!(), 1);
+}
--- /dev/null
+// Copyright 2017 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.
+
+trait Arr0 {
+ fn arr0_secret(&self);
+}
+trait TyParam {
+ fn ty_param_secret(&self);
+}
+
+mod m {
+ struct Priv;
+
+ impl ::Arr0 for [Priv; 0] { fn arr0_secret(&self) {} }
+ impl ::TyParam for Option<Priv> { fn ty_param_secret(&self) {} }
+}
+
+fn main() {
+ [].arr0_secret(); //~ ERROR type `m::Priv` is private
+ None.ty_param_secret(); //~ ERROR type `m::Priv` is private
+}
--- /dev/null
+// Copyright 2017 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.
+
+// aux-build:private-inferred-type.rs
+
+extern crate private_inferred_type as ext;
+
+mod m {
+ struct Priv;
+ pub struct Pub<T>(pub T);
+
+ impl Pub<Priv> {
+ pub fn get_priv() -> Priv { Priv }
+ pub fn static_method() {}
+ }
+}
+
+fn main() {
+ m::Pub::get_priv; //~ ERROR type `m::Priv` is private
+ m::Pub::static_method; //~ ERROR type `m::Priv` is private
+ ext::Pub::static_method; //~ ERROR type `ext::Priv` is private
+}
--- /dev/null
+// Copyright 2017 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.
+
+// aux-build:private-inferred-type.rs
+
+// error-pattern:type `fn() {ext::priv_fn}` is private
+// error-pattern:type `ext::PrivEnum` is private
+// error-pattern:type `fn() {<u8 as ext::PrivTrait>::method}` is private
+// error-pattern:type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct::{{constructor}}}` is pr
+// error-pattern:type `fn(u8) -> ext::PubTupleStruct {ext::PubTupleStruct::{{constructor}}}` is priv
+// error-pattern:type `fn(&ext::Pub<u8>) {<ext::Pub<u8>>::priv_method}` is private
+
+#![feature(decl_macro)]
+
+extern crate private_inferred_type as ext;
+
+fn main() {
+ ext::m!();
+}
--- /dev/null
+// Copyright 2017 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(associated_consts)]
+#![feature(conservative_impl_trait)]
+#![feature(decl_macro)]
+
+mod m {
+ fn priv_fn() {}
+ enum PrivEnum { Variant }
+ pub enum PubEnum { Variant }
+ trait PrivTrait { fn method() {} }
+ impl PrivTrait for u8 {}
+ pub trait PubTrait { fn method() {} }
+ impl PubTrait for u8 {}
+ struct PrivTupleStruct(u8);
+ pub struct PubTupleStruct(u8);
+ impl PubTupleStruct { fn method() {} }
+
+ struct Priv;
+ pub type Alias = Priv;
+ pub struct Pub<T = Alias>(pub T);
+
+ impl Pub<Priv> {
+ pub fn static_method() {}
+ pub const INHERENT_ASSOC_CONST: u8 = 0;
+ }
+ impl<T> Pub<T> {
+ pub fn static_method_generic_self() {}
+ pub const INHERENT_ASSOC_CONST_GENERIC_SELF: u8 = 0;
+ }
+ impl Pub<u8> {
+ fn priv_method(&self) {}
+ pub fn method_with_substs<T>(&self) {}
+ pub fn method_with_priv_params(&self, _: Priv) {}
+ }
+ impl TraitWithAssocConst for Priv {}
+ impl TraitWithAssocTy for Priv { type AssocTy = u8; }
+
+ pub macro m() {
+ priv_fn; //~ ERROR type `fn() {m::priv_fn}` is private
+ PrivEnum::Variant; //~ ERROR type `m::PrivEnum` is private
+ PubEnum::Variant; // OK
+ <u8 as PrivTrait>::method; //~ ERROR type `fn() {<u8 as m::PrivTrait>::method}` is private
+ <u8 as PubTrait>::method; // OK
+ PrivTupleStruct;
+ //~^ ERROR type `fn(u8) -> m::PrivTupleStruct {m::PrivTupleStruct::{{constructor}}}` is priv
+ PubTupleStruct;
+ //~^ ERROR type `fn(u8) -> m::PubTupleStruct {m::PubTupleStruct::{{constructor}}}` is privat
+ Pub(0u8).priv_method();
+ //~^ ERROR type `fn(&m::Pub<u8>) {<m::Pub<u8>>::priv_method}` is private
+ }
+
+ trait Trait {}
+ pub trait TraitWithTyParam<T> {}
+ pub trait TraitWithTyParam2<T> { fn pub_method() {} }
+ pub trait TraitWithAssocTy { type AssocTy; }
+ pub trait TraitWithAssocConst { const TRAIT_ASSOC_CONST: u8 = 0; }
+ impl Trait for u8 {}
+ impl<T> TraitWithTyParam<T> for u8 {}
+ impl TraitWithTyParam2<Priv> for u8 {}
+ impl TraitWithAssocTy for u8 { type AssocTy = Priv; }
+
+ pub fn leak_anon1() -> impl Trait + 'static { 0 }
+ pub fn leak_anon2() -> impl TraitWithTyParam<Alias> { 0 }
+ pub fn leak_anon3() -> impl TraitWithAssocTy<AssocTy = Alias> { 0 }
+
+ pub fn leak_dyn1() -> Box<Trait + 'static> { Box::new(0) }
+ pub fn leak_dyn2() -> Box<TraitWithTyParam<Alias>> { Box::new(0) }
+ pub fn leak_dyn3() -> Box<TraitWithAssocTy<AssocTy = Alias>> { Box::new(0) }
+}
+
+mod adjust {
+ // Construct a chain of derefs with a private type in the middle
+ use std::ops::Deref;
+
+ pub struct S1;
+ struct S2;
+ pub type S2Alias = S2;
+ pub struct S3;
+
+ impl Deref for S1 {
+ type Target = S2Alias;
+ fn deref(&self) -> &Self::Target { loop {} }
+ }
+ impl Deref for S2 {
+ type Target = S3;
+ fn deref(&self) -> &Self::Target { loop {} }
+ }
+
+ impl S3 {
+ pub fn method_s3(&self) {}
+ }
+}
+
+fn main() {
+ let _: m::Alias; //~ ERROR type `m::Priv` is private
+ let _: <m::Alias as m::TraitWithAssocTy>::AssocTy; // FIXME
+ m::Alias {}; //~ ERROR type `m::Priv` is private
+ m::Pub { 0: m::Alias {} }; //~ ERROR type `m::Priv` is private
+ m::Pub { 0: loop {} }; // FIXME
+ m::Pub::static_method; //~ ERROR type `m::Priv` is private
+ m::Pub::INHERENT_ASSOC_CONST; //~ ERROR type `m::Priv` is private
+ m::Pub(0u8).method_with_substs::<m::Alias>(); //~ ERROR type `m::Priv` is private
+ m::Pub(0u8).method_with_priv_params(loop{}); //~ ERROR type `m::Priv` is private
+ <m::Alias as m::TraitWithAssocConst>::TRAIT_ASSOC_CONST; //~ ERROR type `m::Priv` is private
+ <m::Pub<m::Alias>>::INHERENT_ASSOC_CONST; //~ ERROR type `m::Priv` is private
+ <m::Pub<m::Alias>>::INHERENT_ASSOC_CONST_GENERIC_SELF; //~ ERROR type `m::Priv` is private
+ <m::Pub<m::Alias>>::static_method_generic_self; //~ ERROR type `m::Priv` is private
+ use m::TraitWithTyParam2;
+ u8::pub_method; //~ ERROR type `m::Priv` is private
+
+ adjust::S1.method_s3(); //~ ERROR type `adjust::S2` is private
+
+ m::m!();
+
+ m::leak_anon1(); //~ ERROR trait `m::Trait` is private
+ m::leak_anon2(); //~ ERROR type `m::Priv` is private
+ m::leak_anon3(); //~ ERROR type `m::Priv` is private
+
+ m::leak_dyn1(); //~ ERROR type `m::Trait + 'static` is private
+ m::leak_dyn2(); //~ ERROR type `m::Priv` is private
+ m::leak_dyn3(); //~ ERROR type `m::Priv` is private
+
+ // Check that messages are not duplicated for various kinds of assignments
+ let a = m::Alias {}; //~ ERROR type `m::Priv` is private
+ let mut b = a; //~ ERROR type `m::Priv` is private
+ b = a; //~ ERROR type `m::Priv` is private
+ match a { //~ ERROR type `m::Priv` is private
+ _ => {}
+ }
+}
--- /dev/null
+// Copyright 2017 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.
+
+// aux-build:private-inferred-type.rs
+
+#![feature(conservative_impl_trait)]
+
+extern crate private_inferred_type as ext;
+
+mod m {
+ struct Priv;
+ pub type Alias = Priv;
+
+ pub trait Trait { type X; }
+ impl Trait for Priv { type X = u8; }
+}
+
+fn f(_: m::Alias) {} //~ ERROR type `m::Priv` is private
+ //~^ ERROR type `m::Priv` is private
+fn f_ext(_: ext::Alias) {} //~ ERROR type `ext::Priv` is private
+ //~^ ERROR type `ext::Priv` is private
+
+trait Tr1 {}
+impl m::Alias {} //~ ERROR type `m::Priv` is private
+impl Tr1 for ext::Alias {} //~ ERROR type `ext::Priv` is private
+ //~^ ERROR type `ext::Priv` is private
+type A = <m::Alias as m::Trait>::X; //~ ERROR type `m::Priv` is private
+
+trait Tr2<T> {}
+impl<T> Tr2<T> for u8 {}
+fn g() -> impl Tr2<m::Alias> { 0 } //~ ERROR type `m::Priv` is private
+fn g_ext() -> impl Tr2<ext::Alias> { 0 } //~ ERROR type `ext::Priv` is private
+
+fn main() {}
+++ /dev/null
-// Copyright 2017 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(decl_macro)]
-
-pub mod foo {
- pub use self::bar::m;
- mod bar {
- fn f() -> u32 { 1 }
- pub macro m() {
- f();
- }
- }
-}
+++ /dev/null
-// Copyright 2017 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.
-
-// ignore-pretty pretty-printing is unhygienic
-
-#![feature(decl_macro)]
-
-mod foo {
- struct S { x: u32 }
- struct T(u32);
-
- pub macro m($S:ident, $x:ident) {{
- struct $S {
- $x: u32,
- x: i32,
- }
-
- let s = S { x: 0 };
- let _ = s.x;
-
- let t = T(0);
- let _ = t.0;
-
- let s = $S { $x: 0, x: 1 };
- assert_eq!((s.$x, s.x), (0, 1));
- s
- }}
-}
-
-fn main() {
- let s = foo::m!(S, x);
- assert_eq!(s.x, 0);
-}
+++ /dev/null
-// Copyright 2017 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.
-
-// ignore-pretty pretty-printing is unhygienic
-
-#![feature(decl_macro)]
-
-mod foo {
- struct S;
- impl S {
- fn f(&self) {}
- }
-
- pub macro m() {
- let _: () = S.f();
- }
-}
-
-struct S;
-
-macro m($f:ident) {
- impl S {
- fn f(&self) -> u32 { 0 }
- fn $f(&self) -> i32 { 0 }
- }
- fn f() {
- let _: u32 = S.f();
- let _: i32 = S.$f();
- }
-}
-
-m!(f);
-
-fn main() {
- let _: i32 = S.f();
- foo::m!();
-}
+++ /dev/null
-// Copyright 2017 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.
-
-// ignore-pretty pretty-printing is unhygienic
-
-// aux-build:intercrate.rs
-
-#![feature(decl_macro)]
-
-extern crate intercrate;
-
-fn main() {
- assert_eq!(intercrate::foo::m!(), 1);
-}
= note: expected type `()`
found type `usize`
help: did you mean to add a semicolon here?
- | foo();
+ |
+19 | foo();
+ | ^
help: possibly return type missing here?
- | fn bar() -> usize {
+ |
+18 | fn bar() -> usize {
+ | ^^^^^^^^
error: aborting due to previous error
println!("{}", a as usize > b);
println!("{}", a as usize < b);
- println!("{}", a as usize < 4);
+ println!("{}", a
+ as
+ usize
+ <
+ 4);
+ println!("{}", a
+
+
+ as
+
+
+ usize
+ <
+ 5);
}
| not interpreted as comparison
|
help: if you want to compare the casted value then write:
- | println!("{}", (a as usize) < b);
+ |
+16 | println!("{}", (a as usize) < b);
+ | ^^^^^^^^^^^^
error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
- --> $DIR/issue-22644.rs:17:33
+ --> $DIR/issue-22644.rs:21:20
|
-17 | println!("{}", a as usize < 4);
- | - ^ interpreted as generic argument
- | |
- | not interpreted as comparison
+20 | <
+ | - not interpreted as comparison
+21 | 4);
+ | ^ interpreted as generic argument
+ |
+help: if you want to compare the casted value then write:
+ |
+17 | println!("{}", (a
+18 | as
+19 | usize)
+ |
+
+error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
+ --> $DIR/issue-22644.rs:30:20
+ |
+29 | <
+ | - not interpreted as comparison
+30 | 5);
+ | ^ interpreted as generic argument
|
help: if you want to compare the casted value then write:
- | println!("{}", (a as usize) < 4);
+ |
+22 | println!("{}", (a
+23 |
+24 |
+25 | as
+26 |
+27 |
+ ...
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
| ^ not found in `namespaced_enums`
|
help: possible candidate is found in another module, you can import it into scope
- | use namespaced_enums::Foo::A;
+ |
+12 | use namespaced_enums::Foo::A;
+ |
error[E0425]: cannot find function `B` in module `namespaced_enums`
--> $DIR/enums-are-namespaced-xc.rs:18:31
| ^ not found in `namespaced_enums`
|
help: possible candidate is found in another module, you can import it into scope
- | use namespaced_enums::Foo::B;
+ |
+12 | use namespaced_enums::Foo::B;
+ |
error[E0422]: cannot find struct, variant or union type `C` in module `namespaced_enums`
--> $DIR/enums-are-namespaced-xc.rs:21:31
| ^ not found in `namespaced_enums`
|
help: possible candidate is found in another module, you can import it into scope
- | use namespaced_enums::Foo::C;
+ |
+12 | use namespaced_enums::Foo::C;
+ |
error: aborting due to 3 previous errors
| ^^^^^^ not a struct, variant or union type
|
help: possible better candidates are found in other modules, you can import them into scope
- | use std::fmt::Result;
- | use std::io::Result;
- | use std::thread::Result;
+ |
+12 | use std::fmt::Result;
+ |
+12 | use std::io::Result;
+ |
+12 | use std::thread::Result;
+ |
error: aborting due to previous error
| ^ not found in this scope
|
help: possible candidate is found in another module, you can import it into scope
- | use SomeEnum::E;
+ |
+11 | use SomeEnum::E;
+ |
error: aborting due to previous error
| ^^^ not found in this scope
|
help: possible candidates are found in other modules, you can import them into scope
- | use mul1::Mul;
- | use mul2::Mul;
- | use std::ops::Mul;
+ |
+11 | use mul1::Mul;
+ |
+11 | use mul2::Mul;
+ |
+11 | use std::ops::Mul;
+ |
error[E0412]: cannot find type `Mul` in this scope
--> $DIR/issue-21221-1.rs:72:16
| ^^^ not found in this scope
|
help: possible candidates are found in other modules, you can import them into scope
- | use mul1::Mul;
- | use mul2::Mul;
- | use mul3::Mul;
- | use mul4::Mul;
+ |
+11 | use mul1::Mul;
+ |
+11 | use mul2::Mul;
+ |
+11 | use mul3::Mul;
+ |
+11 | use mul4::Mul;
+ |
and 2 other candidates
error[E0405]: cannot find trait `ThisTraitReallyDoesntExistInAnyModuleReally` in this scope
| ^^^ not found in this scope
|
help: possible candidate is found in another module, you can import it into scope
- | use std::ops::Div;
+ |
+11 | use std::ops::Div;
+ |
error: cannot continue compilation due to previous error
| ^ not found in this scope
|
help: possible candidate is found in another module, you can import it into scope
- | use foo::bar::T;
+ |
+11 | use foo::bar::T;
+ |
error[E0601]: main function not found
| ^^^^^^^^^^ not found in this scope
|
help: possible candidate is found in another module, you can import it into scope
- | use issue_21221_3::outer::OuterTrait;
+ |
+16 | use issue_21221_3::outer::OuterTrait;
+ |
error: cannot continue compilation due to previous error
| ^ not found in this scope
|
help: possible candidate is found in another module, you can import it into scope
- | use issue_21221_4::T;
+ |
+16 | use issue_21221_4::T;
+ |
error: cannot continue compilation due to previous error
| ^^^ type aliases cannot be used for traits
|
help: possible better candidate is found in another module, you can import it into scope
- | use issue_3907::Foo;
+ |
+12 | use issue_3907::Foo;
+ |
error: cannot continue compilation due to previous error
| constructor is not visible here due to private fields
|
help: possible better candidate is found in another module, you can import it into scope
- | use m::n::Z;
+ |
+15 | use m::n::Z;
+ |
error[E0423]: expected value, found struct `S`
--> $DIR/privacy-struct-ctor.rs:36:5
| constructor is not visible here due to private fields
|
help: possible better candidate is found in another module, you can import it into scope
- | use m::S;
+ |
+13 | use m::S;
+ |
error[E0423]: expected value, found struct `xcrate::S`
--> $DIR/privacy-struct-ctor.rs:42:5
| constructor is not visible here due to private fields
|
help: possible better candidate is found in another module, you can import it into scope
- | use m::S;
+ |
+13 | use m::S;
+ |
error[E0603]: tuple struct `Z` is private
--> $DIR/privacy-struct-ctor.rs:25:9
| ^^^ not a trait
|
help: possible better candidate is found in another module, you can import it into scope
- | use std::ops::Add;
+ |
+11 | use std::ops::Add;
+ |
error[E0601]: main function not found
| ^^^^^^^^^^^^^^^^^^^ `+` can't be used to concatenate two `&str` strings
|
help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left.
- | let x = "Hello ".to_owned() + "World!";
+ |
+12 | let x = "Hello ".to_owned() + "World!";
+ | ^^^^^^^^^^^^^^^^^^^
error[E0369]: binary operation `+` cannot be applied to type `World`
--> $DIR/issue-39018.rs:17:13