Auto merge of #67419 - Centril:rollup-v7b0ypv, r=Centril

Rollup of 8 pull requests

Successful merges:

 - #67189 (Unify binop wording)
 - #67270 (std: Implement `LineWriter::write_vectored`)
 - #67286 (Fix the configure.py TOML field for a couple LLVM options)
 - #67321 (make htons const fn)
 - #67382 (Remove some unnecessary `ATTR_*` constants.)
 - #67389 (Remove `SO_NOSIGPIPE` dummy variable on platforms that don't use it.)
 - #67394 (Remove outdated references to @T from comments)
 - #67406 (Suggest associated type when the specified one cannot be found)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-12-19 11:33:00 +00:00
commit 0de96d37fb
60 changed files with 435 additions and 217 deletions

View File

@ -59,13 +59,13 @@ o("full-tools", None, "enable all tools")
o("lld", "rust.lld", "build lld") o("lld", "rust.lld", "build lld")
o("lldb", "rust.lldb", "build lldb") o("lldb", "rust.lldb", "build lldb")
o("missing-tools", "dist.missing-tools", "allow failures when building tools") o("missing-tools", "dist.missing-tools", "allow failures when building tools")
o("use-libcxx", "llvm.use_libcxx", "build LLVM with libc++") o("use-libcxx", "llvm.use-libcxx", "build LLVM with libc++")
o("cflags", "llvm.cflags", "build LLVM with these extra compiler flags") o("cflags", "llvm.cflags", "build LLVM with these extra compiler flags")
o("cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler flags") o("cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler flags")
o("ldflags", "llvm.ldflags", "build LLVM with these extra linker flags") o("ldflags", "llvm.ldflags", "build LLVM with these extra linker flags")
o("llvm-libunwind", "rust.llvm_libunwind", "use LLVM libunwind") o("llvm-libunwind", "rust.llvm-libunwind", "use LLVM libunwind")
# Optimization and debugging options. These may be overridden by the release # Optimization and debugging options. These may be overridden by the release
# channel, etc. # channel, etc.

View File

@ -12,21 +12,13 @@ mod impls_hir;
mod impls_ty; mod impls_ty;
mod impls_syntax; mod impls_syntax;
pub const ATTR_DIRTY: Symbol = sym::rustc_dirty;
pub const ATTR_CLEAN: Symbol = sym::rustc_clean;
pub const ATTR_IF_THIS_CHANGED: Symbol = sym::rustc_if_this_changed;
pub const ATTR_THEN_THIS_WOULD_NEED: Symbol = sym::rustc_then_this_would_need;
pub const ATTR_PARTITION_REUSED: Symbol = sym::rustc_partition_reused;
pub const ATTR_PARTITION_CODEGENED: Symbol = sym::rustc_partition_codegened;
pub const ATTR_EXPECTED_CGU_REUSE: Symbol = sym::rustc_expected_cgu_reuse;
pub const IGNORED_ATTRIBUTES: &[Symbol] = &[ pub const IGNORED_ATTRIBUTES: &[Symbol] = &[
sym::cfg, sym::cfg,
ATTR_IF_THIS_CHANGED, sym::rustc_if_this_changed,
ATTR_THEN_THIS_WOULD_NEED, sym::rustc_then_this_would_need,
ATTR_DIRTY, sym::rustc_dirty,
ATTR_CLEAN, sym::rustc_clean,
ATTR_PARTITION_REUSED, sym::rustc_partition_reused,
ATTR_PARTITION_CODEGENED, sym::rustc_partition_codegened,
ATTR_EXPECTED_CGU_REUSE, sym::rustc_expected_cgu_reuse,
]; ];

View File

