Skip to content

Rollup of 9 pull requests #96063

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 21 commits into from
Closed
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5e76103
Reject `#[thread_local]` attribute on non-static items
tmiasko Mar 16, 2022
8c2353b
remove find_use_placement
kckeiks Mar 18, 2022
abf2b4c
Stabilize `derive_default_enum`
jhpratt Feb 28, 2022
a3dd654
Add documentation
jhpratt Mar 8, 2022
d5f3863
Consider lifetimes when comparing types for equality in MIR validator
JakobDegen Apr 13, 2022
4a0f8d5
improve diagnostics for unterminated nested block comment
yue4u Apr 13, 2022
849ede1
Update books
ehuss Apr 14, 2022
f6d9577
docs: add link from zip to unzip
beyarkay Apr 14, 2022
d73e328
Remove trailing whitespace
beyarkay Apr 14, 2022
7a35c0f
Use u32 instead of i32 for futexes.
m-ou-se Apr 14, 2022
1b7008d
refactor: change to use peekable
yue4u Apr 14, 2022
48029ab
Remove some now-dead code that was only relevant before deaggregation.
oli-obk Apr 14, 2022
5ab0306
Rollup merge of #94457 - jhpratt:stabilize-derive_default_enum, r=dav…
Dylan-DPC Apr 15, 2022
c149fec
Rollup merge of #95006 - tmiasko:thread-local-static, r=wesleywiser
Dylan-DPC Apr 15, 2022
5f525be
Rollup merge of #95194 - kckeiks:update-algo-in-find-use-placement, r…
Dylan-DPC Apr 15, 2022
d1b8125
Rollup merge of #95859 - rainy-me:unterminated-nested-block-comment, …
Dylan-DPC Apr 15, 2022
89dd3bf
Rollup merge of #96004 - JakobDegen:fix-validator-ice, r=petrochenkov
Dylan-DPC Apr 15, 2022
4ee5130
Rollup merge of #96032 - ehuss:update-books, r=ehuss
Dylan-DPC Apr 15, 2022
d5232f8
Rollup merge of #96038 - beyarkay:patch-1, r=m-ou-se
Dylan-DPC Apr 15, 2022
61a4193
Rollup merge of #96040 - m-ou-se:futex-u32, r=Amanieu
Dylan-DPC Apr 15, 2022
a024036
Rollup merge of #96050 - oli-obk:deaggregator_cleanup, r=RalfJung
Dylan-DPC Apr 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion compiler/rustc_ast_lowering/src/index.rs
Original file line number Diff line number Diff line change
@@ -52,7 +52,9 @@ pub(super) fn index_hir<'hir>(
};

match item {
OwnerNode::Crate(citem) => collector.visit_mod(&citem, citem.inner, hir::CRATE_HIR_ID),
OwnerNode::Crate(citem) => {
collector.visit_mod(&citem, citem.spans.inner_span, hir::CRATE_HIR_ID)
}
OwnerNode::Item(item) => collector.visit_item(item),
OwnerNode::TraitItem(item) => collector.visit_trait_item(item),
OwnerNode::ImplItem(item) => collector.visit_impl_item(item),
13 changes: 8 additions & 5 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
@@ -124,7 +124,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
debug_assert_eq!(self.resolver.local_def_id(CRATE_NODE_ID), CRATE_DEF_ID);

self.with_lctx(CRATE_NODE_ID, |lctx| {
let module = lctx.lower_mod(&c.items, c.spans.inner_span);
let module = lctx.lower_mod(&c.items, &c.spans);
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs);
hir::OwnerNode::Crate(lctx.arena.alloc(module))
})
@@ -186,9 +186,12 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
}

impl<'hir> LoweringContext<'_, 'hir> {
pub(super) fn lower_mod(&mut self, items: &[P<Item>], inner: Span) -> hir::Mod<'hir> {
pub(super) fn lower_mod(&mut self, items: &[P<Item>], spans: &ModSpans) -> hir::Mod<'hir> {
hir::Mod {
inner: self.lower_span(inner),
spans: hir::ModSpans {
inner_span: self.lower_span(spans.inner_span),
inject_use_span: self.lower_span(spans.inject_use_span),
},
item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_ref(x))),
}
}
@@ -308,8 +311,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
})
}
ItemKind::Mod(_, ref mod_kind) => match mod_kind {
ModKind::Loaded(items, _, ModSpans { inner_span, inject_use_span: _ }) => {
hir::ItemKind::Mod(self.lower_mod(items, *inner_span))
ModKind::Loaded(items, _, spans) => {
hir::ItemKind::Mod(self.lower_mod(items, spans))
}
ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
},
13 changes: 1 addition & 12 deletions compiler/rustc_builtin_macros/src/deriving/default.rs
Original file line number Diff line number Diff line change
@@ -46,18 +46,7 @@ pub fn expand_deriving_default(
StaticStruct(_, fields) => {
default_struct_substructure(cx, trait_span, substr, fields)
}
StaticEnum(enum_def, _) => {
if !cx.sess.features_untracked().derive_default_enum {
rustc_session::parse::feature_err(
cx.parse_sess(),
sym::derive_default_enum,
span,
"deriving `Default` on enums is experimental",
)
.emit();
}
default_enum_substructure(cx, trait_span, enum_def)
}
StaticEnum(enum_def, _) => default_enum_substructure(cx, trait_span, enum_def),
_ => cx.span_bug(trait_span, "method in `derive(Default)`"),
}
})),
22 changes: 3 additions & 19 deletions compiler/rustc_const_eval/src/interpret/step.rs
Original file line number Diff line number Diff line change
@@ -196,27 +196,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.write_immediate(*val, &dest)?;
}

