Skip to content

Commit 0de96d3

Browse files
committed
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
2 parents c605199 + 06985c6 commit 0de96d3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+435
-217
lines changed

src/bootstrap/configure.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@ def v(*args):
5959
o("lld", "rust.lld", "build lld")
6060
o("lldb", "rust.lldb", "build lldb")
6161
o("missing-tools", "dist.missing-tools", "allow failures when building tools")
62-
o("use-libcxx", "llvm.use_libcxx", "build LLVM with libc++")
62+
o("use-libcxx", "llvm.use-libcxx", "build LLVM with libc++")
6363

6464
o("cflags", "llvm.cflags", "build LLVM with these extra compiler flags")
6565
o("cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler flags")
6666
o("ldflags", "llvm.ldflags", "build LLVM with these extra linker flags")
6767

68-
o("llvm-libunwind", "rust.llvm_libunwind", "use LLVM libunwind")
68+
o("llvm-libunwind", "rust.llvm-libunwind", "use LLVM libunwind")
6969

7070
# Optimization and debugging options. These may be overridden by the release
7171
# channel, etc.

src/librustc/ich/mod.rs

+7-15
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,13 @@ mod impls_hir;
1212
mod impls_ty;
1313
mod impls_syntax;
1414

15-
pub const ATTR_DIRTY: Symbol = sym::rustc_dirty;
16-
pub const ATTR_CLEAN: Symbol = sym::rustc_clean;
17-
pub const ATTR_IF_THIS_CHANGED: Symbol = sym::rustc_if_this_changed;
18-
pub const ATTR_THEN_THIS_WOULD_NEED: Symbol = sym::rustc_then_this_would_need;
19-
pub const ATTR_PARTITION_REUSED: Symbol = sym::rustc_partition_reused;
20-
pub const ATTR_PARTITION_CODEGENED: Symbol = sym::rustc_partition_codegened;
21-
pub const ATTR_EXPECTED_CGU_REUSE: Symbol = sym::rustc_expected_cgu_reuse;
22-
2315
pub const IGNORED_ATTRIBUTES: &[Symbol] = &[
2416
sym::cfg,
25-
ATTR_IF_THIS_CHANGED,
26-
ATTR_THEN_THIS_WOULD_NEED,
27-
ATTR_DIRTY,
28-
ATTR_CLEAN,
29-
ATTR_PARTITION_REUSED,
30-
ATTR_PARTITION_CODEGENED,
31-
ATTR_EXPECTED_CGU_REUSE,
17+
sym::rustc_if_this_changed,
18+
sym::rustc_then_this_would_need,
19+
sym::rustc_dirty,
20+
sym::rustc_clean,
21+
sym::rustc_partition_reused,
22+
sym::rustc_partition_codegened,
23+
sym::rustc_expected_cgu_reuse,
3224
];

src/librustc_incremental/assert_dep_graph.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,10 @@ use rustc_data_structures::graph::implementation::{
4444
};
4545
use rustc::hir;
4646
use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
47-
use rustc::ich::{ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED};
4847
use std::env;
4948
use std::fs::{self, File};
5049
use std::io::Write;
51-
use syntax::ast;
50+
use syntax::{ast, symbol::sym};
5251
use syntax_pos::Span;
5352

5453
pub fn assert_dep_graph(tcx: TyCtxt<'_>) {
@@ -78,7 +77,7 @@ pub fn assert_dep_graph(tcx: TyCtxt<'_>) {
7877
assert!(tcx.sess.opts.debugging_opts.query_dep_graph,
7978
"cannot use the `#[{}]` or `#[{}]` annotations \
8079
without supplying `-Z query-dep-graph`",
81-
ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED);
80+
sym::rustc_if_this_changed, sym::rustc_then_this_would_need);
8281
}
8382