@ -44,11 +44,10 @@ use rustc_data_structures::graph::implementation::{
}; };
use rustc::hir; use rustc::hir;
use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc::ich::{ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED};
use std::env; use std::env;
use std::fs::{self, File}; use std::fs::{self, File};
use std::io::Write; use std::io::Write;
use syntax::ast; use syntax::{ast, symbol::sym};
use syntax_pos::Span; use syntax_pos::Span;
pub fn assert_dep_graph(tcx: TyCtxt<'_>) { pub fn assert_dep_graph(tcx: TyCtxt<'_>) {
@ -78,7 +77,7 @@ pub fn assert_dep_graph(tcx: TyCtxt<'_>) {
assert!(tcx.sess.opts.debugging_opts.query_dep_graph, assert!(tcx.sess.opts.debugging_opts.query_dep_graph,
"cannot use the `#[{}]` or `#[{}]` annotations \ "cannot use the `#[{}]` or `#[{}]` annotations \
without supplying `-Z query-dep-graph`", without supplying `-Z query-dep-graph`",
ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED); sym::rustc_if_this_changed, sym::rustc_then_this_would_need);
} }
// Check paths. // Check paths.
@ -114,7 +113,7 @@ impl IfThisChanged<'tcx> {
let def_id = self.tcx.hir().local_def_id(hir_id); let def_id = self.tcx.hir().local_def_id(hir_id);
let def_path_hash = self.tcx.def_path_hash(def_id); let def_path_hash = self.tcx.def_path_hash(def_id);
for attr in attrs { for attr in attrs {
if attr.check_name(ATTR_IF_THIS_CHANGED) { if attr.check_name(sym::rustc_if_this_changed) {
let dep_node_interned = self.argument(attr); let dep_node_interned = self.argument(attr);
let dep_node = match dep_node_interned { let dep_node = match dep_node_interned {
None => def_path_hash.to_dep_node(DepKind::Hir), None => def_path_hash.to_dep_node(DepKind::Hir),
@ -130,7 +129,7 @@ impl IfThisChanged<'tcx> {
} }
}; };
self.if_this_changed.push((attr.span, def_id, dep_node)); self.if_this_changed.push((attr.span, def_id, dep_node));
} else if attr.check_name(ATTR_THEN_THIS_WOULD_NEED) { } else if attr.check_name(sym::rustc_then_this_would_need) {
let dep_node_interned = self.argument(attr); let dep_node_interned = self.argument(attr);
let dep_node = match dep_node_interned { let dep_node = match dep_node_interned {
Some(n) => { Some(n) => {

View File

@ -28,8 +28,6 @@ use rustc::ty::TyCtxt;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use syntax::ast; use syntax::ast;
use syntax::symbol::{Symbol, sym}; use syntax::symbol::{Symbol, sym};
use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED,
ATTR_EXPECTED_CGU_REUSE};
pub fn assert_module_sources(tcx: TyCtxt<'_>) { pub fn assert_module_sources(tcx: TyCtxt<'_>) {
tcx.dep_graph.with_ignore(|| { tcx.dep_graph.with_ignore(|| {
@ -62,11 +60,11 @@ struct AssertModuleSource<'tcx> {
impl AssertModuleSource<'tcx> { impl AssertModuleSource<'tcx> {
fn check_attr(&self, attr: &ast::Attribute) { fn check_attr(&self, attr: &ast::Attribute) {
let (expected_reuse, comp_kind) = if attr.check_name(ATTR_PARTITION_REUSED) { let (expected_reuse, comp_kind) = if attr.check_name(sym::rustc_partition_reused) {
(CguReuse::PreLto, ComparisonKind::AtLeast) (CguReuse::PreLto, ComparisonKind::AtLeast)
} else if attr.check_name(ATTR_PARTITION_CODEGENED) { } else if attr.check_name(sym::rustc_partition_codegened) {
(CguReuse::No, ComparisonKind::Exact) (CguReuse::No, ComparisonKind::Exact)
} else if attr.check_name(ATTR_EXPECTED_CGU_REUSE) { } else if attr.check_name(sym::rustc_expected_cgu_reuse) {
match &*self.field(attr, sym::kind).as_str() { match &*self.field(attr, sym::kind).as_str() {
"no" => (CguReuse::No, ComparisonKind::Exact), "no" => (CguReuse::No, ComparisonKind::Exact),
"pre-lto" => (CguReuse::PreLto, ComparisonKind::Exact), "pre-lto" => (CguReuse::PreLto, ComparisonKind::Exact),

View File

@ -22,7 +22,6 @@ use rustc::hir::Node as HirNode;
use rustc::hir::def_id::DefId; use rustc::hir::def_id::DefId;
use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::hir::intravisit; use rustc::hir::intravisit;
use rustc::ich::{ATTR_DIRTY, ATTR_CLEAN};
use rustc::ty::TyCtxt; use rustc::ty::TyCtxt;
use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
@ -224,7 +223,7 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
let mut all_attrs = FindAllAttrs { let mut all_attrs = FindAllAttrs {
tcx, tcx,
attr_names: vec![ATTR_DIRTY, ATTR_CLEAN], attr_names: vec![sym::rustc_dirty, sym::rustc_clean],
found_attrs: vec![], found_attrs: vec![],
}; };
intravisit::walk_crate(&mut all_attrs, krate); intravisit::walk_crate(&mut all_attrs, krate);
@ -246,9 +245,9 @@ impl DirtyCleanVisitor<'tcx> {
fn assertion_maybe(&mut self, item_id: hir::HirId, attr: &Attribute) fn assertion_maybe(&mut self, item_id: hir::HirId, attr: &Attribute)
-> Option<Assertion> -> Option<Assertion>
{ {
let is_clean = if attr.check_name(ATTR_DIRTY) { let is_clean = if attr.check_name(sym::rustc_dirty) {
false false
} else if attr.check_name(ATTR_CLEAN) { } else if attr.check_name(sym::rustc_clean) {
true true
} else { } else {
// skip: not rustc_clean/dirty // skip: not rustc_clean/dirty

View File

@ -1145,11 +1145,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
} else { } else {
// Otherwise, we have to walk through the supertraits to find // Otherwise, we have to walk through the supertraits to find
// those that do. // those that do.
let candidates = traits::supertraits(tcx, trait_ref).filter(|r| {
self.trait_defines_associated_type_named(r.def_id(), binding.item_name)
});
self.one_bound_for_assoc_type( self.one_bound_for_assoc_type(
candidates, || traits::supertraits(tcx, trait_ref),
&trait_ref.print_only_trait_path().to_string(), &trait_ref.print_only_trait_path().to_string(),
binding.item_name, binding.item_name,
binding.span binding.span
@ -1531,50 +1528,48 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
debug!("find_bound_for_assoc_item: predicates={:#?}", predicates); debug!("find_bound_for_assoc_item: predicates={:#?}", predicates);
let bounds = predicates.iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref());
// Check that there is exactly one way to find an associated type with the
// correct name.
let suitable_bounds = traits::transitive_bounds(tcx, bounds)
.filter(|b| self.trait_defines_associated_type_named(b.def_id(), assoc_name));
let param_hir_id = tcx.hir().as_local_hir_id(ty_param_def_id).unwrap(); let param_hir_id = tcx.hir().as_local_hir_id(ty_param_def_id).unwrap();
let param_name = tcx.hir().ty_param_name(param_hir_id); let param_name = tcx.hir().ty_param_name(param_hir_id);
self.one_bound_for_assoc_type(suitable_bounds, self.one_bound_for_assoc_type(
&param_name.as_str(), || traits::transitive_bounds(tcx, predicates
assoc_name, .iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref())),
span) &param_name.as_str(),
assoc_name,
span,
)
} }
// Checks that `bounds` contains exactly one element and reports appropriate
// errors otherwise.
fn one_bound_for_assoc_type<I>(&self, fn one_bound_for_assoc_type<I>(&self,
mut bounds: I, all_candidates: impl Fn() -> I,
ty_param_name: &str, ty_param_name: &str,
assoc_name: ast::Ident, assoc_name: ast::Ident,
span: Span) span: Span)
-> Result<ty::PolyTraitRef<'tcx>, ErrorReported> -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
where I: Iterator<Item = ty::PolyTraitRef<'tcx>> where I: Iterator<Item = ty::PolyTraitRef<'tcx>>
{ {
let bound = match bounds.next() { let mut matching_candidates = all_candidates().filter(|r| {
self.trait_defines_associated_type_named(r.def_id(), assoc_name)
});
let bound = match matching_candidates.next() {
Some(bound) => bound, Some(bound) => bound,
None => { None => {
struct_span_err!(self.tcx().sess, span, E0220, self.complain_about_assoc_type_not_found(
"associated type `{}` not found for `{}`", all_candidates,
assoc_name, ty_param_name,
ty_param_name) assoc_name,
.span_label(span, format!("associated type `{}` not found", assoc_name)) span
.emit(); );
return Err(ErrorReported); return Err(ErrorReported);
} }
}; };
debug!("one_bound_for_assoc_type: bound = {:?}", bound); debug!("one_bound_for_assoc_type: bound = {:?}", bound);
if let Some(bound2) = bounds.next() { if let Some(bound2) = matching_candidates.next() {
debug!("one_bound_for_assoc_type: bound2 = {:?}", bound2); debug!("one_bound_for_assoc_type: bound2 = {:?}", bound2);
let bounds = iter::once(bound).chain(iter::once(bound2)).chain(bounds); let bounds = iter::once(bound).chain(iter::once(bound2)).chain(matching_candidates);
let mut err = struct_span_err!( let mut err = struct_span_err!(
self.tcx().sess, span, E0221, self.tcx().sess, span, E0221,
"ambiguous associated type `{}` in bounds of `{}`", "ambiguous associated type `{}` in bounds of `{}`",
@ -1606,6 +1601,50 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
return Ok(bound); return Ok(bound);
} }
fn complain_about_assoc_type_not_found<I>(&self,
all_candidates: impl Fn() -> I,
ty_param_name: &str,
assoc_name: ast::Ident,
span: Span)
where I: Iterator<Item = ty::PolyTraitRef<'tcx>> {
let mut err = struct_span_err!(self.tcx().sess, span, E0220,
"associated type `{}` not found for `{}`",
assoc_name,
ty_param_name);
let all_candidate_names: Vec<_> = all_candidates()
.map(|r| self.tcx().associated_items(r.def_id()))
.flatten()
.filter_map(|item|
if item.kind == ty::AssocKind::Type {
Some(item.ident.name)
} else {
None
}
)
.collect();
if let Some(suggested_name) = find_best_match_for_name(
all_candidate_names.iter(),
&assoc_name.as_str(),
None,
) {
err.span_suggestion(
span,
"there is an associated type with a similar name",
suggested_name.to_string(),
Applicability::MaybeIncorrect,
);
} else {
err.span_label(
span,
format!("associated type `{}` not found", assoc_name)
);
}
err.emit();
}
// Create a type from a path to an associated type. // Create a type from a path to an associated type.
// For a path `A::B::C::D`, `qself_ty` and `qself_def` are the type and def for `A::B::C` // For a path `A::B::C::D`, `qself_ty` and `qself_def` are the type and def for `A::B::C`
// and item_segment is the path segment for `D`. We return a type and a def for // and item_segment is the path segment for `D`. We return a type and a def for
@ -1660,10 +1699,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
} }
}; };
let candidates = traits::supertraits(tcx, ty::Binder::bind(trait_ref)) self.one_bound_for_assoc_type(
.filter(|r| self.trait_defines_associated_type_named(r.def_id(), assoc_ident)); || traits::supertraits(tcx, ty::Binder::bind(trait_ref)),
"Self",
self.one_bound_for_assoc_type(candidates, "Self", assoc_ident, span)? assoc_ident,
span
)?
} }
(&ty::Param(_), Res::SelfTy(Some(param_did), None)) | (&ty::Param(_), Res::SelfTy(Some(param_did), None)) |
(&ty::Param(_), Res::Def(DefKind::TyParam, param_did)) => { (&ty::Param(_), Res::Def(DefKind::TyParam, param_did)) => {

View File

@ -334,10 +334,70 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.emit(); err.emit();
} }
IsAssign::No => { IsAssign::No => {
let (message, missing_trait) = match op.node {
hir::BinOpKind::Add => {
(format!("cannot add `{}` to `{}`", rhs_ty, lhs_ty),
Some("std::ops::Add"))
},
hir::BinOpKind::Sub => {
(format!("cannot substract `{}` from `{}`", rhs_ty, lhs_ty),
Some("std::ops::Sub"))
},
hir::BinOpKind::Mul => {
(format!("cannot multiply `{}` to `{}`", rhs_ty, lhs_ty),
Some("std::ops::Mul"))
},
hir::BinOpKind::Div => {
(format!("cannot divide `{}` by `{}`", lhs_ty, rhs_ty),
Some("std::ops::Div"))
},
hir::BinOpKind::Rem => {
(format!("cannot mod `{}` by `{}`", lhs_ty, rhs_ty),
Some("std::ops::Rem"))
},
hir::BinOpKind::BitAnd => {
(format!("no implementation for `{} & {}`", lhs_ty, rhs_ty),
Some("std::ops::BitAnd"))
},
hir::BinOpKind::BitXor => {
(format!("no implementation for `{} ^ {}`", lhs_ty, rhs_ty),
Some("std::ops::BitXor"))
},
hir::BinOpKind::BitOr => {
(format!("no implementation for `{} | {}`", lhs_ty, rhs_ty),
Some("std::ops::BitOr"))
},
hir::BinOpKind::Shl => {
(format!("no implementation for `{} << {}`", lhs_ty, rhs_ty),
Some("std::ops::Shl"))
},
hir::BinOpKind::Shr => {
(format!("no implementation for `{} >> {}`", lhs_ty, rhs_ty),
Some("std::ops::Shr"))
},
hir::BinOpKind::Eq |
hir::BinOpKind::Ne => {
(format!(
"binary operation `{}` cannot be applied to type `{}`",
op.node.as_str(), lhs_ty),
Some("std::cmp::PartialEq"))
},
hir::BinOpKind::Lt |
hir::BinOpKind::Le |
hir::BinOpKind::Gt |
hir::BinOpKind::Ge => {
(format!(
"binary operation `{}` cannot be applied to type `{}`",
op.node.as_str(), lhs_ty),
Some("std::cmp::PartialOrd"))
}
_ => (format!(
"binary operation `{}` cannot be applied to type `{}`",
op.node.as_str(), lhs_ty),
None)
};
let mut err = struct_span_err!(self.tcx.sess, op.span, E0369, let mut err = struct_span_err!(self.tcx.sess, op.span, E0369,
"binary operation `{}` cannot be applied to type `{}`", "{}", message.as_str());
op.node.as_str(),
lhs_ty);
let mut involves_fn = false; let mut involves_fn = false;
if !lhs_expr.span.eq(&rhs_expr.span) { if !lhs_expr.span.eq(&rhs_expr.span) {
@ -382,25 +442,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
} }
let missing_trait = match op.node {
hir::BinOpKind::Add => Some("std::ops::Add"),
hir::BinOpKind::Sub => Some("std::ops::Sub"),
hir::BinOpKind::Mul => Some("std::ops::Mul"),
hir::BinOpKind::Div => Some("std::ops::Div"),
hir::BinOpKind::Rem => Some("std::ops::Rem"),
hir::BinOpKind::BitAnd => Some("std::ops::BitAnd"),
hir::BinOpKind::BitXor => Some("std::ops::BitXor"),
hir::BinOpKind::BitOr => Some("std::ops::BitOr"),
hir::BinOpKind::Shl => Some("std::ops::Shl"),
hir::BinOpKind::Shr => Some("std::ops::Shr"),
hir::BinOpKind::Eq |
hir::BinOpKind::Ne => Some("std::cmp::PartialEq"),
hir::BinOpKind::Lt |
hir::BinOpKind::Le |
hir::BinOpKind::Gt |
hir::BinOpKind::Ge => Some("std::cmp::PartialOrd"),
_ => None
};
if let Some(missing_trait) = missing_trait { if let Some(missing_trait) = missing_trait {
if op.node == hir::BinOpKind::Add && if op.node == hir::BinOpKind::Add &&
self.check_str_addition( self.check_str_addition(

View File

@ -989,6 +989,68 @@ impl<W: Write> Write for LineWriter<W> {
} }
} }
// Vectored writes are very similar to the writes above, but adjusted for
// the list of buffers that we have to write.
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
if self.need_flush {
self.flush()?;
}
// Find the last newline, and failing that write the whole buffer
let last_newline = bufs
.iter()
.enumerate()
.rev()
.filter_map(|(i, buf)| {
let pos = memchr::memrchr(b'\n', buf)?;
Some((i, pos))
})
.next();
let (i, j) = match last_newline {
Some(pair) => pair,
None => return self.inner.write_vectored(bufs),
};
let (prefix, suffix) = bufs.split_at(i);
let (buf, suffix) = suffix.split_at(1);
let buf = &buf[0];
// Write everything up to the last newline, flushing afterwards. Note
// that only if we finished our entire `write_vectored` do we try the
// subsequent
// `write`
let mut n = 0;
let prefix_amt = prefix.iter().map(|i| i.len()).sum();
if prefix_amt > 0 {
n += self.inner.write_vectored(prefix)?;
self.need_flush = true;
}
if n == prefix_amt {
match self.inner.write(&buf[..=j]) {
Ok(m) => n += m,
Err(e) if n == 0 => return Err(e),
Err(_) => return Ok(n),
}
self.need_flush = true;
}
if self.flush().is_err() || n != j + 1 + prefix_amt {
return Ok(n);
}
// ... and now write out everything remaining
match self.inner.write(&buf[j + 1..]) {
Ok(i) => n += i,
Err(_) => return Ok(n),
}
if suffix.iter().map(|s| s.len()).sum::<usize>() == 0 {
return Ok(n)
}
match self.inner.write_vectored(suffix) {
Ok(i) => Ok(n + i),
Err(_) => Ok(n),
}
}
fn flush(&mut self) -> io::Result<()> { fn flush(&mut self) -> io::Result<()> {
self.inner.flush()?; self.inner.flush()?;
self.need_flush = false; self.need_flush = false;
@ -1015,7 +1077,7 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::io::prelude::*; use crate::io::prelude::*;
use crate::io::{self, BufReader, BufWriter, LineWriter, SeekFrom}; use crate::io::{self, BufReader, BufWriter, LineWriter, SeekFrom, IoSlice};
use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sync::atomic::{AtomicUsize, Ordering};
use crate::thread; use crate::thread;
@ -1483,4 +1545,112 @@ mod tests {
assert_eq!(l.write(b"a").unwrap_err().kind(), io::ErrorKind::Other) assert_eq!(l.write(b"a").unwrap_err().kind(), io::ErrorKind::Other)
} }
#[test]
fn line_vectored() {
let mut a = LineWriter::new(Vec::new());
assert_eq!(
a.write_vectored(&[
IoSlice::new(&[]),
IoSlice::new(b"\n"),
IoSlice::new(&[]),
IoSlice::new(b"a"),
])
.unwrap(),
2,
);
assert_eq!(a.get_ref(), b"\n");
assert_eq!(
a.write_vectored(&[
IoSlice::new(&[]),
IoSlice::new(b"b"),
IoSlice::new(&[]),
IoSlice::new(b"a"),
IoSlice::new(&[]),
IoSlice::new(b"c"),
])
.unwrap(),
3,
);
assert_eq!(a.get_ref(), b"\n");
a.flush().unwrap();
assert_eq!(a.get_ref(), b"\nabac");
assert_eq!(a.write_vectored(&[]).unwrap(), 0);
assert_eq!(
a.write_vectored(&[
IoSlice::new(&[]),
IoSlice::new(&[]),
IoSlice::new(&[]),
IoSlice::new(&[]),
])
.unwrap(),
0,
);
assert_eq!(a.write_vectored(&[IoSlice::new(b"a\nb"),]).unwrap(), 3);
assert_eq!(a.get_ref(), b"\nabaca\n");
}
#[test]
fn line_vectored_partial_and_errors() {
enum Call {
Write { inputs: Vec<&'static [u8]>, output: io::Result<usize> },
Flush { output: io::Result<()> },
}
struct Writer {
calls: Vec<Call>,
}
impl Write for Writer {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.write_vectored(&[IoSlice::new(buf)])
}
fn write_vectored(&mut self, buf: &[IoSlice<'_>]) -> io::Result<usize> {
match self.calls.pop().unwrap() {
Call::Write { inputs, output } => {
assert_eq!(inputs, buf.iter().map(|b| &**b).collect::<Vec<_>>());
output
}
_ => panic!("unexpected call to write"),
}
}
fn flush(&mut self) -> io::Result<()> {
match self.calls.pop().unwrap() {
Call::Flush { output } => output,
_ => panic!("unexpected call to flush"),
}
}
}
impl Drop for Writer {
fn drop(&mut self) {
if !thread::panicking() {
assert_eq!(self.calls.len(), 0);
}
}
}
// partial writes keep going
let mut a = LineWriter::new(Writer { calls: Vec::new() });
a.write_vectored(&[IoSlice::new(&[]), IoSlice::new(b"abc")]).unwrap();
a.get_mut().calls.push(Call::Flush { output: Ok(()) });
a.get_mut().calls.push(Call::Write { inputs: vec![b"bcx\n"], output: Ok(4) });
a.get_mut().calls.push(Call::Write { inputs: vec![b"abcx\n"], output: Ok(1) });
a.write_vectored(&[IoSlice::new(b"x"), IoSlice::new(b"\n")]).unwrap();
a.get_mut().calls.push(Call::Flush { output: Ok(()) });
a.flush().unwrap();
// erroneous writes stop and don't write more
a.get_mut().calls.push(Call::Write { inputs: vec![b"x\n"], output: Err(err()) });
assert_eq!(a.write_vectored(&[IoSlice::new(b"x"), IoSlice::new(b"\na")]).unwrap(), 2);
a.get_mut().calls.push(Call::Flush { output: Ok(()) });
a.get_mut().calls.push(Call::Write { inputs: vec![b"x\n"], output: Ok(2) });
a.flush().unwrap();
fn err() -> io::Error {
io::Error::new(io::ErrorKind::Other, "x")
}
}
} }

View File

@ -4,7 +4,7 @@ use crate::hash;
use crate::io; use crate::io;
use crate::iter; use crate::iter;
use crate::mem; use crate::mem;
use crate::net::{hton, ntoh, IpAddr, Ipv4Addr, Ipv6Addr}; use crate::net::{htons, ntohs, IpAddr, Ipv4Addr, Ipv6Addr};
use crate::option; use crate::option;
use crate::slice; use crate::slice;
use crate::sys::net::netc as c; use crate::sys::net::netc as c;
@ -276,7 +276,7 @@ impl SocketAddrV4 {
SocketAddrV4 { SocketAddrV4 {
inner: c::sockaddr_in { inner: c::sockaddr_in {
sin_family: c::AF_INET as c::sa_family_t, sin_family: c::AF_INET as c::sa_family_t,
sin_port: hton(port), sin_port: htons(port),
sin_addr: *ip.as_inner(), sin_addr: *ip.as_inner(),
..unsafe { mem::zeroed() } ..unsafe { mem::zeroed() }
}, },
@ -326,7 +326,7 @@ impl SocketAddrV4 {
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn port(&self) -> u16 { pub fn port(&self) -> u16 {
ntoh(self.inner.sin_port) ntohs(self.inner.sin_port)
} }
/// Changes the port number associated with this socket address. /// Changes the port number associated with this socket address.
@ -342,7 +342,7 @@ impl SocketAddrV4 {
/// ``` /// ```
#[stable(feature = "sockaddr_setters", since = "1.9.0")] #[stable(feature = "sockaddr_setters", since = "1.9.0")]
pub fn set_port(&mut self, new_port: u16) { pub fn set_port(&mut self, new_port: u16) {
self.inner.sin_port = hton(new_port); self.inner.sin_port = htons(new_port);
} }
} }
@ -368,7 +368,7 @@ impl SocketAddrV6 {
SocketAddrV6 { SocketAddrV6 {
inner: c::sockaddr_in6 { inner: c::sockaddr_in6 {
sin6_family: c::AF_INET6 as c::sa_family_t, sin6_family: c::AF_INET6 as c::sa_family_t,
sin6_port: hton(port), sin6_port: htons(port),
sin6_addr: *ip.as_inner(), sin6_addr: *ip.as_inner(),
sin6_flowinfo: flowinfo, sin6_flowinfo: flowinfo,
sin6_scope_id: scope_id, sin6_scope_id: scope_id,
@ -420,7 +420,7 @@ impl SocketAddrV6 {
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn port(&self) -> u16 { pub fn port(&self) -> u16 {
ntoh(self.inner.sin6_port) ntohs(self.inner.sin6_port)
} }
/// Changes the port number associated with this socket address. /// Changes the port number associated with this socket address.
@ -436,7 +436,7 @@ impl SocketAddrV6 {
/// ``` /// ```
#[stable(feature = "sockaddr_setters", since = "1.9.0")] #[stable(feature = "sockaddr_setters", since = "1.9.0")]
pub fn set_port(&mut self, new_port: u16) { pub fn set_port(&mut self, new_port: u16) {
self.inner.sin6_port = hton(new_port); self.inner.sin6_port = htons(new_port);
} }
/// Returns the flow information associated with this address. /// Returns the flow information associated with this address.

View File

@ -85,21 +85,10 @@ pub enum Shutdown {
Both, Both,
} }
#[doc(hidden)] #[inline]
trait NetInt { const fn htons(i: u16) -> u16 { i.to_be() }
fn from_be(i: Self) -> Self; #[inline]
fn to_be(&self) -> Self; const fn ntohs(i: u16) -> u16 { u16::from_be(i) }
}
macro_rules! doit {
($($t:ident)*) => ($(impl NetInt for $t {
fn from_be(i: Self) -> Self { <$t>::from_be(i) }
fn to_be(&self) -> Self { <$t>::to_be(*self) }
})*)
}
doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
fn hton<I: NetInt>(i: I) -> I { i.to_be() }
fn ntoh<I: NetInt>(i: I) -> I { I::from_be(i) }
fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T> fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
where F: FnMut(io::Result<&SocketAddr>) -> io::Result<T> where F: FnMut(io::Result<&SocketAddr>) -> io::Result<T>

View File

@ -28,14 +28,6 @@ use libc::SOCK_CLOEXEC;
#[cfg(not(target_os = "linux"))] #[cfg(not(target_os = "linux"))]
const SOCK_CLOEXEC: c_int = 0; const SOCK_CLOEXEC: c_int = 0;
// Another conditional constant for name resolution: Macos et iOS use
// SO_NOSIGPIPE as a setsockopt flag to disable SIGPIPE emission on socket.
// Other platforms do otherwise.
#[cfg(target_vendor = "apple")]
use libc::SO_NOSIGPIPE;
#[cfg(not(target_vendor = "apple"))]
const SO_NOSIGPIPE: c_int = 0;
pub struct Socket(FileDesc); pub struct Socket(FileDesc);
pub fn init() {} pub fn init() {}
@ -89,9 +81,12 @@ impl Socket {
let fd = FileDesc::new(fd); let fd = FileDesc::new(fd);
fd.set_cloexec()?; fd.set_cloexec()?;
let socket = Socket(fd); let socket = Socket(fd);
if cfg!(target_vendor = "apple") {
setsockopt(&socket, libc::SOL_SOCKET, SO_NOSIGPIPE, 1)?; // macOS and iOS use `SO_NOSIGPIPE` as a `setsockopt`
} // flag to disable `SIGPIPE` emission on socket.
#[cfg(target_vendor = "apple")]
setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)?;
Ok(socket) Ok(socket)
} }
} }

View File

@ -19,7 +19,6 @@ pub extern crate libc as netc;
pub type wrlen_t = size_t; pub type wrlen_t = size_t;
const SOCK_CLOEXEC: c_int = 0; const SOCK_CLOEXEC: c_int = 0;
const SO_NOSIGPIPE: c_int = 0;
pub struct Socket(FileDesc); pub struct Socket(FileDesc);

View File

@ -1,17 +1,12 @@
//! The AST pointer. //! The AST pointer.
//! //!
//! Provides `P<T>`, a frozen owned smart pointer, as a replacement for `@T` in //! Provides `P<T>`, a frozen owned smart pointer.
//! the AST.
//! //!
//! # Motivations and benefits //! # Motivations and benefits
//! //!
//! * **Identity**: sharing AST nodes is problematic for the various analysis //! * **Identity**: sharing AST nodes is problematic for the various analysis
//! passes (e.g., one may be able to bypass the borrow checker with a shared //! passes (e.g., one may be able to bypass the borrow checker with a shared
//! `ExprKind::AddrOf` node taking a mutable borrow). The only reason `@T` in the //! `ExprKind::AddrOf` node taking a mutable borrow).
//! AST hasn't caused issues is because of inefficient folding passes which
//! would always deduplicate any such shared nodes. Even if the AST were to
//! switch to an arena, this would still hold, i.e., it couldn't use `&'a T`,
//! but rather a wrapper like `P<'a, T>`.
//! //!
//! * **Immutability**: `P<T>` disallows mutating its inner `T`, unlike `Box<T>` //! * **Immutability**: `P<T>` disallows mutating its inner `T`, unlike `Box<T>`
//! (unless it contains an `Unsafe` interior, but that may be denied later). //! (unless it contains an `Unsafe` interior, but that may be denied later).

View File

@ -13,13 +13,13 @@ fn main() {
let a: Clam = Clam{x: box 1, y: box 2}; let a: Clam = Clam{x: box 1, y: box 2};
let b: Clam = Clam{x: box 10, y: box 20}; let b: Clam = Clam{x: box 10, y: box 20};
let z: isize = a.x + b.y; let z: isize = a.x + b.y;
//~^ ERROR binary operation `+` cannot be applied to type `std::boxed::Box<isize>` //~^ ERROR cannot add `std::boxed::Box<isize>` to `std::boxed::Box<isize>`
println!("{}", z); println!("{}", z);
assert_eq!(z, 21); assert_eq!(z, 21);
let forty: Fish = Fish{a: box 40}; let forty: Fish = Fish{a: box 40};
let two: Fish = Fish{a: box 2}; let two: Fish = Fish{a: box 2};
let answer: isize = forty.a + two.a; let answer: isize = forty.a + two.a;
//~^ ERROR binary operation `+` cannot be applied to type `std::boxed::Box<isize>` //~^ ERROR cannot add `std::boxed::Box<isize>` to `std::boxed::Box<isize>`
println!("{}", answer); println!("{}", answer);
assert_eq!(answer, 42); assert_eq!(answer, 42);
} }

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `+` cannot be applied to type `std::boxed::Box<isize>` error[E0369]: cannot add `std::boxed::Box<isize>` to `std::boxed::Box<isize>`
--> $DIR/autoderef-full-lval.rs:15:24 --> $DIR/autoderef-full-lval.rs:15:24
| |
LL | let z: isize = a.x + b.y; LL | let z: isize = a.x + b.y;
@ -8,7 +8,7 @@ LL | let z: isize = a.x + b.y;
| |
= note: an implementation of `std::ops::Add` might be missing for `std::boxed::Box<isize>` = note: an implementation of `std::ops::Add` might be missing for `std::boxed::Box<isize>`
error[E0369]: binary operation `+` cannot be applied to type `std::boxed::Box<isize>` error[E0369]: cannot add `std::boxed::Box<isize>` to `std::boxed::Box<isize>`
--> $DIR/autoderef-full-lval.rs:21:33 --> $DIR/autoderef-full-lval.rs:21:33
| |
LL | let answer: isize = forty.a + two.a; LL | let answer: isize = forty.a + two.a;

View File

@ -2,7 +2,7 @@ fn main() {
let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9]; let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
let vr = v.iter().filter(|x| { let vr = v.iter().filter(|x| {
x % 2 == 0 x % 2 == 0
//~^ ERROR binary operation `%` cannot be applied to type `&&{integer}` //~^ ERROR cannot mod `&&{integer}` by `{integer}`
}); });
println!("{:?}", vr); println!("{:?}", vr);
} }

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `%` cannot be applied to type `&&{integer}` error[E0369]: cannot mod `&&{integer}` by `{integer}`
--> $DIR/binary-op-on-double-ref.rs:4:11 --> $DIR/binary-op-on-double-ref.rs:4:11
| |
LL | x % 2 == 0 LL | x % 2 == 0

View File

@ -1,3 +1,3 @@
// error-pattern:`^` cannot be applied to type `std::string::String` // error-pattern:no implementation for `std::string::String ^ std::string::String`
fn main() { let x = "a".to_string() ^ "b".to_string(); } fn main() { let x = "a".to_string() ^ "b".to_string(); }

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `^` cannot be applied to type `std::string::String` error[E0369]: no implementation for `std::string::String ^ std::string::String`
--> $DIR/binop-bitxor-str.rs:3:37 --> $DIR/binop-bitxor-str.rs:3:37
| |
LL | fn main() { let x = "a".to_string() ^ "b".to_string(); } LL | fn main() { let x = "a".to_string() ^ "b".to_string(); }

View File

@ -1,3 +1,3 @@
// error-pattern:`*` cannot be applied to type `bool` // error-pattern:cannot multiply `bool` to `bool`
fn main() { let x = true * false; } fn main() { let x = true * false; }

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `*` cannot be applied to type `bool` error[E0369]: cannot multiply `bool` to `bool`
--> $DIR/binop-mul-bool.rs:3:26 --> $DIR/binop-mul-bool.rs:3:26
| |
LL | fn main() { let x = true * false; } LL | fn main() { let x = true * false; }

View File

@ -4,5 +4,5 @@ fn main() {
let x = true; let x = true;
let y = 1; let y = 1;
let z = x + y; let z = x + y;
//~^ ERROR binary operation `+` cannot be applied to type `bool` //~^ ERROR cannot add `{integer}` to `bool`
} }

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `+` cannot be applied to type `bool` error[E0369]: cannot add `{integer}` to `bool`
--> $DIR/binop-typeck.rs:6:15 --> $DIR/binop-typeck.rs:6:15
| |
LL | let z = x + y; LL | let z = x + y;

View File

@ -1,5 +1,5 @@
pub fn main() { pub fn main() {
let x = () + (); //~ ERROR binary operation let x = () + (); //~ ERROR cannot add `()` to `()`
// this shouldn't have a flow-on error: // this shouldn't have a flow-on error:
for _ in x {} for _ in x {}

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `+` cannot be applied to type `()` error[E0369]: cannot add `()` to `()`
--> $DIR/for-loop-type-error.rs:2:16 --> $DIR/for-loop-type-error.rs:2:16
| |
LL | let x = () + (); LL | let x = () + ();

View File

@ -4,5 +4,5 @@ fn main() {
let x: Box<isize> = box 0; let x: Box<isize> = box 0;
println!("{}", x + 1); println!("{}", x + 1);
//~^ ERROR binary operation `+` cannot be applied to type `std::boxed::Box<isize>` //~^ ERROR cannot add `{integer}` to `std::boxed::Box<isize>`
} }

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `+` cannot be applied to type `std::boxed::Box<isize>` error[E0369]: cannot add `{integer}` to `std::boxed::Box<isize>`
--> $DIR/issue-14915.rs:6:22 --> $DIR/issue-14915.rs:6:22
| |
LL | println!("{}", x + 1); LL | println!("{}", x + 1);

View File

@ -1,6 +1,6 @@
fn main() { fn main() {
1.create_a_type_error[ //~ `{integer}` is a primitive type and therefore doesn't have fields 1.create_a_type_error[ //~ `{integer}` is a primitive type and therefore doesn't have fields
()+() //~ ERROR binary operation `+` cannot be applied ()+() //~ ERROR cannot add
// ^ ensure that we typeck the inner expression ^ // ^ ensure that we typeck the inner expression ^
]; ];
} }

View File

@ -4,7 +4,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
LL | 1.create_a_type_error[ LL | 1.create_a_type_error[
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^
error[E0369]: binary operation `+` cannot be applied to type `()` error[E0369]: cannot add `()` to `()`
--> $DIR/issue-24363.rs:3:11 --> $DIR/issue-24363.rs:3:11
| |
LL | ()+() LL | ()+()

View File

@ -3,23 +3,23 @@ struct A;
fn main() { fn main() {
let a = A; let a = A;
a + a; //~ ERROR binary operation `+` cannot be applied to type `A` a + a; //~ ERROR cannot add `A` to `A`
a - a; //~ ERROR binary operation `-` cannot be applied to type `A` a - a; //~ ERROR cannot substract `A` from `A`
a * a; //~ ERROR binary operation `*` cannot be applied to type `A` a * a; //~ ERROR cannot multiply `A` to `A`
a / a; //~ ERROR binary operation `/` cannot be applied to type `A` a / a; //~ ERROR cannot divide `A` by `A`
a % a; //~ ERROR binary operation `%` cannot be applied to type `A` a % a; //~ ERROR cannot mod `A` by `A`
a & a; //~ ERROR binary operation `&` cannot be applied to type `A` a & a; //~ ERROR no implementation for `A & A`
a | a; //~ ERROR binary operation `|` cannot be applied to type `A` a | a; //~ ERROR no implementation for `A | A`
a << a; //~ ERROR binary operation `<<` cannot be applied to type `A` a << a; //~ ERROR no implementation for `A << A`
a >> a; //~ ERROR binary operation `>>` cannot be applied to type `A` a >> a; //~ ERROR no implementation for `A >> A`
a == a; //~ ERROR binary operation `==` cannot be applied to type `A` a == a; //~ ERROR binary operation `==` cannot be applied to type `A`

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `+` cannot be applied to type `A` error[E0369]: cannot add `A` to `A`
--> $DIR/issue-28837.rs:6:7 --> $DIR/issue-28837.rs:6:7
| |
LL | a + a; LL | a + a;
@ -8,7 +8,7 @@ LL | a + a;
| |
= note: an implementation of `std::ops::Add` might be missing for `A` = note: an implementation of `std::ops::Add` might be missing for `A`
error[E0369]: binary operation `-` cannot be applied to type `A` error[E0369]: cannot substract `A` from `A`
--> $DIR/issue-28837.rs:8:7 --> $DIR/issue-28837.rs:8:7
| |
LL | a - a; LL | a - a;
@ -18,7 +18,7 @@ LL | a - a;
| |
= note: an implementation of `std::ops::Sub` might be missing for `A` = note: an implementation of `std::ops::Sub` might be missing for `A`
error[E0369]: binary operation `*` cannot be applied to type `A` error[E0369]: cannot multiply `A` to `A`
--> $DIR/issue-28837.rs:10:7 --> $DIR/issue-28837.rs:10:7
| |
LL | a * a; LL | a * a;
@ -28,7 +28,7 @@ LL | a * a;
| |
= note: an implementation of `std::ops::Mul` might be missing for `A` = note: an implementation of `std::ops::Mul` might be missing for `A`
error[E0369]: binary operation `/` cannot be applied to type `A` error[E0369]: cannot divide `A` by `A`
--> $DIR/issue-28837.rs:12:7 --> $DIR/issue-28837.rs:12:7
| |
LL | a / a; LL | a / a;
@ -38,7 +38,7 @@ LL | a / a;
| |
= note: an implementation of `std::ops::Div` might be missing for `A` = note: an implementation of `std::ops::Div` might be missing for `A`
error[E0369]: binary operation `%` cannot be applied to type `A` error[E0369]: cannot mod `A` by `A`
--> $DIR/issue-28837.rs:14:7 --> $DIR/issue-28837.rs:14:7
| |
LL | a % a; LL | a % a;
@ -48,7 +48,7 @@ LL | a % a;
| |
= note: an implementation of `std::ops::Rem` might be missing for `A` = note: an implementation of `std::ops::Rem` might be missing for `A`
error[E0369]: binary operation `&` cannot be applied to type `A` error[E0369]: no implementation for `A & A`
--> $DIR/issue-28837.rs:16:7 --> $DIR/issue-28837.rs:16:7
| |
LL | a & a; LL | a & a;
@ -58,7 +58,7 @@ LL | a & a;
| |
= note: an implementation of `std::ops::BitAnd` might be missing for `A` = note: an implementation of `std::ops::BitAnd` might be missing for `A`
error[E0369]: binary operation `|` cannot be applied to type `A` error[E0369]: no implementation for `A | A`
--> $DIR/issue-28837.rs:18:7 --> $DIR/issue-28837.rs:18:7
| |
LL | a | a; LL | a | a;
@ -68,7 +68,7 @@ LL | a | a;
| |
= note: an implementation of `std::ops::BitOr` might be missing for `A` = note: an implementation of `std::ops::BitOr` might be missing for `A`
error[E0369]: binary operation `<<` cannot be applied to type `A` error[E0369]: no implementation for `A << A`
--> $DIR/issue-28837.rs:20:7 --> $DIR/issue-28837.rs:20:7
| |
LL | a << a; LL | a << a;
@ -78,7 +78,7 @@ LL | a << a;
| |
= note: an implementation of `std::ops::Shl` might be missing for `A` = note: an implementation of `std::ops::Shl` might be missing for `A`
error[E0369]: binary operation `>>` cannot be applied to type `A` error[E0369]: no implementation for `A >> A`
--> $DIR/issue-28837.rs:22:7 --> $DIR/issue-28837.rs:22:7
| |
LL | a >> a; LL | a >> a;

View File

@ -11,7 +11,7 @@ impl Add<i32> for i32 {}
fn main() { fn main() {
let x = 5 + 6; let x = 5 + 6;
//~^ ERROR binary operation `+` cannot be applied to type `{integer}` //~^ ERROR cannot add `{integer}` to `{integer}`
let y = 5i32 + 6i32; let y = 5i32 + 6i32;
//~^ ERROR binary operation `+` cannot be applied to type `i32` //~^ ERROR cannot add `i32` to `i32`
} }

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `+` cannot be applied to type `{integer}` error[E0369]: cannot add `{integer}` to `{integer}`
--> $DIR/issue-31076.rs:13:15 --> $DIR/issue-31076.rs:13:15
| |
LL | let x = 5 + 6; LL | let x = 5 + 6;
@ -8,7 +8,7 @@ LL | let x = 5 + 6;
| |
= note: an implementation of `std::ops::Add` might be missing for `{integer}` = note: an implementation of `std::ops::Add` might be missing for `{integer}`
error[E0369]: binary operation `+` cannot be applied to type `i32` error[E0369]: cannot add `i32` to `i32`
--> $DIR/issue-31076.rs:15:18 --> $DIR/issue-31076.rs:15:18
| |
LL | let y = 5i32 + 6i32; LL | let y = 5i32 + 6i32;

View File

@ -1,6 +1,6 @@
fn func<'a, T>(a: &'a [T]) -> impl Iterator<Item=&'a T> { fn func<'a, T>(a: &'a [T]) -> impl Iterator<Item=&'a T> {
a.iter().map(|a| a*a) a.iter().map(|a| a*a)
//~^ ERROR binary operation `*` cannot be applied to type `&T` //~^ ERROR cannot multiply `&T` to `&T`
} }
fn main() { fn main() {

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `*` cannot be applied to type `&T` error[E0369]: cannot multiply `&T` to `&T`
--> $DIR/issue-35668.rs:2:23 --> $DIR/issue-35668.rs:2:23
| |
LL | a.iter().map(|a| a*a) LL | a.iter().map(|a| a*a)

View File

@ -11,5 +11,5 @@ impl Thing {
fn main() { fn main() {
let u = Thing {x: 2}; let u = Thing {x: 2};
let _v = u.mul(&3); // This is ok let _v = u.mul(&3); // This is ok
let w = u * 3; //~ ERROR binary operation `*` cannot be applied to type `Thing` let w = u * 3; //~ ERROR cannot multiply `{integer}` to `Thing`
} }

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `*` cannot be applied to type `Thing` error[E0369]: cannot multiply `{integer}` to `Thing`
--> $DIR/issue-3820.rs:14:15 --> $DIR/issue-3820.rs:14:15
| |
LL | let w = u * 3; LL | let w = u * 3;

View File

@ -2,5 +2,5 @@ fn f(_: &[f32]) {}
fn main() { fn main() {
() + f(&[1.0]); () + f(&[1.0]);
//~^ ERROR binary operation `+` cannot be applied to type `()` //~^ ERROR cannot add `()` to `()`
} }

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `+` cannot be applied to type `()` error[E0369]: cannot add `()` to `()`
--> $DIR/issue-40610.rs:4:8 --> $DIR/issue-40610.rs:4:8
| |
LL | () + f(&[1.0]); LL | () + f(&[1.0]);

View File

@ -1,6 +1,6 @@
enum Foo { enum Foo {
A = "" + 1 A = "" + 1
//~^ ERROR binary operation `+` cannot be applied to type `&str` //~^ ERROR cannot add `{integer}` to `&str`
} }
enum Bar { enum Bar {

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `+` cannot be applied to type `&str` error[E0369]: cannot add `{integer}` to `&str`
--> $DIR/issue-41394.rs:2:12 --> $DIR/issue-41394.rs:2:12
| |
LL | A = "" + 1 LL | A = "" + 1

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `+` cannot be applied to type `&str` error[E0369]: cannot add `&str` to `&str`
--> $DIR/issue-47377.rs:4:14 --> $DIR/issue-47377.rs:4:14
| |
LL | let _a = b + ", World!"; LL | let _a = b + ", World!";

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `+` cannot be applied to type `&str` error[E0369]: cannot add `&str` to `&str`
--> $DIR/issue-47380.rs:3:35 --> $DIR/issue-47380.rs:3:35
| |
LL | println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!"; LL | println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!";

View File

@ -21,7 +21,7 @@ use E::*;
fn no_top_level_or_patterns() { fn no_top_level_or_patterns() {
// We do *not* allow or-patterns at the top level of lambdas... // We do *not* allow or-patterns at the top level of lambdas...
let _ = |A | B: E| (); //~ ERROR binary operation `|` cannot be applied to type `E` let _ = |A | B: E| (); //~ ERROR no implementation for `E | ()`
// -------- This looks like an or-pattern but is in fact `|A| (B: E | ())`. // -------- This looks like an or-pattern but is in fact `|A| (B: E | ())`.
// ...and for now neither do we allow or-patterns at the top level of functions. // ...and for now neither do we allow or-patterns at the top level of functions.

View File

@ -104,7 +104,7 @@ LL | #![feature(or_patterns)]
| |
= note: `#[warn(incomplete_features)]` on by default = note: `#[warn(incomplete_features)]` on by default
error[E0369]: binary operation `|` cannot be applied to type `E` error[E0369]: no implementation for `E | ()`
--> $DIR/or-patterns-syntactic-fail.rs:24:22 --> $DIR/or-patterns-syntactic-fail.rs:24:22
| |
LL | let _ = |A | B: E| (); LL | let _ = |A | B: E| ();

View File

@ -1,6 +1,6 @@
enum Bar { T1((), Option<Vec<isize>>), T2, } enum Bar { T1((), Option<Vec<isize>>), T2, }
fn foo(t: Bar) -> isize { match t { Bar::T1(_, Some(x)) => { return x * 3; } _ => { panic!(); } } } fn foo(t: Bar) -> isize { match t { Bar::T1(_, Some(x)) => { return x * 3; } _ => { panic!(); } } }
//~^ ERROR binary operation `*` cannot be applied to //~^ ERROR cannot multiply `{integer}` to `std::vec::Vec<isize>`
fn main() { } fn main() { }

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `*` cannot be applied to type `std::vec::Vec<isize>` error[E0369]: cannot multiply `{integer}` to `std::vec::Vec<isize>`
--> $DIR/pattern-tyvar-2.rs:3:71 --> $DIR/pattern-tyvar-2.rs:3:71
| |
LL | fn foo(t: Bar) -> isize { match t { Bar::T1(_, Some(x)) => { return x * 3; } _ => { panic!(); } } } LL | fn foo(t: Bar) -> isize { match t { Bar::T1(_, Some(x)) => { return x * 3; } _ => { panic!(); } } }

View File

@ -1,15 +1,15 @@
pub fn main() { pub fn main() {
let x = "Hello " + "World!"; let x = "Hello " + "World!";
//~^ ERROR cannot be applied to type //~^ ERROR cannot add
// Make sure that the span outputs a warning // Make sure that the span outputs a warning
// for not having an implementation for std::ops::Add // for not having an implementation for std::ops::Add
// that won't output for the above string concatenation // that won't output for the above string concatenation
let y = World::Hello + World::Goodbye; let y = World::Hello + World::Goodbye;
//~^ ERROR cannot be applied to type //~^ ERROR cannot add
let x = "Hello " + "World!".to_owned(); let x = "Hello " + "World!".to_owned();
//~^ ERROR cannot be applied to type //~^ ERROR cannot add
} }
enum World { enum World {
@ -23,16 +23,16 @@ fn foo() {
let c = ""; let c = "";
let d = ""; let d = "";
let e = &a; let e = &a;
let _ = &a + &b; //~ ERROR binary operation let _ = &a + &b; //~ ERROR cannot add
let _ = &a + b; //~ ERROR binary operation let _ = &a + b; //~ ERROR cannot add
let _ = a + &b; // ok let _ = a + &b; // ok
let _ = a + b; //~ ERROR mismatched types let _ = a + b; //~ ERROR mismatched types
let _ = e + b; //~ ERROR binary operation let _ = e + b; //~ ERROR cannot add
let _ = e + &b; //~ ERROR binary operation let _ = e + &b; //~ ERROR cannot add
let _ = e + d; //~ ERROR binary operation let _ = e + d; //~ ERROR cannot add
let _ = e + &d; //~ ERROR binary operation let _ = e + &d; //~ ERROR cannot add
let _ = &c + &d; //~ ERROR binary operation let _ = &c + &d; //~ ERROR cannot add
let _ = &c + d; //~ ERROR binary operation let _ = &c + d; //~ ERROR cannot add
let _ = c + &d; //~ ERROR binary operation let _ = c + &d; //~ ERROR cannot add
let _ = c + d; //~ ERROR binary operation let _ = c + d; //~ ERROR cannot add
} }

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `+` cannot be applied to type `&str` error[E0369]: cannot add `&str` to `&str`
--> $DIR/issue-39018.rs:2:22 --> $DIR/issue-39018.rs:2:22
| |
LL | let x = "Hello " + "World!"; LL | let x = "Hello " + "World!";
@ -12,7 +12,7 @@ help: `to_owned()` can be used to create an owned `String` from a string referen
LL | let x = "Hello ".to_owned() + "World!"; LL | let x = "Hello ".to_owned() + "World!";
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^
error[E0369]: binary operation `+` cannot be applied to type `World` error[E0369]: cannot add `World` to `World`
--> $DIR/issue-39018.rs:8:26 --> $DIR/issue-39018.rs:8:26
| |
LL | let y = World::Hello + World::Goodbye; LL | let y = World::Hello + World::Goodbye;
@ -22,7 +22,7 @@ LL | let y = World::Hello + World::Goodbye;
| |
= note: an implementation of `std::ops::Add` might be missing for `World` = note: an implementation of `std::ops::Add` might be missing for `World`
error[E0369]: binary operation `+` cannot be applied to type `&str` error[E0369]: cannot add `std::string::String` to `&str`
--> $DIR/issue-39018.rs:11:22 --> $DIR/issue-39018.rs:11:22
| |
LL | let x = "Hello " + "World!".to_owned(); LL | let x = "Hello " + "World!".to_owned();
@ -36,7 +36,7 @@ help: `to_owned()` can be used to create an owned `String` from a string referen
LL | let x = "Hello ".to_owned() + &"World!".to_owned(); LL | let x = "Hello ".to_owned() + &"World!".to_owned();
| ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
error[E0369]: binary operation `+` cannot be applied to type `&std::string::String` error[E0369]: cannot add `&std::string::String` to `&std::string::String`
--> $DIR/issue-39018.rs:26:16 --> $DIR/issue-39018.rs:26:16
| |
LL | let _ = &a + &b; LL | let _ = &a + &b;
@ -50,7 +50,7 @@ help: String concatenation appends the string on the right to the string on the
LL | let _ = a + &b; LL | let _ = a + &b;
| ^ | ^
error[E0369]: binary operation `+` cannot be applied to type `&std::string::String` error[E0369]: cannot add `std::string::String` to `&std::string::String`
--> $DIR/issue-39018.rs:27:16 --> $DIR/issue-39018.rs:27:16
| |
LL | let _ = &a + b; LL | let _ = &a + b;
@ -73,7 +73,7 @@ LL | let _ = a + b;
| expected `&str`, found struct `std::string::String` | expected `&str`, found struct `std::string::String`
| help: consider borrowing here: `&b` | help: consider borrowing here: `&b`
error[E0369]: binary operation `+` cannot be applied to type `&std::string::String` error[E0369]: cannot add `std::string::String` to `&std::string::String`
--> $DIR/issue-39018.rs:30:15 --> $DIR/issue-39018.rs:30:15
| |
LL | let _ = e + b; LL | let _ = e + b;
@ -87,7 +87,7 @@ help: `to_owned()` can be used to create an owned `String` from a string referen
LL | let _ = e.to_owned() + &b; LL | let _ = e.to_owned() + &b;
| ^^^^^^^^^^^^ ^^ | ^^^^^^^^^^^^ ^^
error[E0369]: binary operation `+` cannot be applied to type `&std::string::String` error[E0369]: cannot add `&std::string::String` to `&std::string::String`
--> $DIR/issue-39018.rs:31:15 --> $DIR/issue-39018.rs:31:15
| |
LL | let _ = e + &b; LL | let _ = e + &b;
@ -101,7 +101,7 @@ help: `to_owned()` can be used to create an owned `String` from a string referen
LL | let _ = e.to_owned() + &b; LL | let _ = e.to_owned() + &b;
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error[E0369]: binary operation `+` cannot be applied to type `&std::string::String` error[E0369]: cannot add `&str` to `&std::string::String`
--> $DIR/issue-39018.rs:32:15 --> $DIR/issue-39018.rs:32:15
| |
LL | let _ = e + d; LL | let _ = e + d;
@ -115,7 +115,7 @@ help: `to_owned()` can be used to create an owned `String` from a string referen
LL | let _ = e.to_owned() + d; LL | let _ = e.to_owned() + d;
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error[E0369]: binary operation `+` cannot be applied to type `&std::string::String` error[E0369]: cannot add `&&str` to `&std::string::String`
--> $DIR/issue-39018.rs:33:15 --> $DIR/issue-39018.rs:33:15
| |
LL | let _ = e + &d; LL | let _ = e + &d;
@ -129,7 +129,7 @@ help: `to_owned()` can be used to create an owned `String` from a string referen
LL | let _ = e.to_owned() + &d; LL | let _ = e.to_owned() + &d;
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error[E0369]: binary operation `+` cannot be applied to type `&&str` error[E0369]: cannot add `&&str` to `&&str`
--> $DIR/issue-39018.rs:34:16 --> $DIR/issue-39018.rs:34:16
| |
LL | let _ = &c + &d; LL | let _ = &c + &d;
@ -139,7 +139,7 @@ LL | let _ = &c + &d;
| |
= note: an implementation of `std::ops::Add` might be missing for `&&str` = note: an implementation of `std::ops::Add` might be missing for `&&str`
error[E0369]: binary operation `+` cannot be applied to type `&&str` error[E0369]: cannot add `&str` to `&&str`
--> $DIR/issue-39018.rs:35:16 --> $DIR/issue-39018.rs:35:16
| |
LL | let _ = &c + d; LL | let _ = &c + d;
@ -149,7 +149,7 @@ LL | let _ = &c + d;
| |
= note: an implementation of `std::ops::Add` might be missing for `&&str` = note: an implementation of `std::ops::Add` might be missing for `&&str`
error[E0369]: binary operation `+` cannot be applied to type `&str` error[E0369]: cannot add `&&str` to `&str`
--> $DIR/issue-39018.rs:36:15 --> $DIR/issue-39018.rs:36:15
| |
LL | let _ = c + &d; LL | let _ = c + &d;
@ -163,7 +163,7 @@ help: `to_owned()` can be used to create an owned `String` from a string referen
LL | let _ = c.to_owned() + &d; LL | let _ = c.to_owned() + &d;
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error[E0369]: binary operation `+` cannot be applied to type `&str` error[E0369]: cannot add `&str` to `&str`
--> $DIR/issue-39018.rs:37:15 --> $DIR/issue-39018.rs:37:15
| |
LL | let _ = c + d; LL | let _ = c + d;

View File

@ -2,7 +2,7 @@ error[E0220]: associated type `Trget` not found for `std::ops::Deref`
--> $DIR/type-binding.rs:6:20 --> $DIR/type-binding.rs:6:20
| |
LL | fn homura<T: Deref<Trget = i32>>(_: T) {} LL | fn homura<T: Deref<Trget = i32>>(_: T) {}
| ^^^^^^^^^^^ associated type `Trget` not found | ^^^^^^^^^^^ help: there is an associated type with a similar name: `Target`
error: aborting due to previous error error: aborting due to previous error

View File

@ -2,6 +2,6 @@ fn main() {
let a: &String = &"1".to_owned(); let a: &String = &"1".to_owned();
let b: &str = &"2"; let b: &str = &"2";
let c = a + b; let c = a + b;
//~^ ERROR binary operation `+` cannot be applied to type `&std::string::String` //~^ ERROR cannot add `&str` to `&std::string::String`
println!("{:?}", c); println!("{:?}", c);
} }

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `+` cannot be applied to type `&std::string::String` error[E0369]: cannot add `&str` to `&std::string::String`
--> $DIR/str-concat-on-double-ref.rs:4:15 --> $DIR/str-concat-on-double-ref.rs:4:15
| |
LL | let c = a + b; LL | let c = a + b;

View File

@ -3,5 +3,5 @@
fn main() { fn main() {
let unicode_is_fun = "؁‱ஹ௸௵꧄.ဪ꧅⸻𒈙𒐫﷽𒌄𒈟𒍼𒁎𒀱𒌧𒅃 𒈓𒍙𒊎𒄡𒅌𒁏𒀰𒐪𒐩𒈙𒐫𪚥"; let unicode_is_fun = "؁‱ஹ௸௵꧄.ဪ꧅⸻𒈙𒐫﷽𒌄𒈟𒍼𒁎𒀱𒌧𒅃 𒈓𒍙𒊎𒄡𒅌𒁏𒀰𒐪𒐩𒈙𒐫𪚥";
let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇ཈ཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ཭཮཯཰ཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇ཈ཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ཭཮཯཰ཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!";
//~^ ERROR binary operation `+` cannot be applied to type `&str` //~^ ERROR cannot add `&str` to `&str`
} }

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `+` cannot be applied to type `&str` error[E0369]: cannot add `&str` to `&str`
--> $DIR/non-1-width-unicode-multiline-label.rs:5:260 --> $DIR/non-1-width-unicode-multiline-label.rs:5:260
| |
LL | ...ཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇...࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; LL | ...ཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇...࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!";

View File

@ -5,7 +5,7 @@ trait MyMul<Rhs, Res> {
} }
fn foo<T: MyMul<f64, f64>>(a: &T, b: f64) -> f64 { fn foo<T: MyMul<f64, f64>>(a: &T, b: f64) -> f64 {
a * b //~ ERROR binary operation `*` cannot be applied to type `&T` a * b //~ ERROR cannot multiply `f64` to `&T`
} }
fn main() {} fn main() {}

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `*` cannot be applied to type `&T` error[E0369]: cannot multiply `f64` to `&T`
--> $DIR/trait-resolution-in-overloaded-op.rs:8:7 --> $DIR/trait-resolution-in-overloaded-op.rs:8:7
| |
LL | a * b LL | a * b

View File

@ -2,7 +2,7 @@ fn main() {
} }
fn foo<T>(x: T, y: T) { fn foo<T>(x: T, y: T) {
let z = x + y; //~ ERROR binary operation `+` cannot be applied to type `T` let z = x + y; //~ ERROR cannot add `T` to `T`
} }
fn bar<T>(x: T) { fn bar<T>(x: T) {

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `+` cannot be applied to type `T` error[E0369]: cannot add `T` to `T`
--> $DIR/missing_trait_impl.rs:5:15 --> $DIR/missing_trait_impl.rs:5:15
| |
LL | let z = x + y; LL | let z = x + y;

View File

@ -14,6 +14,6 @@ fn main() {
let i = vec![r(0)]; let i = vec![r(0)];
let j = vec![r(1)]; let j = vec![r(1)];
let k = i + j; let k = i + j;
//~^ ERROR binary operation `+` cannot be applied to type //~^ ERROR cannot add `std::vec::Vec<R>` to `std::vec::Vec<R>`
println!("{:?}", j); println!("{:?}", j);
} }

View File

@ -1,4 +1,4 @@
error[E0369]: binary operation `+` cannot be applied to type `std::vec::Vec<R>` error[E0369]: cannot add `std::vec::Vec<R>` to `std::vec::Vec<R>`
--> $DIR/vec-res-add.rs:16:15 --> $DIR/vec-res-add.rs:16:15
| |
LL | let k = i + j; LL | let k = i + j;