Aggregate(ref kind, ref operands) => {
// active_field_index is for union initialization.
let (dest, active_field_index) = match **kind {
mir::AggregateKind::Adt(adt_did, variant_index, _, _, active_field_index) => {
self.write_discriminant(variant_index, &dest)?;
if self.tcx.adt_def(adt_did).is_enum() {
assert!(active_field_index.is_none());
(self.place_downcast(&dest, variant_index)?, None)
} else {
if active_field_index.is_some() {
assert_eq!(operands.len(), 1);
}
(dest, active_field_index)
}
}
_ => (dest, None),
};
Aggregate(box ref kind, ref operands) => {
assert!(matches!(kind, mir::AggregateKind::Array(..)));

for (i, operand) in operands.iter().enumerate() {
for (field_index, operand) in operands.iter().enumerate() {
let op = self.eval_operand(operand, None)?;
let field_index = active_field_index.unwrap_or(i);
let field_dest = self.place_field(&dest, field_index)?;
self.copy_op(&op, &field_dest)?;
}
7 changes: 3 additions & 4 deletions compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
@@ -315,9 +315,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
| ty::FnPtr(..)
)
}
// None of the possible types have lifetimes, so we can just compare
// directly
if a != b {
// The function pointer types can have lifetimes
if !self.mir_assign_valid_types(a, b) {
self.fail(
location,
format!("Cannot compare unequal types {:?} and {:?}", a, b),
@@ -464,7 +463,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
};
// since CopyNonOverlapping is parametrized by 1 type,
// we only need to check that they are equal and not keep an extra parameter.
if op_src_ty != op_dst_ty {
if !self.mir_assign_valid_types(op_src_ty, op_dst_ty) {
self.fail(location, format!("bad arg ({:?} != {:?})", op_src_ty, op_dst_ty));
}

2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
@@ -126,6 +126,8 @@ declare_features! (
(accepted, default_type_params, "1.0.0", None, None),
/// Allows `#[deprecated]` attribute.
(accepted, deprecated, "1.9.0", Some(29935), None),
/// Allows `#[derive(Default)]` and `#[default]` on enums.
(accepted, derive_default_enum, "1.62.0", Some(86985), None),
/// Allows the use of destructuring assignments.
(accepted, destructuring_assignment, "1.59.0", Some(71126), None),
/// Allows `#[doc(alias = "...")]`.
2 changes: 0 additions & 2 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
@@ -368,8 +368,6 @@ declare_features! (
(active, deprecated_safe, "1.61.0", Some(94978), None),
/// Allows having using `suggestion` in the `#[deprecated]` attribute.
(active, deprecated_suggestion, "1.61.0", Some(94785), None),
/// Allows `#[derive(Default)]` and `#[default]` on enums.
(active, derive_default_enum, "1.56.0", Some(86985), None),
/// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
(active, doc_auto_cfg, "1.58.0", Some(43781), None),
/// Allows `#[doc(cfg(...))]`.
2 changes: 1 addition & 1 deletion compiler/rustc_feature/src/lib.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@
//! even if it is stabilized or removed, *do not remove it*. Instead, move the
//! symbol to the `accepted` or `removed` modules respectively.
#![feature(derive_default_enum)]
#![cfg_attr(bootstrap, feature(derive_default_enum))]
#![feature(once_cell)]

mod accepted;
14 changes: 10 additions & 4 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
@@ -2557,11 +2557,17 @@ impl FnRetTy<'_> {

#[derive(Encodable, Debug, HashStable_Generic)]
pub struct Mod<'hir> {
pub spans: ModSpans,
pub item_ids: &'hir [ItemId],
}

#[derive(Copy, Clone, Debug, HashStable_Generic, Encodable)]
pub struct ModSpans {
/// A span from the first token past `{` to the last token until `}`.
/// For `mod foo;`, the inner span ranges from the first token
/// to the last token in the external file.
pub inner: Span,
pub item_ids: &'hir [ItemId],
pub inner_span: Span,
pub inject_use_span: Span,
}

#[derive(Debug, HashStable_Generic)]
@@ -3059,8 +3065,8 @@ impl<'hir> OwnerNode<'hir> {
OwnerNode::Item(Item { span, .. })
| OwnerNode::ForeignItem(ForeignItem { span, .. })
| OwnerNode::ImplItem(ImplItem { span, .. })
| OwnerNode::TraitItem(TraitItem { span, .. })
| OwnerNode::Crate(Mod { inner: span, .. }) => *span,
| OwnerNode::TraitItem(TraitItem { span, .. }) => *span,
OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => *inner_span,
}
}

2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@
#![feature(bool_to_option)]
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(derive_default_enum)]
#![cfg_attr(bootstrap, feature(derive_default_enum))]
#![feature(extend_one)]
#![feature(label_break_value)]
#![feature(let_chains)]
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
@@ -584,7 +584,7 @@ impl<'hir> Map<'hir> {
Some(OwnerNode::Item(&Item { span, kind: ItemKind::Mod(ref m), .. })) => {
(m, span, hir_id)
}
Some(OwnerNode::Crate(item)) => (item, item.inner, hir_id),
Some(OwnerNode::Crate(item)) => (item, item.spans.inner_span, hir_id),
node => panic!("not a module: {:?}", node),
}
}
@@ -1012,7 +1012,7 @@ impl<'hir> Map<'hir> {
Node::Infer(i) => i.span,
Node::Visibility(v) => bug!("unexpected Visibility {:?}", v),
Node::Local(local) => local.span,
Node::Crate(item) => item.inner,
Node::Crate(item) => item.spans.inner_span,
};
Some(span)
}
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/lib.rs
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@
#![feature(bool_to_option)]
#![feature(box_patterns)]
#![feature(core_intrinsics)]
#![feature(derive_default_enum)]
#![cfg_attr(bootstrap, feature(derive_default_enum))]
#![feature(discriminant_kind)]
#![feature(exhaustive_patterns)]
#![feature(get_mut_unchecked)]
3 changes: 2 additions & 1 deletion compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
@@ -2518,7 +2518,8 @@ pub enum Rvalue<'tcx> {
/// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second
/// parameter may be a `usize` as well.
/// * The comparison operations accept `bool`s, `char`s, signed or unsigned integers, floats,
/// raw pointers, or function pointers of matching types and return a `bool`.
/// raw pointers, or function pointers and return a `bool`. The types of the operands must be
/// matching, up to the usual caveat of the lifetimes in function pointers.
/// * Left and right shift operations accept signed or unsigned integers not necessarily of the
/// same type and return a value of the same type as their LHS. Like in Rust, the RHS is
/// truncated as needed.
60 changes: 50 additions & 10 deletions compiler/rustc_parse/src/lexer/mod.rs
Original file line number Diff line number Diff line change
@@ -182,16 +182,7 @@ impl<'a> StringReader<'a> {
}
rustc_lexer::TokenKind::BlockComment { doc_style, terminated } => {
if !terminated {
let msg = match doc_style {
Some(_) => "unterminated block doc-comment",
None => "unterminated block comment",
};
let last_bpos = self.pos;
self.sess.span_diagnostic.span_fatal_with_code(
self.mk_sp(start, last_bpos),
msg,
error_code!(E0758),
);
self.report_unterminated_block_comment(start, doc_style);
}

// Skip non-doc comments
@@ -553,6 +544,55 @@ impl<'a> StringReader<'a> {
err.emit()
}

fn report_unterminated_block_comment(&self, start: BytePos, doc_style: Option<DocStyle>) {
let msg = match doc_style {
Some(_) => "unterminated block doc-comment",
None => "unterminated block comment",
};
let last_bpos = self.pos;
let mut err = self.sess.span_diagnostic.struct_span_fatal_with_code(
self.mk_sp(start, last_bpos),
msg,
error_code!(E0758),
);
let mut nested_block_comment_open_idxs = vec![];
let mut last_nested_block_comment_idxs = None;
let mut content_chars = self.str_from(start).char_indices().peekable();

while let Some((idx, current_char)) = content_chars.next() {
match content_chars.peek() {
Some((_, '*')) if current_char == '/' => {
nested_block_comment_open_idxs.push(idx);
}
Some((_, '/')) if current_char == '*' => {
last_nested_block_comment_idxs =
nested_block_comment_open_idxs.pop().map(|open_idx| (open_idx, idx));
}
_ => {}
};
}

if let Some((nested_open_idx, nested_close_idx)) = last_nested_block_comment_idxs {
err.span_label(self.mk_sp(start, start + BytePos(2)), msg)
.span_label(
self.mk_sp(
start + BytePos(nested_open_idx as u32),
start + BytePos(nested_open_idx as u32 + 2),
),
"...as last nested comment starts here, maybe you want to close this instead?",
)
.span_label(
self.mk_sp(
start + BytePos(nested_close_idx as u32),
start + BytePos(nested_close_idx as u32 + 2),
),
"...and last nested comment terminates here.",
);
}

err.emit();
}

// RFC 3101 introduced the idea of (reserved) prefixes. As of Rust 2021,
// using a (unknown) prefix is an error. In earlier editions, however, they
// only result in a (allowed by default) lint, and are treated as regular
16 changes: 16 additions & 0 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
@@ -80,6 +80,7 @@ impl CheckAttrVisitor<'_> {
self.check_rustc_must_implement_one_of(attr, span, target)
}
sym::target_feature => self.check_target_feature(hir_id, attr, span, target),
sym::thread_local => self.check_thread_local(attr, span, target),
sym::track_caller => {
self.check_track_caller(hir_id, attr.span, attrs, span, target)
}
@@ -523,6 +524,21 @@ impl CheckAttrVisitor<'_> {
}
}

