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:
commit
0de96d37fb
|
@ -59,13 +59,13 @@ o("full-tools", None, "enable all tools")
|
|||
o("lld", "rust.lld", "build lld")
|
||||
o("lldb", "rust.lldb", "build lldb")
|
||||
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("cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler 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
|
||||
# channel, etc.
|
||||
|
|
|
@ -12,21 +12,13 @@ mod impls_hir;
|
|||
mod impls_ty;
|
||||
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] = &[
|
||||
sym::cfg,
|
||||
ATTR_IF_THIS_CHANGED,
|
||||
ATTR_THEN_THIS_WOULD_NEED,
|
||||
ATTR_DIRTY,
|
||||
ATTR_CLEAN,
|
||||
ATTR_PARTITION_REUSED,
|
||||
ATTR_PARTITION_CODEGENED,
|
||||
ATTR_EXPECTED_CGU_REUSE,
|
||||
sym::rustc_if_this_changed,
|
||||
sym::rustc_then_this_would_need,
|
||||
sym::rustc_dirty,
|
||||
sym::rustc_clean,
|
||||
sym::rustc_partition_reused,
|
||||
sym::rustc_partition_codegened,
|
||||
sym::rustc_expected_cgu_reuse,
|
||||
];
|
||||
|
|
|
@ -44,11 +44,10 @@ use rustc_data_structures::graph::implementation::{
|
|||
};
|
||||
use rustc::hir;
|
||||
use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||
use rustc::ich::{ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED};
|
||||
use std::env;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
use syntax::ast;
|
||||
use syntax::{ast, symbol::sym};
|
||||
use syntax_pos::Span;
|
||||
|
||||
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,
|
||||
"cannot use the `#[{}]` or `#[{}]` annotations \
|
||||
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.
|
||||
|
@ -114,7 +113,7 @@ impl IfThisChanged<'tcx> {
|
|||
let def_id = self.tcx.hir().local_def_id(hir_id);
|
||||
let def_path_hash = self.tcx.def_path_hash(def_id);
|
||||
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 = match dep_node_interned {
|
||||
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));
|
||||
} 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 = match dep_node_interned {
|
||||
Some(n) => {
|
||||
|
|
|
@ -28,8 +28,6 @@ use rustc::ty::TyCtxt;
|
|||
use std::collections::BTreeSet;
|
||||
use syntax::ast;
|
||||
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<'_>) {
|
||||
tcx.dep_graph.with_ignore(|| {
|
||||
|
@ -62,11 +60,11 @@ struct AssertModuleSource<'tcx> {
|
|||
|
||||
impl AssertModuleSource<'tcx> {
|
||||
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)
|
||||
} else if attr.check_name(ATTR_PARTITION_CODEGENED) {
|
||||
} else if attr.check_name(sym::rustc_partition_codegened) {
|
||||
(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() {
|
||||
"no" => (CguReuse::No, ComparisonKind::Exact),
|
||||
"pre-lto" => (CguReuse::PreLto, ComparisonKind::Exact),
|
||||
|
|
|
@ -22,7 +22,6 @@ use rustc::hir::Node as HirNode;
|
|||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::itemlikevisit::ItemLikeVisitor;
|
||||
use rustc::hir::intravisit;
|
||||
use rustc::ich::{ATTR_DIRTY, ATTR_CLEAN};
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
|
@ -224,7 +223,7 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
|
|||
|
||||
let mut all_attrs = FindAllAttrs {
|
||||
tcx,
|
||||
attr_names: vec![ATTR_DIRTY, ATTR_CLEAN],
|
||||
attr_names: vec![sym::rustc_dirty, sym::rustc_clean],
|
||||
found_attrs: vec![],
|
||||
};
|
||||
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)
|
||||
-> Option<Assertion>
|
||||
{
|
||||
let is_clean = if attr.check_name(ATTR_DIRTY) {
|
||||
let is_clean = if attr.check_name(sym::rustc_dirty) {
|
||||
false
|
||||
} else if attr.check_name(ATTR_CLEAN) {
|
||||
} else if attr.check_name(sym::rustc_clean) {
|
||||
true
|
||||
} else {
|
||||
// skip: not rustc_clean/dirty
|
||||
|
|
|
@ -1145,11 +1145,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
} else {
|
||||
// Otherwise, we have to walk through the supertraits to find
|
||||
// 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(
|
||||
candidates,
|
||||
|| traits::supertraits(tcx, trait_ref),
|
||||
&trait_ref.print_only_trait_path().to_string(),
|
||||
binding.item_name,
|
||||
binding.span
|
||||
|
@ -1531,50 +1528,48 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
|
||||
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_name = tcx.hir().ty_param_name(param_hir_id);
|
||||
self.one_bound_for_assoc_type(suitable_bounds,
|
||||
¶m_name.as_str(),
|
||||
assoc_name,
|
||||
span)
|
||||
self.one_bound_for_assoc_type(
|
||||
|| traits::transitive_bounds(tcx, predicates
|
||||
.iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref())),
|
||||
¶m_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,
|
||||
mut bounds: I,
|
||||
all_candidates: impl Fn() -> I,
|
||||
ty_param_name: &str,
|
||||
assoc_name: ast::Ident,
|
||||
span: Span)
|
||||
-> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
|
||||
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,
|
||||
None => {
|
||||
struct_span_err!(self.tcx().sess, span, E0220,
|
||||
"associated type `{}` not found for `{}`",
|
||||
assoc_name,
|
||||
ty_param_name)
|
||||
.span_label(span, format!("associated type `{}` not found", assoc_name))
|
||||
.emit();
|
||||
self.complain_about_assoc_type_not_found(
|
||||
all_candidates,
|
||||
ty_param_name,
|
||||
assoc_name,
|
||||
span
|
||||
);
|
||||
return Err(ErrorReported);
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
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!(
|
||||
self.tcx().sess, span, E0221,
|
||||
"ambiguous associated type `{}` in bounds of `{}`",
|
||||
|
@ -1606,6 +1601,50 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
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.
|
||||
// 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
|
||||
|
@ -1660,10 +1699,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
};
|
||||
|
||||
let candidates = traits::supertraits(tcx, ty::Binder::bind(trait_ref))
|
||||
.filter(|r| self.trait_defines_associated_type_named(r.def_id(), assoc_ident));
|
||||
|
||||
self.one_bound_for_assoc_type(candidates, "Self", assoc_ident, span)?
|
||||
self.one_bound_for_assoc_type(
|
||||
|| traits::supertraits(tcx, ty::Binder::bind(trait_ref)),
|
||||
"Self",
|
||||
assoc_ident,
|
||||
span
|
||||
)?
|
||||
}
|
||||
(&ty::Param(_), Res::SelfTy(Some(param_did), None)) |
|
||||
(&ty::Param(_), Res::Def(DefKind::TyParam, param_did)) => {
|
||||
|
|
|
@ -334,10 +334,70 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
err.emit();
|
||||
}
|
||||
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,
|
||||
"binary operation `{}` cannot be applied to type `{}`",
|
||||
op.node.as_str(),
|
||||
lhs_ty);
|
||||
"{}", message.as_str());
|
||||
|
||||
let mut involves_fn = false;
|
||||
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 op.node == hir::BinOpKind::Add &&
|
||||
self.check_str_addition(
|
||||
|
|
|
@ -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<()> {
|
||||
self.inner.flush()?;
|
||||
self.need_flush = false;
|
||||
|
@ -1015,7 +1077,7 @@ where
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
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::thread;
|
||||
|
||||
|
@ -1483,4 +1545,112 @@ mod tests {
|
|||
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::hash;
|
|||
use crate::io;
|
||||
use crate::iter;
|
||||
use crate::mem;
|
||||
use crate::net::{hton, ntoh, IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
use crate::net::{htons, ntohs, IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
use crate::option;
|
||||
use crate::slice;
|
||||
use crate::sys::net::netc as c;
|
||||
|
@ -276,7 +276,7 @@ impl SocketAddrV4 {
|
|||
SocketAddrV4 {
|
||||
inner: c::sockaddr_in {
|
||||
sin_family: c::AF_INET as c::sa_family_t,
|
||||
sin_port: hton(port),
|
||||
sin_port: htons(port),
|
||||
sin_addr: *ip.as_inner(),
|
||||
..unsafe { mem::zeroed() }
|
||||
},
|
||||
|
@ -326,7 +326,7 @@ impl SocketAddrV4 {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn port(&self) -> u16 {
|
||||
ntoh(self.inner.sin_port)
|
||||
ntohs(self.inner.sin_port)
|
||||
}
|
||||
|
||||
/// Changes the port number associated with this socket address.
|
||||
|
@ -342,7 +342,7 @@ impl SocketAddrV4 {
|
|||
/// ```
|
||||
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
|
||||
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 {
|
||||
inner: c::sockaddr_in6 {
|
||||
sin6_family: c::AF_INET6 as c::sa_family_t,
|
||||
sin6_port: hton(port),
|
||||
sin6_port: htons(port),
|
||||
sin6_addr: *ip.as_inner(),
|
||||
sin6_flowinfo: flowinfo,
|
||||
sin6_scope_id: scope_id,
|
||||
|
@ -420,7 +420,7 @@ impl SocketAddrV6 {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn port(&self) -> u16 {
|
||||
ntoh(self.inner.sin6_port)
|
||||
ntohs(self.inner.sin6_port)
|
||||
}
|
||||
|
||||
/// Changes the port number associated with this socket address.
|
||||
|
@ -436,7 +436,7 @@ impl SocketAddrV6 {
|
|||
/// ```
|
||||
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
|
||||
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.
|
||||
|
|
|
@ -85,21 +85,10 @@ pub enum Shutdown {
|
|||
Both,
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
trait NetInt {
|
||||
fn from_be(i: Self) -> Self;
|
||||
fn to_be(&self) -> Self;
|
||||
}
|
||||
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) }
|
||||
#[inline]
|
||||
const fn htons(i: u16) -> u16 { i.to_be() }
|
||||
#[inline]
|
||||
const fn ntohs(i: u16) -> u16 { u16::from_be(i) }
|
||||
|
||||
fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
|
||||
where F: FnMut(io::Result<&SocketAddr>) -> io::Result<T>
|
||||
|
|
|
@ -28,14 +28,6 @@ use libc::SOCK_CLOEXEC;
|
|||
#[cfg(not(target_os = "linux"))]
|
||||
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 fn init() {}
|
||||
|
@ -89,9 +81,12 @@ impl Socket {
|
|||
let fd = FileDesc::new(fd);
|
||||
fd.set_cloexec()?;
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ pub extern crate libc as netc;
|
|||
pub type wrlen_t = size_t;
|
||||
|
||||
const SOCK_CLOEXEC: c_int = 0;
|
||||
const SO_NOSIGPIPE: c_int = 0;
|
||||
|
||||
pub struct Socket(FileDesc);
|
||||
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
//! The AST pointer.
|
||||
//!
|
||||
//! Provides `P<T>`, a frozen owned smart pointer, as a replacement for `@T` in
|
||||
//! the AST.
|
||||
//! Provides `P<T>`, a frozen owned smart pointer.
|
||||
//!
|
||||
//! # Motivations and benefits
|
||||
//!
|
||||
//! * **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
|
||||
//! `ExprKind::AddrOf` node taking a mutable borrow). The only reason `@T` in the
|
||||
//! 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>`.
|
||||
//! `ExprKind::AddrOf` node taking a mutable borrow).
|
||||
//!
|
||||
//! * **Immutability**: `P<T>` disallows mutating its inner `T`, unlike `Box<T>`
|
||||
//! (unless it contains an `Unsafe` interior, but that may be denied later).
|
||||
|
|
|
@ -13,13 +13,13 @@ fn main() {
|
|||
let a: Clam = Clam{x: box 1, y: box 2};
|
||||
let b: Clam = Clam{x: box 10, y: box 20};
|
||||
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);
|
||||
assert_eq!(z, 21);
|
||||
let forty: Fish = Fish{a: box 40};
|
||||
let two: Fish = Fish{a: box 2};
|
||||
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);
|
||||
assert_eq!(answer, 42);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
||||
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>`
|
||||
|
||||
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
|
||||
|
|
||||
LL | let answer: isize = forty.a + two.a;
|
||||
|
|
|
@ -2,7 +2,7 @@ fn main() {
|
|||
let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
let vr = v.iter().filter(|x| {
|
||||
x % 2 == 0
|
||||
//~^ ERROR binary operation `%` cannot be applied to type `&&{integer}`
|
||||
//~^ ERROR cannot mod `&&{integer}` by `{integer}`
|
||||
});
|
||||
println!("{:?}", vr);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | x % 2 == 0
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | fn main() { let x = "a".to_string() ^ "b".to_string(); }
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | fn main() { let x = true * false; }
|
||||
|
|
|
@ -4,5 +4,5 @@ fn main() {
|
|||
let x = true;
|
||||
let y = 1;
|
||||
let z = x + y;
|
||||
//~^ ERROR binary operation `+` cannot be applied to type `bool`
|
||||
//~^ ERROR cannot add `{integer}` to `bool`
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | let z = x + y;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
pub fn main() {
|
||||
let x = () + (); //~ ERROR binary operation
|
||||
let x = () + (); //~ ERROR cannot add `()` to `()`
|
||||
|
||||
// this shouldn't have a flow-on error:
|
||||
for _ in x {}
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | let x = () + ();
|
||||
|
|
|
@ -4,5 +4,5 @@ fn main() {
|
|||
let x: Box<isize> = box 0;
|
||||
|
||||
println!("{}", x + 1);
|
||||
//~^ ERROR binary operation `+` cannot be applied to type `std::boxed::Box<isize>`
|
||||
//~^ ERROR cannot add `{integer}` to `std::boxed::Box<isize>`
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | println!("{}", x + 1);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
fn main() {
|
||||
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 ^
|
||||
];
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
|
|||
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
|
||||
|
|
||||
LL | ()+()
|
||||
|
|
|
@ -3,23 +3,23 @@ struct A;
|
|||
fn main() {
|
||||
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`
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | a + a;
|
||||
|
@ -8,7 +8,7 @@ LL | a + 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
|
||||
|
|
||||
LL | a - a;
|
||||
|
@ -18,7 +18,7 @@ LL | a - 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
|
||||
|
|
||||
LL | a * a;
|
||||
|
@ -28,7 +28,7 @@ LL | a * 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
|
||||
|
|
||||
LL | a / a;
|
||||
|
@ -38,7 +38,7 @@ LL | a / 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
|
||||
|
|
||||
LL | a % a;
|
||||
|
@ -48,7 +48,7 @@ LL | a % 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
|
||||
|
|
||||
LL | a & a;
|
||||
|
@ -58,7 +58,7 @@ LL | a & 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
|
||||
|
|
||||
LL | a | a;
|
||||
|
@ -68,7 +68,7 @@ LL | a | 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
|
||||
|
|
||||
LL | a << a;
|
||||
|
@ -78,7 +78,7 @@ LL | a << 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
|
||||
|
|
||||
LL | a >> a;
|
||||
|
|
|
@ -11,7 +11,7 @@ impl Add<i32> for i32 {}
|
|||
|
||||
fn main() {
|
||||
let x = 5 + 6;
|
||||
//~^ ERROR binary operation `+` cannot be applied to type `{integer}`
|
||||
//~^ ERROR cannot add `{integer}` to `{integer}`
|
||||
let y = 5i32 + 6i32;
|
||||
//~^ ERROR binary operation `+` cannot be applied to type `i32`
|
||||
//~^ ERROR cannot add `i32` to `i32`
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
||||
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}`
|
||||
|
||||
error[E0369]: binary operation `+` cannot be applied to type `i32`
|
||||
error[E0369]: cannot add `i32` to `i32`
|
||||
--> $DIR/issue-31076.rs:15:18
|
||||
|
|
||||
LL | let y = 5i32 + 6i32;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
fn func<'a, T>(a: &'a [T]) -> impl Iterator<Item=&'a T> {
|
||||
a.iter().map(|a| a*a)
|
||||
//~^ ERROR binary operation `*` cannot be applied to type `&T`
|
||||
//~^ ERROR cannot multiply `&T` to `&T`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | a.iter().map(|a| a*a)
|
||||
|
|
|
@ -11,5 +11,5 @@ impl Thing {
|
|||
fn main() {
|
||||
let u = Thing {x: 2};
|
||||
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`
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | let w = u * 3;
|
||||
|
|
|
@ -2,5 +2,5 @@ fn f(_: &[f32]) {}
|
|||
|
||||
fn main() {
|
||||
() + f(&[1.0]);
|
||||
//~^ ERROR binary operation `+` cannot be applied to type `()`
|
||||
//~^ ERROR cannot add `()` to `()`
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0369]: binary operation `+` cannot be applied to type `()`
|
||||
error[E0369]: cannot add `()` to `()`
|
||||
--> $DIR/issue-40610.rs:4:8
|
||||
|
|
||||
LL | () + f(&[1.0]);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
enum Foo {
|
||||
A = "" + 1
|
||||
//~^ ERROR binary operation `+` cannot be applied to type `&str`
|
||||
//~^ ERROR cannot add `{integer}` to `&str`
|
||||
}
|
||||
|
||||
enum Bar {
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | A = "" + 1
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | let _a = b + ", World!";
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!";
|
||||
|
|
|
@ -21,7 +21,7 @@ use E::*;
|
|||
|
||||
fn no_top_level_or_patterns() {
|
||||
// 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 | ())`.
|
||||
|
||||
// ...and for now neither do we allow or-patterns at the top level of functions.
|
||||
|
|
|
@ -104,7 +104,7 @@ LL | #![feature(or_patterns)]
|
|||
|
|
||||
= 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
|
||||
|
|
||||
LL | let _ = |A | B: E| ();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
enum Bar { T1((), Option<Vec<isize>>), T2, }
|
||||
|
||||
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() { }
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | fn foo(t: Bar) -> isize { match t { Bar::T1(_, Some(x)) => { return x * 3; } _ => { panic!(); } } }
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
pub fn main() {
|
||||
let x = "Hello " + "World!";
|
||||
//~^ ERROR cannot be applied to type
|
||||
//~^ ERROR cannot add
|
||||
|
||||
// Make sure that the span outputs a warning
|
||||
// for not having an implementation for std::ops::Add
|
||||
// that won't output for the above string concatenation
|
||||
let y = World::Hello + World::Goodbye;
|
||||
//~^ ERROR cannot be applied to type
|
||||
//~^ ERROR cannot add
|
||||
|
||||
let x = "Hello " + "World!".to_owned();
|
||||
//~^ ERROR cannot be applied to type
|
||||
//~^ ERROR cannot add
|
||||
}
|
||||
|
||||
enum World {
|
||||
|
@ -23,16 +23,16 @@ fn foo() {
|
|||
let c = "";
|
||||
let d = "";
|
||||
let e = &a;
|
||||
let _ = &a + &b; //~ ERROR binary operation
|
||||
let _ = &a + b; //~ ERROR binary operation
|
||||
let _ = &a + &b; //~ ERROR cannot add
|
||||
let _ = &a + b; //~ ERROR cannot add
|
||||
let _ = a + &b; // ok
|
||||
let _ = a + b; //~ ERROR mismatched types
|
||||
let _ = e + b; //~ ERROR binary operation
|
||||
let _ = e + &b; //~ ERROR binary operation
|
||||
let _ = e + d; //~ ERROR binary operation
|
||||
let _ = e + &d; //~ ERROR binary operation
|
||||
let _ = &c + &d; //~ ERROR binary operation
|
||||
let _ = &c + d; //~ ERROR binary operation
|
||||
let _ = c + &d; //~ ERROR binary operation
|
||||
let _ = c + d; //~ ERROR binary operation
|
||||
let _ = e + b; //~ ERROR cannot add
|
||||
let _ = e + &b; //~ ERROR cannot add
|
||||
let _ = e + d; //~ ERROR cannot add
|
||||
let _ = e + &d; //~ ERROR cannot add
|
||||
let _ = &c + &d; //~ ERROR cannot add
|
||||
let _ = &c + d; //~ ERROR cannot add
|
||||
let _ = c + &d; //~ ERROR cannot add
|
||||
let _ = c + d; //~ ERROR cannot add
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
||||
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!";
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0369]: binary operation `+` cannot be applied to type `World`
|
||||
error[E0369]: cannot add `World` to `World`
|
||||
--> $DIR/issue-39018.rs:8:26
|
||||
|
|
||||
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`
|
||||
|
||||
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
|
||||
|
|
||||
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();
|
||||
| ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
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
|
||||
|
|
||||
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;
|
||||
| ^
|
||||
|
||||
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
|
||||
|
|
||||
LL | let _ = &a + b;
|
||||
|
@ -73,7 +73,7 @@ LL | let _ = a + b;
|
|||
| expected `&str`, found struct `std::string::String`
|
||||
| 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
|
||||
|
|
||||
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;
|
||||
| ^^^^^^^^^^^^ ^^
|
||||
|
||||
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
|
||||
|
|
||||
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;
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
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
|
||||
|
|
||||
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;
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
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
|
||||
|
|
||||
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;
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error[E0369]: binary operation `+` cannot be applied to type `&&str`
|
||||
error[E0369]: cannot add `&&str` to `&&str`
|
||||
--> $DIR/issue-39018.rs:34:16
|
||||
|
|
||||
LL | let _ = &c + &d;
|
||||
|
@ -139,7 +139,7 @@ LL | let _ = &c + &d;
|
|||
|
|
||||
= 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
|
||||
|
|
||||
LL | let _ = &c + d;
|
||||
|
@ -149,7 +149,7 @@ LL | let _ = &c + d;
|
|||
|
|
||||
= 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
|
||||
|
|
||||
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;
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error[E0369]: binary operation `+` cannot be applied to type `&str`
|
||||
error[E0369]: cannot add `&str` to `&str`
|
||||
--> $DIR/issue-39018.rs:37:15
|
||||
|
|
||||
LL | let _ = c + d;
|
||||
|
|
|
@ -2,7 +2,7 @@ error[E0220]: associated type `Trget` not found for `std::ops::Deref`
|
|||
--> $DIR/type-binding.rs:6:20
|
||||
|
|
||||
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
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@ fn main() {
|
|||
let a: &String = &"1".to_owned();
|
||||
let b: &str = &"2";
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | let c = a + b;
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
fn main() {
|
||||
let unicode_is_fun = "‱ஹ௸௵꧄.ဪ꧅⸻𒈙𒐫﷽𒌄𒈟𒍼𒁎𒀱𒌧𒅃 𒈓𒍙𒊎𒄡𒅌𒁏𒀰𒐪𒐩𒈙𒐫𪚥";
|
||||
let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!";
|
||||
//~^ ERROR binary operation `+` cannot be applied to type `&str`
|
||||
//~^ ERROR cannot add `&str` to `&str`
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | ...ཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྾྿࿀࿁࿂࿃࿄࿅࿆࿇...࿋࿌࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!";
|
||||
|
|
|
@ -5,7 +5,7 @@ trait MyMul<Rhs, Res> {
|
|||
}
|
||||
|
||||
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() {}
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | a * b
|
||||
|
|
|
@ -2,7 +2,7 @@ fn main() {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | let z = x + y;
|
||||
|
|
|
@ -14,6 +14,6 @@ fn main() {
|
|||
let i = vec![r(0)];
|
||||
let j = vec![r(1)];
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
||||
LL | let k = i + j;
|
||||
|
|
Loading…
Reference in New Issue