8483
// Check paths.
@@ -114,7 +113,7 @@ impl IfThisChanged<'tcx> {
114113
let def_id = self.tcx.hir().local_def_id(hir_id);
115114
let def_path_hash = self.tcx.def_path_hash(def_id);
116115
for attr in attrs {
117-
if attr.check_name(ATTR_IF_THIS_CHANGED) {
116+
if attr.check_name(sym::rustc_if_this_changed) {
118117
let dep_node_interned = self.argument(attr);
119118
let dep_node = match dep_node_interned {
120119
None => def_path_hash.to_dep_node(DepKind::Hir),
@@ -130,7 +129,7 @@ impl IfThisChanged<'tcx> {
130129
}
131130
};
132131
self.if_this_changed.push((attr.span, def_id, dep_node));
133-
} else if attr.check_name(ATTR_THEN_THIS_WOULD_NEED) {
132+
} else if attr.check_name(sym::rustc_then_this_would_need) {
134133
let dep_node_interned = self.argument(attr);
135134
let dep_node = match dep_node_interned {
136135
Some(n) => {

src/librustc_incremental/assert_module_sources.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ use rustc::ty::TyCtxt;
2828
use std::collections::BTreeSet;
2929
use syntax::ast;
3030
use syntax::symbol::{Symbol, sym};
31-
use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED,
32-
ATTR_EXPECTED_CGU_REUSE};
3331

3432
pub fn assert_module_sources(tcx: TyCtxt<'_>) {
3533
tcx.dep_graph.with_ignore(|| {
@@ -62,11 +60,11 @@ struct AssertModuleSource<'tcx> {
6260

6361
impl AssertModuleSource<'tcx> {
6462
fn check_attr(&self, attr: &ast::Attribute) {
65-
let (expected_reuse, comp_kind) = if attr.check_name(ATTR_PARTITION_REUSED) {
63+
let (expected_reuse, comp_kind) = if attr.check_name(sym::rustc_partition_reused) {
6664
(CguReuse::PreLto, ComparisonKind::AtLeast)
67-
} else if attr.check_name(ATTR_PARTITION_CODEGENED) {
65+
} else if attr.check_name(sym::rustc_partition_codegened) {
6866
(CguReuse::No, ComparisonKind::Exact)
69-
} else if attr.check_name(ATTR_EXPECTED_CGU_REUSE) {
67+
} else if attr.check_name(sym::rustc_expected_cgu_reuse) {
7068
match &*self.field(attr, sym::kind).as_str() {
7169
"no" => (CguReuse::No, ComparisonKind::Exact),
7270
"pre-lto" => (CguReuse::PreLto, ComparisonKind::Exact),

src/librustc_incremental/persist/dirty_clean.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ use rustc::hir::Node as HirNode;
2222
use rustc::hir::def_id::DefId;
2323
use rustc::hir::itemlikevisit::ItemLikeVisitor;
2424
use rustc::hir::intravisit;
25-
use rustc::ich::{ATTR_DIRTY, ATTR_CLEAN};
2625
use rustc::ty::TyCtxt;
2726
use rustc_data_structures::fingerprint::Fingerprint;
2827
use rustc_data_structures::fx::FxHashSet;
@@ -224,7 +223,7 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
224223

225224
let mut all_attrs = FindAllAttrs {
226225
tcx,
227-
attr_names: vec![ATTR_DIRTY, ATTR_CLEAN],
226+
attr_names: vec![sym::rustc_dirty, sym::rustc_clean],
228227
found_attrs: vec![],
229228
};
230229
intravisit::walk_crate(&mut all_attrs, krate);
@@ -246,9 +245,9 @@ impl DirtyCleanVisitor<'tcx> {
246245
fn assertion_maybe(&mut self, item_id: hir::HirId, attr: &Attribute)
247246
-> Option<Assertion>
248247
{
249-
let is_clean = if attr.check_name(ATTR_DIRTY) {
248+
let is_clean = if attr.check_name(sym::rustc_dirty) {
250249
false
251-
} else if attr.check_name(ATTR_CLEAN) {
250+
} else if attr.check_name(sym::rustc_clean) {
252251
true
253252
} else {
254253
// skip: not rustc_clean/dirty

src/librustc_typeck/astconv.rs

+72-31
Original file line numberDiff line numberDiff line change
@@ -1145,11 +1145,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
11451145
} else {
11461146
// Otherwise, we have to walk through the supertraits to find
11471147
// those that do.
1148-
let candidates = traits::supertraits(tcx, trait_ref).filter(|r| {
1149-
self.trait_defines_associated_type_named(r.def_id(), binding.item_name)
1150-
});
11511148
self.one_bound_for_assoc_type(
1152-
candidates,
1149+
|| traits::supertraits(tcx, trait_ref),
11531150
&trait_ref.print_only_trait_path().to_string(),
11541151
binding.item_name,
11551152
binding.span
@@ -1531,50 +1528,48 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
15311528

15321529
debug!("find_bound_for_assoc_item: predicates={:#?}", predicates);
15331530

1534-
let bounds = predicates.iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref());
1535-
1536-
// Check that there is exactly one way to find an associated type with the
1537-
// correct name.
1538-
let suitable_bounds = traits::transitive_bounds(tcx, bounds)
1539-
.filter(|b| self.trait_defines_associated_type_named(b.def_id(), assoc_name));
1540-
15411531
let param_hir_id = tcx.hir().as_local_hir_id(ty_param_def_id).unwrap();
15421532
let param_name = tcx.hir().ty_param_name(param_hir_id);
1543-
self.one_bound_for_assoc_type(suitable_bounds,
1544-
&param_name.as_str(),
1545-
assoc_name,
1546-
span)
1533+
self.one_bound_for_assoc_type(
1534+
|| traits::transitive_bounds(tcx, predicates
1535+
.iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref())),
1536+
&param_name.as_str(),
1537+
assoc_name,
1538+
span,
1539+
)
15471540
}
15481541

1549-
// Checks that `bounds` contains exactly one element and reports appropriate
1550-
// errors otherwise.
15511542
fn one_bound_for_assoc_type<I>(&self,
1552-
mut bounds: I,
1543+
all_candidates: impl Fn() -> I,
15531544
ty_param_name: &str,
15541545
assoc_name: ast::Ident,
15551546
span: Span)
15561547
-> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
15571548
where I: Iterator<Item = ty::PolyTraitRef<'tcx>>
15581549
{
1559-
let bound = match bounds.next() {
1550+
let mut matching_candidates = all_candidates().filter(|r| {
1551+
self.trait_defines_associated_type_named(r.def_id(), assoc_name)
1552+
});
1553+
1554+
let bound = match matching_candidates.next() {
15601555
Some(bound) => bound,
15611556
None => {
1562-
struct_span_err!(self.tcx().sess, span, E0220,
1563-
"associated type `{}` not found for `{}`",
1564-
assoc_name,
1565-
ty_param_name)
1566-
.span_label(span, format!("associated type `{}` not found", assoc_name))
1567-
.emit();
1557+
self.complain_about_assoc_type_not_found(
1558+
all_candidates,
1559+
ty_param_name,
1560+
assoc_name,
1561+
span
1562+
);
15681563
return Err(ErrorReported);
15691564
}
15701565
};
15711566

15721567
debug!("one_bound_for_assoc_type: bound = {:?}", bound);
15731568

1574-
if let Some(bound2) = bounds.next() {
1569+
if let Some(bound2) = matching_candidates.next() {
15751570
debug!("one_bound_for_assoc_type: bound2 = {:?}", bound2);
15761571

1577-
let bounds = iter::once(bound).chain(iter::once(bound2)).chain(bounds);
1572+
let bounds = iter::once(bound).chain(iter::once(bound2)).chain(matching_candidates);
15781573
let mut err = struct_span_err!(
15791574
self.tcx().sess, span, E0221,
15801575
"ambiguous associated type `{}` in bounds of `{}`",
@@ -1606,6 +1601,50 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16061601
return Ok(bound);
16071602
}
16081603

1604+
fn complain_about_assoc_type_not_found<I>(&self,
1605+
all_candidates: impl Fn() -> I,
1606+
ty_param_name: &str,
1607+
assoc_name: ast::Ident,
1608+
span: Span)
1609+
where I: Iterator<Item = ty::PolyTraitRef<'tcx>> {
1610+
let mut err = struct_span_err!(self.tcx().sess, span, E0220,
1611+
"associated type `{}` not found for `{}`",
1612+
assoc_name,
1613+
ty_param_name);
1614+
1615+
let all_candidate_names: Vec<_> = all_candidates()
1616+
.map(|r| self.tcx().associated_items(r.def_id()))
1617+
.flatten()
1618+
.filter_map(|item|
1619+
if item.kind == ty::AssocKind::Type {
1620+
Some(item.ident.name)
1621+
} else {
1622+
None
1623+
}
1624+
)
1625+
.collect();
1626+
1627+
if let Some(suggested_name) = find_best_match_for_name(
1628+
all_candidate_names.iter(),
1629+
&assoc_name.as_str(),
1630+
None,
1631+
) {
1632+
err.span_suggestion(
1633+
span,
1634+
"there is an associated type with a similar name",
1635+
suggested_name.to_string(),
1636+
Applicability::MaybeIncorrect,
1637+
);
1638+
} else {
1639+
err.span_label(
1640+
span,
1641+
format!("associated type `{}` not found", assoc_name)
1642+
);
1643+
}
1644+
1645+
err.emit();
1646+
}
1647+
16091648
// Create a type from a path to an associated type.
16101649
// For a path `A::B::C::D`, `qself_ty` and `qself_def` are the type and def for `A::B::C`
16111650
// 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 {
16601699
}
16611700
};
16621701

1663-
let candidates = traits::supertraits(tcx, ty::Binder::bind(trait_ref))
1664-
.filter(|r| self.trait_defines_associated_type_named(r.def_id(), assoc_ident));
1665-
1666-
self.one_bound_for_assoc_type(candidates, "Self", assoc_ident, span)?
1702+
self.one_bound_for_assoc_type(
1703+
|| traits::supertraits(tcx, ty::Binder::bind(trait_ref)),
1704+
"Self",
1705+
assoc_ident,
1706+
span
1707+
)?
16671708
}
16681709
(&ty::Param(_), Res::SelfTy(Some(param_did), None)) |
16691710
(&ty::Param(_), Res::Def(DefKind::TyParam, param_did)) => {

src/librustc_typeck/check/op.rs

+63-22
Original file line numberDiff line numberDiff line change
@@ -334,10 +334,70 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
334334
err.emit();
335335
}
336336
IsAssign::No => {
337+
let (message, missing_trait) = match op.node {
338+
hir::BinOpKind::Add => {
339+
(format!("cannot add `{}` to `{}`", rhs_ty, lhs_ty),
340+
Some("std::ops::Add"))
341+
},
342+
hir::BinOpKind::Sub => {
343+
(format!("cannot substract `{}` from `{}`", rhs_ty, lhs_ty),
344+
Some("std::ops::Sub"))
345+
},
346+
hir::BinOpKind::Mul => {
347+
(format!("cannot multiply `{}` to `{}`", rhs_ty, lhs_ty),
348+
Some("std::ops::Mul"))
349+
},
350+
hir::BinOpKind::Div => {
351+
(format!("cannot divide `{}` by `{}`", lhs_ty, rhs_ty),
352+
Some("std::ops::Div"))
353+
},
354+
hir::BinOpKind::Rem => {
355+
(format!("cannot mod `{}` by `{}`", lhs_ty, rhs_ty),
356+
Some("std::ops::Rem"))
357+
},
358+
hir::BinOpKind::BitAnd => {
359+
(format!("no implementation for `{} & {}`", lhs_ty, rhs_ty),
360+
Some("std::ops::BitAnd"))
361+
},
362+
hir::BinOpKind::BitXor => {
363+
(format!("no implementation for `{} ^ {}`", lhs_ty, rhs_ty),
364+
Some("std::ops::BitXor"))
365+
},
366+
hir::BinOpKind::BitOr => {
367+
(format!("no implementation for `{} | {}`", lhs_ty, rhs_ty),
368+
Some("std::ops::BitOr"))
369+
},
370+
hir::BinOpKind::Shl => {
371+
(format!("no implementation for `{} << {}`", lhs_ty, rhs_ty),
372+
Some("std::ops::Shl"))
373+
},
374+
hir::BinOpKind::Shr => {
375+
(format!("no implementation for `{} >> {}`", lhs_ty, rhs_ty),
376+
Some("std::ops::Shr"))
377+
},
378+
hir::BinOpKind::Eq |
379+
hir::BinOpKind::Ne => {
380+
(format!(
381+
"binary operation `{}` cannot be applied to type `{}`",
382+
op.node.as_str(), lhs_ty),
383+
Some("std::cmp::PartialEq"))
384+
},
385+
hir::BinOpKind::Lt |
386+
hir::BinOpKind::Le |
387+
hir::BinOpKind::Gt |
388+
hir::BinOpKind::Ge => {
389+
(format!(
390+
"binary operation `{}` cannot be applied to type `{}`",
391+
op.node.as_str(), lhs_ty),
392+
Some("std::cmp::PartialOrd"))
393+
}
394+
_ => (format!(
395+
"binary operation `{}` cannot be applied to type `{}`",
396+
op.node.as_str(), lhs_ty),
397+
None)
398+
};
337399
let mut err = struct_span_err!(self.tcx.sess, op.span, E0369,
338-
"binary operation `{}` cannot be applied to type `{}`",
339-
op.node.as_str(),
340-
lhs_ty);
400+
"{}", message.as_str());
341401

342402
let mut involves_fn = false;
343403
if !lhs_expr.span.eq(&rhs_expr.span) {
@@ -382,25 +442,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
382442
}
383443
}
384444
}
385-
let missing_trait = match op.node {
386-
hir::BinOpKind::Add => Some("std::ops::Add"),
387-
hir::BinOpKind::Sub => Some("std::ops::Sub"),
388-
hir::BinOpKind::Mul => Some("std::ops::Mul"),
389-
hir::BinOpKind::Div => Some("std::ops::Div"),
390-
hir::BinOpKind::Rem => Some("std::ops::Rem"),
391-
hir::BinOpKind::BitAnd => Some("std::ops::BitAnd"),
392-
hir::BinOpKind::BitXor => Some("std::ops::BitXor"),
393-
hir::BinOpKind::BitOr => Some("std::ops::BitOr"),
394-
hir::BinOpKind::Shl => Some("std::ops::Shl"),
395-
hir::BinOpKind::Shr => Some("std::ops::Shr"),
396-
hir::BinOpKind::Eq |
397-
hir::BinOpKind::Ne => Some("std::cmp::PartialEq"),
398-
hir::BinOpKind::Lt |
399-
hir::BinOpKind::Le |
400-
hir::BinOpKind::Gt |
401-
hir::BinOpKind::Ge => Some("std::cmp::PartialOrd"),
402-
_ => None
403-
};
404445
if let Some(missing_trait) = missing_trait {
405446
if op.node == hir::BinOpKind::Add &&
406447
self.check_str_addition(

0 commit comments

Comments
 (0)