/// Checks if the `#[thread_local]` attribute on `item` is valid. Returns `true` if valid.
fn check_thread_local(&self, attr: &Attribute, span: Span, target: Target) -> bool {
match target {
Target::ForeignStatic | Target::Static => true,
_ => {
self.tcx
.sess
.struct_span_err(attr.span, "attribute should be applied to a static")
.span_label(span, "not a static")
.emit();
false
}
}
}

fn doc_attr_str_error(&self, meta: &NestedMetaItem, attr_name: &str) {
self.tcx
.sess
4 changes: 2 additions & 2 deletions compiler/rustc_save_analysis/src/dump_visitor.rs
Original file line number Diff line number Diff line change
@@ -1095,11 +1095,11 @@ impl<'tcx> DumpVisitor<'tcx> {

let sm = self.tcx.sess.source_map();
let krate_mod = self.tcx.hir().root_module();
let filename = sm.span_to_filename(krate_mod.inner);
let filename = sm.span_to_filename(krate_mod.spans.inner_span);
let data_id = id_from_hir_id(id, &self.save_ctxt);
let children =
krate_mod.item_ids.iter().map(|i| id_from_def_id(i.def_id.to_def_id())).collect();
let span = self.span_from_span(krate_mod.inner);
let span = self.span_from_span(krate_mod.spans.inner_span);
let attrs = self.tcx.hir().attrs(id);

self.dumper.dump_def(
2 changes: 1 addition & 1 deletion compiler/rustc_save_analysis/src/lib.rs
Original file line number Diff line number Diff line change
@@ -282,7 +282,7 @@ impl<'tcx> SaveContext<'tcx> {
let qualname = format!("::{}", self.tcx.def_path_str(def_id));

let sm = self.tcx.sess.source_map();
let filename = sm.span_to_filename(m.inner);
let filename = sm.span_to_filename(m.spans.inner_span);

filter!(self.span_utils, item.ident.span);

2 changes: 1 addition & 1 deletion compiler/rustc_session/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![feature(crate_visibility_modifier)]
#![feature(derive_default_enum)]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![cfg_attr(bootstrap, feature(derive_default_enum))]
#![feature(let_else)]
#![feature(min_specialization)]
#![feature(never_type)]
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/lib.rs
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(crate_visibility_modifier)]
#![feature(derive_default_enum)]
#![cfg_attr(bootstrap, feature(derive_default_enum))]
#![feature(drain_filter)]
#![feature(hash_drain_filter)]
#![feature(label_break_value)]
146 changes: 21 additions & 125 deletions compiler/rustc_typeck/src/check/method/suggest.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ use rustc_errors::{
MultiSpan,
};
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{ExprKind, Node, QPath};
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -1473,12 +1473,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

fn suggest_use_candidates(
&self,
err: &mut Diagnostic,
mut msg: String,
candidates: Vec<DefId>,
) {
fn suggest_use_candidates(&self, err: &mut Diagnostic, msg: String, candidates: Vec<DefId>) {
let parent_map = self.tcx.visible_parent_map(());

// Separate out candidates that must be imported with a glob, because they are named `_`
@@ -1502,80 +1497,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
});

let module_did = self.tcx.parent_module(self.body_id);
let (span, found_use) = find_use_placement(self.tcx, module_did);
if let Some(span) = span {
let path_strings = candidates.iter().map(|trait_did| {
// Produce an additional newline to separate the new use statement
// from the directly following item.
let additional_newline = if found_use { "" } else { "\n" };
format!(
"use {};\n{}",
with_crate_prefix!(self.tcx.def_path_str(*trait_did)),
additional_newline
)
});
let (module, _, _) = self.tcx.hir().get_module(module_did);
let span = module.spans.inject_use_span;

let glob_path_strings = globs.iter().map(|trait_did| {
let parent_did = parent_map.get(trait_did).unwrap();
let path_strings = candidates.iter().map(|trait_did| {
format!("use {};\n", with_crate_prefix!(self.tcx.def_path_str(*trait_did)),)
});

// Produce an additional newline to separate the new use statement
// from the directly following item.
let additional_newline = if found_use { "" } else { "\n" };
format!(
"use {}::*; // trait {}\n{}",
with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
self.tcx.item_name(*trait_did),
additional_newline
)
});
let glob_path_strings = globs.iter().map(|trait_did| {
let parent_did = parent_map.get(trait_did).unwrap();
format!(
"use {}::*; // trait {}\n",
with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
self.tcx.item_name(*trait_did),
)
});

err.span_suggestions(
span,
&msg,
path_strings.chain(glob_path_strings),
Applicability::MaybeIncorrect,
);
} else {
let limit = if candidates.len() + globs.len() == 5 { 5 } else { 4 };
for (i, trait_did) in candidates.iter().take(limit).enumerate() {
if candidates.len() + globs.len() > 1 {
msg.push_str(&format!(
"\ncandidate #{}: `use {};`",
i + 1,
with_crate_prefix!(self.tcx.def_path_str(*trait_did))
));
} else {
msg.push_str(&format!(
"\n`use {};`",
with_crate_prefix!(self.tcx.def_path_str(*trait_did))
));
}
}
for (i, trait_did) in
globs.iter().take(limit.saturating_sub(candidates.len())).enumerate()
{
let parent_did = parent_map.get(trait_did).unwrap();

if candidates.len() + globs.len() > 1 {
msg.push_str(&format!(
"\ncandidate #{}: `use {}::*; // trait {}`",
candidates.len() + i + 1,
with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
self.tcx.item_name(*trait_did),
));
} else {
msg.push_str(&format!(
"\n`use {}::*; // trait {}`",
with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
self.tcx.item_name(*trait_did),
));
}
}
if candidates.len() > limit {
msg.push_str(&format!("\nand {} others", candidates.len() + globs.len() - limit));
}
err.note(&msg);
}
err.span_suggestions(
span,
&msg,
path_strings.chain(glob_path_strings),
Applicability::MaybeIncorrect,
);
}

fn suggest_valid_traits(
@@ -2106,53 +2049,6 @@ pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
tcx.all_traits().map(|def_id| TraitInfo { def_id }).collect()
}

fn find_use_placement<'tcx>(tcx: TyCtxt<'tcx>, target_module: LocalDefId) -> (Option<Span>, bool) {
// FIXME(#94854): this code uses an out-of-date method for inferring a span
// to suggest. It would be better to thread the ModSpans from the AST into
// the HIR, and then use that to drive the suggestion here.

let mut span = None;
let mut found_use = false;
let (module, _, _) = tcx.hir().get_module(target_module);

// Find a `use` statement.
for &item_id in module.item_ids {
let item = tcx.hir().item(item_id);
match item.kind {
hir::ItemKind::Use(..) => {
// Don't suggest placing a `use` before the prelude
// import or other generated ones.
if !item.span.from_expansion() {
span = Some(item.span.shrink_to_lo());
found_use = true;
break;
}
}
// Don't place `use` before `extern crate`...
hir::ItemKind::ExternCrate(_) => {}
// ...but do place them before the first other item.
_ => {
if span.map_or(true, |span| item.span < span) {
if !item.span.from_expansion() {
span = Some(item.span.shrink_to_lo());
// Don't insert between attributes and an item.
let attrs = tcx.hir().attrs(item.hir_id());
// Find the first attribute on the item.
// FIXME: This is broken for active attributes.
for attr in attrs {
if !attr.span.is_dummy() && span.map_or(true, |span| attr.span < span) {
span = Some(attr.span.shrink_to_lo());
}
}
}
}
}
}
}

(span, found_use)
}

fn print_disambiguation_help<'tcx>(
item_name: Ident,
args: Option<&'tcx [hir::Expr<'tcx>]>,
17 changes: 17 additions & 0 deletions library/core/src/default.rs
Original file line number Diff line number Diff line change
@@ -52,6 +52,23 @@
/// This trait can be used with `#[derive]` if all of the type's fields implement
/// `Default`. When `derive`d, it will use the default value for each field's type.
///
/// ### `enum`s
///
/// When using `#[derive(Default)]` on an `enum`, you need to choose which unit variant will be
/// default. You do this by placing the `#[default]` attribute on the variant.
///
/// ```
/// #[derive(Default)]
/// enum Kind {
/// #[default]
/// A,
/// B,
/// C,
/// }
/// ```
///
/// You cannot use the `#[default]` attribute on non-unit or non-exhaustive variants.
///
/// ## How can I implement `Default`?
///
/// Provide an implementation for the `default()` method that returns the value of
4 changes: 4 additions & 0 deletions library/core/src/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
@@ -470,6 +470,10 @@ pub trait Iterator {
/// it will first try to advance the first iterator at most one time and if it still yielded an item
/// try to advance the second iterator at most one time.
///
/// To 'undo' the result of zipping up two iterators, see [`unzip`].
///
/// [`unzip`]: Iterator::unzip
///
/// # Examples
///
/// Basic usage:
2 changes: 1 addition & 1 deletion library/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -167,7 +167,7 @@
#![feature(const_precise_live_drops)]
#![feature(const_refs_to_cell)]
#![feature(decl_macro)]
#![feature(derive_default_enum)]
#![cfg_attr(bootstrap, feature(derive_default_enum))]
#![feature(deprecated_suggestion)]
#![feature(doc_cfg)]
#![feature(doc_notable_trait)]
30 changes: 14 additions & 16 deletions library/std/src/sys/unix/futex.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
all(target_os = "emscripten", target_feature = "atomics")
))]

use crate::sync::atomic::AtomicI32;
use crate::sync::atomic::AtomicU32;
use crate::time::Duration;

/// Wait for a futex_wake operation to wake us.
@@ -13,7 +13,7 @@ use crate::time::Duration;
///
/// Returns false on timeout, and true in all other cases.
#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) -> bool {
pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool {
use super::time::Timespec;
use crate::ptr::null;
use crate::sync::atomic::Ordering::Relaxed;
@@ -35,7 +35,7 @@ pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) -
let r = unsafe {
libc::syscall(
libc::SYS_futex,
futex as *const AtomicI32,
futex as *const AtomicU32,
libc::FUTEX_WAIT_BITSET | libc::FUTEX_PRIVATE_FLAG,
expected,
timespec.as_ref().map_or(null(), |t| &t.t as *const libc::timespec),
@@ -53,21 +53,19 @@ pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) -
}

#[cfg(target_os = "emscripten")]
pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) {
pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) {
extern "C" {
fn emscripten_futex_wait(
addr: *const AtomicI32,
addr: *const AtomicU32,
val: libc::c_uint,
max_wait_ms: libc::c_double,
) -> libc::c_int;
}

unsafe {
emscripten_futex_wait(
futex as *const AtomicI32,
// `val` is declared unsigned to match the Emscripten headers, but since it's used as
// an opaque value, we can ignore the meaning of signed vs. unsigned and cast here.
expected as libc::c_uint,
futex,
expected,
timeout.map_or(crate::f64::INFINITY, |d| d.as_secs_f64() * 1000.0),
);
}
@@ -78,11 +76,11 @@ pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) {
/// Returns true if this actually woke up such a thread,
/// or false if no thread was waiting on this futex.
#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn futex_wake(futex: &AtomicI32) -> bool {
pub fn futex_wake(futex: &AtomicU32) -> bool {
unsafe {
libc::syscall(
libc::SYS_futex,
futex as *const AtomicI32,
futex as *const AtomicU32,
libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG,
1,
) > 0
@@ -91,22 +89,22 @@ pub fn futex_wake(futex: &AtomicI32) -> bool {

/// Wake up all threads that are waiting on futex_wait on this futex.
#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn futex_wake_all(futex: &AtomicI32) {
pub fn futex_wake_all(futex: &AtomicU32) {
unsafe {
libc::syscall(
libc::SYS_futex,
futex as *const AtomicI32,
futex as *const AtomicU32,
libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG,
i32::MAX,
);
}
}

#[cfg(target_os = "emscripten")]
pub fn futex_wake(futex: &AtomicI32) -> bool {
pub fn futex_wake(futex: &AtomicU32) -> bool {
extern "C" {
fn emscripten_futex_wake(addr: *const AtomicI32, count: libc::c_int) -> libc::c_int;
fn emscripten_futex_wake(addr: *const AtomicU32, count: libc::c_int) -> libc::c_int;
}

unsafe { emscripten_futex_wake(futex as *const AtomicI32, 1) > 0 }
unsafe { emscripten_futex_wake(futex, 1) > 0 }
}
12 changes: 6 additions & 6 deletions library/std/src/sys/unix/locks/futex.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::cell::UnsafeCell;
use crate::sync::atomic::{
AtomicI32, AtomicUsize,
AtomicU32, AtomicUsize,
Ordering::{Acquire, Relaxed, Release},
};
use crate::sys::futex::{futex_wait, futex_wake, futex_wake_all};
@@ -13,13 +13,13 @@ pub struct Mutex {
/// 0: unlocked
/// 1: locked, no other threads waiting
/// 2: locked, and other threads waiting (contended)
futex: AtomicI32,
futex: AtomicU32,
}

impl Mutex {
#[inline]
pub const fn new() -> Self {
Self { futex: AtomicI32::new(0) }
Self { futex: AtomicU32::new(0) }
}

#[inline]
@@ -71,7 +71,7 @@ impl Mutex {
}
}

fn spin(&self) -> i32 {
fn spin(&self) -> u32 {
let mut spin = 100;
loop {
// We only use `load` (and not `swap` or `compare_exchange`)
@@ -110,13 +110,13 @@ pub struct Condvar {
// The value of this atomic is simply incremented on every notification.
// This is used by `.wait()` to not miss any notifications after
// unlocking the mutex and before waiting for notifications.
futex: AtomicI32,
futex: AtomicU32,
}

impl Condvar {
#[inline]
pub const fn new() -> Self {
Self { futex: AtomicI32::new(0) }
Self { futex: AtomicU32::new(0) }
}

#[inline]
40 changes: 20 additions & 20 deletions library/std/src/sys/unix/locks/futex_rwlock.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::sync::atomic::{
AtomicI32,
AtomicU32,
Ordering::{Acquire, Relaxed, Release},
};
use crate::sys::futex::{futex_wait, futex_wake, futex_wake_all};
@@ -14,36 +14,36 @@ pub struct RwLock {
// 0x3FFF_FFFF: Write locked
// Bit 30: Readers are waiting on this futex.
// Bit 31: Writers are waiting on the writer_notify futex.
state: AtomicI32,
state: AtomicU32,
// The 'condition variable' to notify writers through.
// Incremented on every signal.
writer_notify: AtomicI32,
writer_notify: AtomicU32,
}

const READ_LOCKED: i32 = 1;
const MASK: i32 = (1 << 30) - 1;
const WRITE_LOCKED: i32 = MASK;
const MAX_READERS: i32 = MASK - 1;
const READERS_WAITING: i32 = 1 << 30;
const WRITERS_WAITING: i32 = 1 << 31;
const READ_LOCKED: u32 = 1;
const MASK: u32 = (1 << 30) - 1;
const WRITE_LOCKED: u32 = MASK;
const MAX_READERS: u32 = MASK - 1;
const READERS_WAITING: u32 = 1 << 30;
const WRITERS_WAITING: u32 = 1 << 31;

fn is_unlocked(state: i32) -> bool {
fn is_unlocked(state: u32) -> bool {
state & MASK == 0
}

fn is_write_locked(state: i32) -> bool {
fn is_write_locked(state: u32) -> bool {
state & MASK == WRITE_LOCKED
}

fn has_readers_waiting(state: i32) -> bool {
fn has_readers_waiting(state: u32) -> bool {
state & READERS_WAITING != 0
}

fn has_writers_waiting(state: i32) -> bool {
fn has_writers_waiting(state: u32) -> bool {
state & WRITERS_WAITING != 0
}

fn is_read_lockable(state: i32) -> bool {
fn is_read_lockable(state: u32) -> bool {
// This also returns false if the counter could overflow if we tried to read lock it.
//
// We don't allow read-locking if there's readers waiting, even if the lock is unlocked
@@ -53,14 +53,14 @@ fn is_read_lockable(state: i32) -> bool {
state & MASK < MAX_READERS && !has_readers_waiting(state) && !has_writers_waiting(state)
}

fn has_reached_max_readers(state: i32) -> bool {
fn has_reached_max_readers(state: u32) -> bool {
state & MASK == MAX_READERS
}

impl RwLock {
#[inline]
pub const fn new() -> Self {
Self { state: AtomicI32::new(0), writer_notify: AtomicI32::new(0) }
Self { state: AtomicU32::new(0), writer_notify: AtomicU32::new(0) }
}

#[inline]
@@ -227,7 +227,7 @@ impl RwLock {
/// If both are waiting, this will wake up only one writer, but will fall
/// back to waking up readers if there was no writer to wake up.
#[cold]
fn wake_writer_or_readers(&self, mut state: i32) {
fn wake_writer_or_readers(&self, mut state: u32) {
assert!(is_unlocked(state));

// The readers waiting bit might be turned on at any point now,
@@ -287,7 +287,7 @@ impl RwLock {
}

/// Spin for a while, but stop directly at the given condition.
fn spin_until(&self, f: impl Fn(i32) -> bool) -> i32 {
fn spin_until(&self, f: impl Fn(u32) -> bool) -> u32 {
let mut spin = 100; // Chosen by fair dice roll.
loop {
let state = self.state.load(Relaxed);
@@ -299,12 +299,12 @@ impl RwLock {
}
}

fn spin_write(&self) -> i32 {
fn spin_write(&self) -> u32 {
// Stop spinning when it's unlocked or when there's waiting writers, to keep things somewhat fair.
self.spin_until(|state| is_unlocked(state) || has_writers_waiting(state))
}

fn spin_read(&self) -> i32 {
fn spin_read(&self) -> u32 {
// Stop spinning when it's unlocked or read locked, or when there's waiting threads.
self.spin_until(|state| {
!is_write_locked(state) || has_readers_waiting(state) || has_writers_waiting(state)
14 changes: 9 additions & 5 deletions library/std/src/sys/wasm/atomics/futex.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
use crate::arch::wasm32;
use crate::convert::TryInto;
use crate::sync::atomic::AtomicI32;
use crate::sync::atomic::AtomicU32;
use crate::time::Duration;

pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) {
pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) {
let timeout = timeout.and_then(|t| t.as_nanos().try_into().ok()).unwrap_or(-1);
unsafe {
wasm32::memory_atomic_wait32(futex as *const AtomicI32 as *mut i32, expected, timeout);
wasm32::memory_atomic_wait32(
futex as *const AtomicU32 as *mut i32,
expected as i32,
timeout,
);
}
}

pub fn futex_wake(futex: &AtomicI32) {
pub fn futex_wake(futex: &AtomicU32) {
unsafe {
wasm32::memory_atomic_notify(futex as *const AtomicI32 as *mut i32, 1);
wasm32::memory_atomic_notify(futex as *const AtomicU32 as *mut i32, 1);
}
}
12 changes: 6 additions & 6 deletions library/std/src/sys_common/thread_parker/futex.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use crate::sync::atomic::AtomicI32;
use crate::sync::atomic::AtomicU32;
use crate::sync::atomic::Ordering::{Acquire, Release};
use crate::sys::futex::{futex_wait, futex_wake};
use crate::time::Duration;

const PARKED: i32 = -1;
const EMPTY: i32 = 0;
const NOTIFIED: i32 = 1;
const PARKED: u32 = u32::MAX;
const EMPTY: u32 = 0;
const NOTIFIED: u32 = 1;

pub struct Parker {
state: AtomicI32,
state: AtomicU32,
}

// Notes about memory ordering:
@@ -34,7 +34,7 @@ pub struct Parker {
impl Parker {
#[inline]
pub const fn new() -> Self {
Parker { state: AtomicI32::new(EMPTY) }
Parker { state: AtomicU32::new(EMPTY) }
}

// Assumes this is only called by the thread that owns the Parker,
2 changes: 1 addition & 1 deletion src/doc/book
Submodule book updated 37 files
+2 −2 .github/workflows/main.yml
+1 −1 listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs
+1 −1 listings/ch02-guessing-game-tutorial/listing-02-02/src/main.rs
+3 −3 listings/ch02-guessing-game-tutorial/listing-02-03/src/main.rs
+2 −2 listings/ch02-guessing-game-tutorial/listing-02-04/output.txt
+3 −3 listings/ch02-guessing-game-tutorial/listing-02-04/src/main.rs
+3 −3 listings/ch02-guessing-game-tutorial/listing-02-05/src/main.rs
+2 −2 listings/ch02-guessing-game-tutorial/listing-02-06/src/main.rs
+2 −1 listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/Cargo.lock
+1 −1 listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/src/main.rs
+3 −3 listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/src/main.rs
+3 −3 listings/ch02-guessing-game-tutorial/no-listing-04-looping/src/main.rs
+3 −3 listings/ch02-guessing-game-tutorial/no-listing-05-quitting/src/main.rs
+2 −0 listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt
+3 −3 listings/ch07-managing-growing-projects/listing-07-18/src/main.rs
+3 −3 listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/src/main.rs
+1 −1 listings/ch09-error-handling/listing-09-13/src/main.rs
+1 −1 listings/ch09-error-handling/no-listing-09-guess-out-of-range/src/main.rs
+2 −0 listings/ch13-functional-features/no-listing-03-move-closures/output.txt
+0 −1 listings/ch14-more-about-cargo/output-only-02-add-one/add/.gitignore
+8 −0 listings/ch14-more-about-cargo/output-only-02-add-one/add/add_one/Cargo.toml
+8 −0 listings/ch14-more-about-cargo/output-only-02-add-one/add/add_one/src/lib.rs
+1 −1 listings/ch15-smart-pointers/listing-15-03/output.txt
+2 −0 listings/ch16-fearless-concurrency/listing-16-09/output.txt
+1 −3 listings/ch18-patterns-and-matching/listing-18-05/output.txt
+158 −96 nostarch/chapter02.md
+200 −208 nostarch/chapter11.md
+1 −1 rust-toolchain
+1 −1 src/appendix-04-useful-development-tools.md
+58 −52 src/ch02-00-guessing-game-tutorial.md
+9 −11 src/ch11-00-testing.md
+135 −140 src/ch11-01-writing-tests.md
+20 −21 src/ch11-02-running-tests.md
+29 −36 src/ch11-03-test-organization.md
+3 −2 src/ch13-02-iterators.md
+1 −1 src/title-page.md
+5 −2 tools/src/bin/concat_chapters.rs
2 changes: 1 addition & 1 deletion src/doc/nomicon
Submodule nomicon updated 1 files
+1 −1 src/send-and-sync.md
7 changes: 5 additions & 2 deletions src/librustdoc/html/render/span_map.rs
Original file line number Diff line number Diff line change
@@ -119,11 +119,14 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
fn visit_mod(&mut self, m: &'tcx Mod<'tcx>, span: Span, id: HirId) {
// To make the difference between "mod foo {}" and "mod foo;". In case we "import" another
// file, we want to link to it. Otherwise no need to create a link.
if !span.overlaps(m.inner) {
if !span.overlaps(m.spans.inner_span) {
// Now that we confirmed it's a file import, we want to get the span for the module
// name only and not all the "mod foo;".
if let Some(Node::Item(item)) = self.tcx.hir().find(id) {
self.matches.insert(item.ident.span, LinkFromSrc::Local(clean::Span::new(m.inner)));
self.matches.insert(
item.ident.span,
LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)),
);
}
}
intravisit::walk_mod(self, m, id);
2 changes: 1 addition & 1 deletion src/librustdoc/visit_ast.rs
Original file line number Diff line number Diff line change
@@ -154,7 +154,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
m: &'tcx hir::Mod<'tcx>,
name: Symbol,
) -> Module<'tcx> {
let mut om = Module::new(name, id, m.inner);
let mut om = Module::new(name, id, m.spans.inner_span);
let def_id = self.cx.tcx.hir().local_def_id(id).to_def_id();
// Keep track of if there were any private modules in the path.
let orig_inside_public_path = self.inside_public_path;
2 changes: 0 additions & 2 deletions src/test/ui/deriving/deriving-default-enum.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// run-pass

#![feature(derive_default_enum)]

// nb: does not impl Default
#[derive(Debug, PartialEq)]
struct NotDefault;
1 change: 0 additions & 1 deletion src/test/ui/deriving/deriving-with-helper.rs
Original file line number Diff line number Diff line change
@@ -5,7 +5,6 @@
#![feature(lang_items)]
#![feature(no_core)]
#![feature(rustc_attrs)]
#![feature(derive_default_enum)]

#![no_core]

7 changes: 0 additions & 7 deletions src/test/ui/feature-gates/feature-gate-derive_default_enum.rs

This file was deleted.

13 changes: 0 additions & 13 deletions src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr

This file was deleted.

4 changes: 2 additions & 2 deletions src/test/ui/imports/overlapping_pub_trait.rs
Original file line number Diff line number Diff line change
@@ -4,10 +4,10 @@
* This crate declares two public paths, `m::Tr` and `prelude::_`. Make sure we prefer the former.
*/
extern crate overlapping_pub_trait_source;
//~^ HELP the following trait is implemented but not in scope; perhaps add a `use` for it:
//~| SUGGESTION overlapping_pub_trait_source::m::Tr

fn main() {
//~^ HELP the following trait is implemented but not in scope; perhaps add a `use` for it:
//~| SUGGESTION overlapping_pub_trait_source::m::Tr
use overlapping_pub_trait_source::S;
S.method();
//~^ ERROR no method named `method` found for struct `S` in the current scope [E0599]
4 changes: 2 additions & 2 deletions src/test/ui/imports/unnamed_pub_trait.rs
Original file line number Diff line number Diff line change
@@ -5,10 +5,10 @@
* importing it by name, and instead we suggest importing it by glob.
*/
extern crate unnamed_pub_trait_source;
//~^ HELP the following trait is implemented but not in scope; perhaps add a `use` for it:
//~| SUGGESTION unnamed_pub_trait_source::prelude::*; // trait Tr

fn main() {
//~^ HELP the following trait is implemented but not in scope; perhaps add a `use` for it:
//~| SUGGESTION unnamed_pub_trait_source::prelude::*; // trait Tr
use unnamed_pub_trait_source::S;
S.method();
//~^ ERROR no method named `method` found for struct `S` in the current scope [E0599]
1 change: 0 additions & 1 deletion src/test/ui/macros/macros-nonfatal-errors.rs
Original file line number Diff line number Diff line change
@@ -5,7 +5,6 @@

#![feature(trace_macros, concat_idents)]
#![feature(stmt_expr_attributes, arbitrary_enum_discriminant)]
#![feature(derive_default_enum)]

use std::arch::asm;

58 changes: 29 additions & 29 deletions src/test/ui/macros/macros-nonfatal-errors.stderr
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
error: the `#[default]` attribute may only be used on unit enum variants
--> $DIR/macros-nonfatal-errors.rs:14:5
--> $DIR/macros-nonfatal-errors.rs:13:5
|
LL | #[default]
| ^^^^^^^^^^

error: the `#[default]` attribute may only be used on unit enum variants
--> $DIR/macros-nonfatal-errors.rs:19:36
--> $DIR/macros-nonfatal-errors.rs:18:36
|
LL | struct DefaultInnerAttrTupleStruct(#[default] ());
| ^^^^^^^^^^

error: the `#[default]` attribute may only be used on unit enum variants
--> $DIR/macros-nonfatal-errors.rs:23:1
--> $DIR/macros-nonfatal-errors.rs:22:1
|
LL | #[default]
| ^^^^^^^^^^

error: the `#[default]` attribute may only be used on unit enum variants
--> $DIR/macros-nonfatal-errors.rs:27:1
--> $DIR/macros-nonfatal-errors.rs:26:1
|
LL | #[default]
| ^^^^^^^^^^

error: the `#[default]` attribute may only be used on unit enum variants
--> $DIR/macros-nonfatal-errors.rs:37:11
--> $DIR/macros-nonfatal-errors.rs:36:11
|
LL | Foo = #[default] 0,
| ^^^^^^^^^^

error: the `#[default]` attribute may only be used on unit enum variants
--> $DIR/macros-nonfatal-errors.rs:38:14
--> $DIR/macros-nonfatal-errors.rs:37:14
|
LL | Bar([u8; #[default] 1]),
| ^^^^^^^^^^

error: no default declared
--> $DIR/macros-nonfatal-errors.rs:43:10
--> $DIR/macros-nonfatal-errors.rs:42:10
|
LL | #[derive(Default)]
| ^^^^^^^
@@ -44,7 +44,7 @@ LL | #[derive(Default)]
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)

error: multiple declared defaults
--> $DIR/macros-nonfatal-errors.rs:49:10
--> $DIR/macros-nonfatal-errors.rs:48:10
|
LL | #[derive(Default)]
| ^^^^^^^
@@ -62,15 +62,15 @@ LL | Baz,
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)

error: `#[default]` attribute does not accept a value
--> $DIR/macros-nonfatal-errors.rs:61:5
--> $DIR/macros-nonfatal-errors.rs:60:5
|
LL | #[default = 1]
| ^^^^^^^^^^^^^^
|
= help: try using `#[default]`

error: multiple `#[default]` attributes
--> $DIR/macros-nonfatal-errors.rs:69:5
--> $DIR/macros-nonfatal-errors.rs:68:5
|
LL | #[default]
| ---------- `#[default]` used here
@@ -81,13 +81,13 @@ LL | Foo,
|
= note: only one `#[default]` attribute is needed
help: try removing this
--> $DIR/macros-nonfatal-errors.rs:68:5
--> $DIR/macros-nonfatal-errors.rs:67:5
|
LL | #[default]
| ^^^^^^^^^^

error: multiple `#[default]` attributes
--> $DIR/macros-nonfatal-errors.rs:79:5
--> $DIR/macros-nonfatal-errors.rs:78:5
|
LL | #[default]
| ---------- `#[default]` used here
@@ -99,7 +99,7 @@ LL | Foo,
|
= note: only one `#[default]` attribute is needed
help: try removing these
--> $DIR/macros-nonfatal-errors.rs:76:5
--> $DIR/macros-nonfatal-errors.rs:75:5
|
LL | #[default]
| ^^^^^^^^^^
@@ -109,15 +109,15 @@ LL | #[default]
| ^^^^^^^^^^

error: the `#[default]` attribute may only be used on unit enum variants
--> $DIR/macros-nonfatal-errors.rs:86:5
--> $DIR/macros-nonfatal-errors.rs:85:5
|
LL | Foo {},
| ^^^
|
= help: consider a manual implementation of `Default`

error: default variant must be exhaustive
--> $DIR/macros-nonfatal-errors.rs:94:5
--> $DIR/macros-nonfatal-errors.rs:93:5
|
LL | #[non_exhaustive]
| ----------------- declared `#[non_exhaustive]` here
@@ -127,45 +127,45 @@ LL | Foo,
= help: consider a manual implementation of `Default`

error: asm template must be a string literal
--> $DIR/macros-nonfatal-errors.rs:99:10
--> $DIR/macros-nonfatal-errors.rs:98:10
|
LL | asm!(invalid);
| ^^^^^^^

error: concat_idents! requires ident args
--> $DIR/macros-nonfatal-errors.rs:102:5
--> $DIR/macros-nonfatal-errors.rs:101:5
|
LL | concat_idents!("not", "idents");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: argument must be a string literal
--> $DIR/macros-nonfatal-errors.rs:104:17
--> $DIR/macros-nonfatal-errors.rs:103:17
|
LL | option_env!(invalid);
| ^^^^^^^

error: expected string literal
--> $DIR/macros-nonfatal-errors.rs:105:10
--> $DIR/macros-nonfatal-errors.rs:104:10
|
LL | env!(invalid);
| ^^^^^^^

error: expected string literal
--> $DIR/macros-nonfatal-errors.rs:106:10
--> $DIR/macros-nonfatal-errors.rs:105:10
|
LL | env!(foo, abr, baz);
| ^^^

error: environment variable `RUST_HOPEFULLY_THIS_DOESNT_EXIST` not defined
--> $DIR/macros-nonfatal-errors.rs:107:5
--> $DIR/macros-nonfatal-errors.rs:106:5
|
LL | env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)

error: format argument must be a string literal
--> $DIR/macros-nonfatal-errors.rs:109:13
--> $DIR/macros-nonfatal-errors.rs:108:13
|
LL | format!(invalid);
| ^^^^^^^
@@ -176,47 +176,47 @@ LL | format!("{}", invalid);
| +++++

error: argument must be a string literal
--> $DIR/macros-nonfatal-errors.rs:111:14
--> $DIR/macros-nonfatal-errors.rs:110:14
|
LL | include!(invalid);
| ^^^^^^^

error: argument must be a string literal
--> $DIR/macros-nonfatal-errors.rs:113:18
--> $DIR/macros-nonfatal-errors.rs:112:18
|
LL | include_str!(invalid);
| ^^^^^^^

error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: $FILE_NOT_FOUND_MSG (os error 2)
--> $DIR/macros-nonfatal-errors.rs:114:5
--> $DIR/macros-nonfatal-errors.rs:113:5
|
LL | include_str!("i'd be quite surprised if a file with this name existed");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info)

error: argument must be a string literal
--> $DIR/macros-nonfatal-errors.rs:115:20
--> $DIR/macros-nonfatal-errors.rs:114:20
|
LL | include_bytes!(invalid);
| ^^^^^^^

error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: $FILE_NOT_FOUND_MSG (os error 2)
--> $DIR/macros-nonfatal-errors.rs:116:5
--> $DIR/macros-nonfatal-errors.rs:115:5
|
LL | include_bytes!("i'd be quite surprised if a file with this name existed");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info)

error: trace_macros! accepts only `true` or `false`
--> $DIR/macros-nonfatal-errors.rs:118:5
--> $DIR/macros-nonfatal-errors.rs:117:5
|
LL | trace_macros!(invalid);
| ^^^^^^^^^^^^^^^^^^^^^^

error: cannot find macro `llvm_asm` in this scope
--> $DIR/macros-nonfatal-errors.rs:100:5
--> $DIR/macros-nonfatal-errors.rs:99:5
|
LL | llvm_asm!(invalid);
| ^^^^^^^^
10 changes: 10 additions & 0 deletions src/test/ui/mir/issue-95978-validator-lifetime-comparison.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// check-pass
// compile-flags: -Zvalidate-mir

fn foo(_a: &str) {}

fn main() {
let x = foo as fn(&'static str);

let _ = x == foo;
}
1 change: 0 additions & 1 deletion src/test/ui/suggestions/use-placement-typeck.fixed
Original file line number Diff line number Diff line change
@@ -7,7 +7,6 @@
#![allow(unused)]

use m::Foo;

fn main() {
let s = m::S;
s.abc(); //~ ERROR no method named `abc`
30 changes: 30 additions & 0 deletions src/test/ui/thread-local/non-static.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Check that #[thread_local] attribute is rejected on non-static items.
#![feature(thread_local)]

#[thread_local]
//~^ ERROR attribute should be applied to a static
const A: u32 = 0;

#[thread_local]
//~^ ERROR attribute should be applied to a static
fn main() {
#[thread_local] || {};
//~^ ERROR attribute should be applied to a static
}

struct S {
#[thread_local]
//~^ ERROR attribute should be applied to a static
a: String,
b: String,
}

#[thread_local]
// Static. OK.
static B: u32 = 0;

extern "C" {
#[thread_local]
// Foreign static. OK.
static C: u32;
}
38 changes: 38 additions & 0 deletions src/test/ui/thread-local/non-static.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
error: attribute should be applied to a static
--> $DIR/non-static.rs:4:1
|
LL | #[thread_local]
| ^^^^^^^^^^^^^^^
LL |
LL | const A: u32 = 0;
| ----------------- not a static

error: attribute should be applied to a static
--> $DIR/non-static.rs:8:1
|
LL | #[thread_local]
| ^^^^^^^^^^^^^^^
LL |
LL | / fn main() {
LL | | #[thread_local] || {};
LL | |
LL | | }
| |_- not a static

error: attribute should be applied to a static
--> $DIR/non-static.rs:11:5
|
LL | #[thread_local] || {};
| ^^^^^^^^^^^^^^^ ----- not a static

error: attribute should be applied to a static
--> $DIR/non-static.rs:16:5
|
LL | #[thread_local]
| ^^^^^^^^^^^^^^^
LL |
LL | a: String,
| --------- not a static

error: aborting due to 4 previous errors

4 changes: 4 additions & 0 deletions src/test/ui/unterminated-nested-comment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/* //~ ERROR E0758
/* */
/*
*/
21 changes: 21 additions & 0 deletions src/test/ui/unterminated-nested-comment.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0758]: unterminated block comment
--> $DIR/unterminated-nested-comment.rs:1:1
|
LL | /*
| ^-
| |
| _unterminated block comment
| |
LL | | /* */
LL | | /*
| | --
| | |
| | ...as last nested comment starts here, maybe you want to close this instead?
LL | | */
| |_--^
| |
| ...and last nested comment terminates here.

error: aborting due to previous error

For more information about this error, try `rustc --explain E0758`.