Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 598d89b

Browse files
committedOct 1, 2021
Auto merge of rust-lang#89414 - Manishearth:rollup-hs11bcq, r=Manishearth
Rollup of 8 pull requests Successful merges: - rust-lang#88782 (Fix ICE when `start` lang item has wrong generics) - rust-lang#89202 (Resolve infered types when complaining about unexpected call type ) - rust-lang#89248 (Suggest similarly named associated items in trait impls) - rust-lang#89303 (Add `#[must_not_suspend]` to some types in std) - rust-lang#89306 (thread: implements available_concurrency on haiku) - rust-lang#89314 (fix(lint): don't suggest refutable patterns to "fix" irrefutable bind) - rust-lang#89370 (CTFE: tweak aggregate rvalue handling) - rust-lang#89392 (bootstrap: Update comment in config.library.toml.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 1c0ed0d + 9ea439d commit 598d89b

File tree

30 files changed

+427
-63
lines changed

30 files changed

+427
-63
lines changed
 

‎compiler/rustc_const_eval/src/interpret/step.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -197,12 +197,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
197197
}
198198

199199
Aggregate(ref kind, ref operands) => {
200+
// active_field_index is for union initialization.
200201
let (dest, active_field_index) = match **kind {
201202
mir::AggregateKind::Adt(adt_def, variant_index, _, _, active_field_index) => {
202203
self.write_discriminant(variant_index, &dest)?;
203204
if adt_def.is_enum() {
204-
(self.place_downcast(&dest, variant_index)?, active_field_index)
205+
assert!(active_field_index.is_none());
206+
(self.place_downcast(&dest, variant_index)?, None)
205207
} else {
208+
if active_field_index.is_some() {
209+
assert_eq!(operands.len(), 1);
210+
}
206211
(dest, active_field_index)
207212
}
208213
}
@@ -211,12 +216,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
211216

212217
for (i, operand) in operands.iter().enumerate() {
213218
let op = self.eval_operand(operand, None)?;
214-
// Ignore zero-sized fields.
215-
if !op.layout.is_zst() {
216-
let field_index = active_field_index.unwrap_or(i);
217-
let field_dest = self.place_field(&dest, field_index)?;
218-
self.copy_op(&op, &field_dest)?;
219-
}
219+
let field_index = active_field_index.unwrap_or(i);
220+
let field_dest = self.place_field(&dest, field_index)?;
221+
self.copy_op(&op, &field_dest)?;
220222
}
221223
}
222224

@@ -253,7 +255,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
253255
}
254256

255257
Len(place) => {
256-
// FIXME(CTFE): don't allow computing the length of arrays in const eval
257258
let src = self.eval_place(place)?;
258259
let mplace = self.force_allocation(&src)?;
259260
let len = mplace.len(self)?;

‎compiler/rustc_hir/src/lang_items.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ language_item_table! {
300300
Oom, sym::oom, oom, Target::Fn, GenericRequirement::None;
301301
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;
302302

303-
Start, sym::start, start_fn, Target::Fn, GenericRequirement::None;
303+
Start, sym::start, start_fn, Target::Fn, GenericRequirement::Exact(1);
304304

305305
EhPersonality, sym::eh_personality, eh_personality, Target::Fn, GenericRequirement::None;
306306
EhCatchTypeinfo, sym::eh_catch_typeinfo, eh_catch_typeinfo, Target::Static, GenericRequirement::None;

‎compiler/rustc_mir_build/src/thir/pattern/check_match.rs

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ fn create_e0004(sess: &Session, sp: Span, error_message: String) -> DiagnosticBu
3939
struct_span_err!(sess, sp, E0004, "{}", &error_message)
4040
}
4141

42+
#[derive(PartialEq)]
43+
enum RefutableFlag {
44+
Irrefutable,
45+
Refutable,
46+
}
47+
use RefutableFlag::*;
48+
4249
struct MatchVisitor<'a, 'p, 'tcx> {
4350
tcx: TyCtxt<'tcx>,
4451
typeck_results: &'a ty::TypeckResults<'tcx>,
@@ -73,13 +80,13 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, '_, 'tcx> {
7380
hir::LocalSource::AssignDesugar(_) => ("destructuring assignment binding", None),
7481
};
7582
self.check_irrefutable(&loc.pat, msg, sp);
76-
self.check_patterns(&loc.pat);
83+
self.check_patterns(&loc.pat, Irrefutable);
7784
}
7885

7986
fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
8087
intravisit::walk_param(self, param);
8188
self.check_irrefutable(&param.pat, "function argument", None);
82-
self.check_patterns(&param.pat);
89+
self.check_patterns(&param.pat, Irrefutable);
8390
}
8491
}
8592

@@ -113,9 +120,9 @@ impl PatCtxt<'_, '_> {
113120
}
114121

115122
impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
116-
fn check_patterns(&self, pat: &Pat<'_>) {
123+
fn check_patterns(&self, pat: &Pat<'_>, rf: RefutableFlag) {
117124
pat.walk_always(|pat| check_borrow_conflicts_in_at_patterns(self, pat));
118-
check_for_bindings_named_same_as_variants(self, pat);
125+
check_for_bindings_named_same_as_variants(self, pat, rf);
119126
}
120127

121128
fn lower_pattern(
@@ -145,7 +152,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
145152
}
146153

147154
fn check_let(&mut self, pat: &'tcx hir::Pat<'tcx>, expr: &hir::Expr<'_>, span: Span) {
148-
self.check_patterns(pat);
155+
self.check_patterns(pat, Refutable);
149156
let mut cx = self.new_cx(expr.hir_id);
150157
let tpat = self.lower_pattern(&mut cx, pat, &mut false);
151158
check_let_reachability(&mut cx, pat.hir_id, tpat, span);
@@ -161,9 +168,9 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
161168

162169
for arm in arms {
163170
// Check the arm for some things unrelated to exhaustiveness.
164-
self.check_patterns(&arm.pat);
171+
self.check_patterns(&arm.pat, Refutable);
165172
if let Some(hir::Guard::IfLet(ref pat, _)) = arm.guard {
166-
self.check_patterns(pat);
173+
self.check_patterns(pat, Refutable);
167174
let tpat = self.lower_pattern(&mut cx, pat, &mut false);
168175
check_let_reachability(&mut cx, pat.hir_id, tpat, tpat.span());
169176
}
@@ -297,7 +304,11 @@ fn const_not_var(
297304
}
298305
}
299306

300-
fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_, '_>, pat: &Pat<'_>) {
307+
fn check_for_bindings_named_same_as_variants(
308+
cx: &MatchVisitor<'_, '_, '_>,
309+
pat: &Pat<'_>,
310+
rf: RefutableFlag,
311+
) {
301312
pat.walk_always(|p| {
302313
if let hir::PatKind::Binding(_, _, ident, None) = p.kind {
303314
if let Some(ty::BindByValue(hir::Mutability::Not)) =
@@ -310,25 +321,31 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_, '_>, pat:
310321
variant.ident == ident && variant.ctor_kind == CtorKind::Const
311322
})
312323
{
324+
let variant_count = edef.variants.len();
313325
cx.tcx.struct_span_lint_hir(
314326
BINDINGS_WITH_VARIANT_NAME,
315327
p.hir_id,
316328
p.span,
317329
|lint| {
318330
let ty_path = cx.tcx.def_path_str(edef.did);
319-
lint.build(&format!(
331+
let mut err = lint.build(&format!(
320332
"pattern binding `{}` is named the same as one \
321-
of the variants of the type `{}`",
333+
of the variants of the type `{}`",
322334
ident, ty_path
323-
))
324-
.code(error_code!(E0170))
325-
.span_suggestion(
326-
p.span,
327-
"to match on the variant, qualify the path",
328-
format!("{}::{}", ty_path, ident),
329-
Applicability::MachineApplicable,
330-
)
331-
.emit();
335+
));
336+
err.code(error_code!(E0170));
337+
// If this is an irrefutable pattern, and there's > 1 variant,
338+
// then we can't actually match on this. Applying the below
339+
// suggestion would produce code that breaks on `check_irrefutable`.
340+
if rf == Refutable || variant_count == 1 {
341+
err.span_suggestion(
342+
p.span,
343+
"to match on the variant, qualify the path",
344+
format!("{}::{}", ty_path, ident),
345+
Applicability::MachineApplicable,
346+
);
347+
}
348+
err.emit();
332349
},
333350
)
334351
}

‎compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ impl<'a> Resolver<'a> {
198198
err.span_label(first_use_span, format!("first use of `{}`", name));
199199
err
200200
}
201-
ResolutionError::MethodNotMemberOfTrait(method, trait_) => {
201+
ResolutionError::MethodNotMemberOfTrait(method, trait_, candidate) => {
202202
let mut err = struct_span_err!(
203203
self.session,
204204
span,
@@ -208,9 +208,17 @@ impl<'a> Resolver<'a> {
208208
trait_
209209
);
210210
err.span_label(span, format!("not a member of trait `{}`", trait_));
211+
if let Some(candidate) = candidate {
212+
err.span_suggestion(
213+
method.span,
214+
"there is an associated function with a similar name",
215+
candidate.to_ident_string(),
216+
Applicability::MaybeIncorrect,
217+
);
218+
}
211219
err
212220
}
213-
ResolutionError::TypeNotMemberOfTrait(type_, trait_) => {
221+
ResolutionError::TypeNotMemberOfTrait(type_, trait_, candidate) => {
214222
let mut err = struct_span_err!(
215223
self.session,
216224
span,
@@ -220,9 +228,17 @@ impl<'a> Resolver<'a> {
220228
trait_
221229
);
222230
err.span_label(span, format!("not a member of trait `{}`", trait_));
231+
if let Some(candidate) = candidate {
232+
err.span_suggestion(
233+
type_.span,
234+
"there is an associated type with a similar name",
235+
candidate.to_ident_string(),
236+
Applicability::MaybeIncorrect,
237+
);
238+
}
223239
err
224240
}
225-
ResolutionError::ConstNotMemberOfTrait(const_, trait_) => {
241+
ResolutionError::ConstNotMemberOfTrait(const_, trait_, candidate) => {
226242
let mut err = struct_span_err!(
227243
self.session,
228244
span,
@@ -232,6 +248,14 @@ impl<'a> Resolver<'a> {
232248
trait_
233249
);
234250
err.span_label(span, format!("not a member of trait `{}`", trait_));
251+
if let Some(candidate) = candidate {
252+
err.span_suggestion(
253+
const_.span,
254+
"there is an associated constant with a similar name",
255+
candidate.to_ident_string(),
256+
Applicability::MaybeIncorrect,
257+
);
258+
}
235259
err
236260
}
237261
ResolutionError::VariableNotBoundInPattern(binding_error) => {

‎compiler/rustc_resolve/src/late.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,14 +1309,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13091309
use crate::ResolutionError::*;
13101310
match &item.kind {
13111311
AssocItemKind::Const(_default, _ty, _expr) => {
1312-
debug!("resolve_implementation AssocItemKind::Const",);
1312+
debug!("resolve_implementation AssocItemKind::Const");
13131313
// If this is a trait impl, ensure the const
13141314
// exists in trait
13151315
this.check_trait_item(
13161316
item.ident,
1317+
&item.kind,
13171318
ValueNS,
13181319
item.span,
1319-
|n, s| ConstNotMemberOfTrait(n, s),
1320+
|i, s, c| ConstNotMemberOfTrait(i, s, c),
13201321
);
13211322

13221323
// We allow arbitrary const expressions inside of associated consts,
@@ -1338,6 +1339,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13381339
);
13391340
}
13401341
AssocItemKind::Fn(box FnKind(.., generics, _)) => {
1342+
debug!("resolve_implementation AssocItemKind::Fn");
13411343
// We also need a new scope for the impl item type parameters.
13421344
this.with_generic_param_rib(
13431345
generics,
@@ -1347,9 +1349,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13471349
// exists in trait
13481350
this.check_trait_item(
13491351
item.ident,
1352+
&item.kind,
13501353
ValueNS,
13511354
item.span,
1352-
|n, s| MethodNotMemberOfTrait(n, s),
1355+
|i, s, c| MethodNotMemberOfTrait(i, s, c),
13531356
);
13541357

13551358
visit::walk_assoc_item(
@@ -1366,6 +1369,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13661369
_,
13671370
_,
13681371
)) => {
1372+
debug!("resolve_implementation AssocItemKind::TyAlias");
13691373
// We also need a new scope for the impl item type parameters.
13701374
this.with_generic_param_rib(
13711375
generics,
@@ -1375,9 +1379,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13751379
// exists in trait
13761380
this.check_trait_item(
13771381
item.ident,
1382+
&item.kind,
13781383
TypeNS,
13791384
item.span,
1380-
|n, s| TypeNotMemberOfTrait(n, s),
1385+
|i, s, c| TypeNotMemberOfTrait(i, s, c),
13811386
);
13821387

13831388
visit::walk_assoc_item(
@@ -1401,9 +1406,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
14011406
});
14021407
}
14031408

1404-
fn check_trait_item<F>(&mut self, ident: Ident, ns: Namespace, span: Span, err: F)
1405-
where
1406-
F: FnOnce(Symbol, &str) -> ResolutionError<'_>,
1409+
fn check_trait_item<F>(
1410+
&mut self,
1411+
ident: Ident,
1412+
kind: &AssocItemKind,
1413+
ns: Namespace,
1414+
span: Span,
1415+
err: F,
1416+
) where
1417+
F: FnOnce(Ident, &str, Option<Symbol>) -> ResolutionError<'_>,
14071418
{
14081419
// If there is a TraitRef in scope for an impl, then the method must be in the
14091420
// trait.
@@ -1420,8 +1431,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
14201431
)
14211432
.is_err()
14221433
{
1434+
let candidate = self.find_similarly_named_assoc_item(ident.name, kind);
14231435
let path = &self.current_trait_ref.as_ref().unwrap().1.path;
1424-
self.report_error(span, err(ident.name, &path_names_to_string(path)));
1436+
self.report_error(span, err(ident, &path_names_to_string(path), candidate));
14251437
}
14261438
}
14271439
}

‎compiler/rustc_resolve/src/late/diagnostics.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use crate::{PathResult, PathSource, Segment};
77

88
use rustc_ast::visit::FnKind;
99
use rustc_ast::{
10-
self as ast, Expr, ExprKind, GenericParam, GenericParamKind, Item, ItemKind, NodeId, Path, Ty,
11-
TyKind,
10+
self as ast, AssocItemKind, Expr, ExprKind, GenericParam, GenericParamKind, Item, ItemKind,
11+
NodeId, Path, Ty, TyKind,
1212
};
1313
use rustc_ast_pretty::pprust::path_segment_to_string;
1414
use rustc_data_structures::fx::FxHashSet;
@@ -1150,6 +1150,40 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
11501150
true
11511151
}
11521152

1153+
/// Given the target `ident` and `kind`, search for the similarly named associated item
1154+
/// in `self.current_trait_ref`.
1155+
crate fn find_similarly_named_assoc_item(
1156+
&mut self,
1157+
ident: Symbol,
1158+
kind: &AssocItemKind,
1159+
) -> Option<Symbol> {
1160+
let module = if let Some((module, _)) = self.current_trait_ref {
1161+
module
1162+
} else {
1163+
return None;
1164+
};
1165+
if ident == kw::Underscore {
1166+
// We do nothing for `_`.
1167+
return None;
1168+
}
1169+
1170+
let resolutions = self.r.resolutions(module);
1171+
let targets = resolutions
1172+
.borrow()
1173+
.iter()
1174+
.filter_map(|(key, res)| res.borrow().binding.map(|binding| (key, binding.res())))
1175+
.filter(|(_, res)| match (kind, res) {
1176+
(AssocItemKind::Const(..), Res::Def(DefKind::AssocConst, _)) => true,
1177+
(AssocItemKind::Fn(_), Res::Def(DefKind::AssocFn, _)) => true,
1178+
(AssocItemKind::TyAlias(..), Res::Def(DefKind::AssocTy, _)) => true,
1179+
_ => false,
1180+
})
1181+
.map(|(key, _)| key.ident.name)
1182+
.collect::<Vec<_>>();
1183+
1184+
find_best_match_for_name(&targets, ident, None)
1185+
}
1186+
11531187
fn lookup_assoc_candidate<FilterFn>(
11541188
&mut self,
11551189
ident: Ident,

‎compiler/rustc_resolve/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,11 @@ enum ResolutionError<'a> {
206206
/// parameter list.
207207
NameAlreadyUsedInParameterList(Symbol, Span),
208208
/// Error E0407: method is not a member of trait.
209-
MethodNotMemberOfTrait(Symbol, &'a str),
209+
MethodNotMemberOfTrait(Ident, &'a str, Option<Symbol>),
210210
/// Error E0437: type is not a member of trait.
211-
TypeNotMemberOfTrait(Symbol, &'a str),
211+
TypeNotMemberOfTrait(Ident, &'a str, Option<Symbol>),
212212
/// Error E0438: const is not a member of trait.
213-
ConstNotMemberOfTrait(Symbol, &'a str),
213+
ConstNotMemberOfTrait(Ident, &'a str, Option<Symbol>),
214214
/// Error E0408: variable `{}` is not bound in all patterns.
215215
VariableNotBoundInPattern(&'a BindingError),
216216
/// Error E0409: variable `{}` is bound in inconsistent ways within the same match arm.

‎compiler/rustc_typeck/src/check/callee.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
356356
}
357357
}
358358

359+
let callee_ty = self.resolve_vars_if_possible(callee_ty);
359360
let mut err = type_error_struct!(
360361
self.tcx.sess,
361362
callee_expr.span,

‎library/core/src/cell.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,11 @@ impl Clone for BorrowRef<'_> {
13031303
///
13041304
/// See the [module-level documentation](self) for more.
13051305
#[stable(feature = "rust1", since = "1.0.0")]
1306+
#[cfg_attr(
1307+
not(bootstrap),
1308+
must_not_suspend = "Holding a Ref across suspend \
1309+
points can cause BorrowErrors"
1310+
)]
13061311
pub struct Ref<'b, T: ?Sized + 'b> {
13071312
value: &'b T,
13081313
borrow: BorrowRef<'b>,
@@ -1679,6 +1684,11 @@ impl<'b> BorrowRefMut<'b> {
16791684
///
16801685
/// See the [module-level documentation](self) for more.
16811686
#[stable(feature = "rust1", since = "1.0.0")]
1687+
#[cfg_attr(
1688+
not(bootstrap),
1689+
must_not_suspend = "Holding a RefMut across suspend \
1690+
points can cause BorrowErrors"
1691+
)]
16821692
pub struct RefMut<'b, T: ?Sized + 'b> {
16831693
value: &'b mut T,
16841694
borrow: BorrowRefMut<'b>,

‎library/core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142
#![feature(link_llvm_intrinsics)]
143143
#![feature(llvm_asm)]
144144
#![feature(min_specialization)]
145+
#![cfg_attr(not(bootstrap), feature(must_not_suspend))]
145146
#![feature(negative_impls)]
146147
#![feature(never_type)]
147148
#![feature(no_core)]

‎library/std/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@
297297
#![feature(maybe_uninit_slice)]
298298
#![feature(maybe_uninit_uninit_array)]
299299
#![feature(min_specialization)]
300+
#![cfg_attr(not(bootstrap), feature(must_not_suspend))]
300301
#![feature(needs_panic_runtime)]
301302
#![feature(negative_impls)]
302303
#![feature(never_type)]

‎library/std/src/sync/mutex.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,12 @@ unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
188188
/// [`lock`]: Mutex::lock
189189
/// [`try_lock`]: Mutex::try_lock
190190
#[must_use = "if unused the Mutex will immediately unlock"]
191+
#[cfg_attr(
192+
not(bootstrap),
193+
must_not_suspend = "Holding a MutexGuard across suspend \
194+
points can cause deadlocks, delays, \
195+
and cause Futures to not implement `Send`"
196+
)]
191197
#[stable(feature = "rust1", since = "1.0.0")]
192198
pub struct MutexGuard<'a, T: ?Sized + 'a> {
193199
lock: &'a Mutex<T>,

‎library/std/src/sync/rwlock.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
9595
/// [`read`]: RwLock::read
9696
/// [`try_read`]: RwLock::try_read
9797
#[must_use = "if unused the RwLock will immediately unlock"]
98+
#[cfg_attr(
99+
not(bootstrap),
100+
must_not_suspend = "Holding a RwLockReadGuard across suspend \
101+
points can cause deadlocks, delays, \
102+
and cause Futures to not implement `Send`"
103+
)]
98104
#[stable(feature = "rust1", since = "1.0.0")]
99105
pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
100106
lock: &'a RwLock<T>,
@@ -115,6 +121,12 @@ unsafe impl<T: ?Sized + Sync> Sync for RwLockReadGuard<'_, T> {}
115121
/// [`write`]: RwLock::write
116122
/// [`try_write`]: RwLock::try_write
117123
#[must_use = "if unused the RwLock will immediately unlock"]
124+
#[cfg_attr(
125+
not(bootstrap),
126+
must_not_suspend = "Holding a RwLockWriteGuard across suspend \
127+
points can cause deadlocks, delays, \
128+
and cause Future's to not implement `Send`"
129+
)]
118130
#[stable(feature = "rust1", since = "1.0.0")]
119131
pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
120132
lock: &'a RwLock<T>,

‎library/std/src/sys/unix/thread.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,17 @@ pub fn available_concurrency() -> io::Result<NonZeroUsize> {
338338
}
339339

340340
Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) })
341+
} else if #[cfg(target_os = "haiku")] {
342+
let mut sinfo: libc::system_info = crate::mem::zeroed();
343+
let res = libc::get_system_info(&mut sinfo);
344+
345+
if res != libc::B_OK {
346+
return Err(io::Error::last_os_error());
347+
}
348+
349+
Ok(unsafe { NonZeroUsize::new_unchecked(sinfo.cpu_count as usize) })
341350
} else {
342-
// FIXME: implement on vxWorks, Redox, Haiku, l4re
351+
// FIXME: implement on vxWorks, Redox, l4re
343352
Err(io::Error::new_const(io::ErrorKind::Unsupported, &"Getting the number of hardware threads is not supported on the target platform"))
344353
}
345354
}

‎src/bootstrap/defaults/config.library.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,5 @@ bench-stage = 0
1010
incremental = true
1111

1212
[llvm]
13-
# Will download LLVM from CI if available on your platform (Linux only for now)
14-
# https://github.com/rust-lang/rust/issues/77084 tracks support for more platforms
13+
# Will download LLVM from CI if available on your platform.
1514
download-ci-llvm = "if-available"

‎src/test/run-make-fulldeps/target-specs/foo.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ trait Sized {}
1111
auto trait Freeze {}
1212

1313
#[lang = "start"]
14-
fn start(_main: *const u8, _argc: isize, _argv: *const *const u8) -> isize {
14+
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize {
1515
0
1616
}
1717

‎src/test/ui/error-codes/E0407.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ error[E0407]: method `b` is not a member of trait `Foo`
22
--> $DIR/E0407.rs:9:5
33
|
44
LL | fn b() {}
5-
| ^^^^^^^^^ not a member of trait `Foo`
5+
| ^^^-^^^^^
6+
| | |
7+
| | help: there is an associated function with a similar name: `a`
8+
| not a member of trait `Foo`
69

710
error: aborting due to previous error
811

‎src/test/ui/hygiene/assoc_item_ctxt.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ error[E0407]: method `method` is not a member of trait `Tr`
22
--> $DIR/assoc_item_ctxt.rs:35:13
33
|
44
LL | fn method() {}
5-
| ^^^^^^^^^^^^^^ not a member of trait `Tr`
5+
| ^^^------^^^^^
6+
| | |
7+
| | help: there is an associated function with a similar name: `method`
8+
| not a member of trait `Tr`
69
...
710
LL | mac_trait_impl!();
811
| ------------------ in this macro invocation

‎src/test/ui/lang-items/lang-item-generic-requirements.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
// Checks whether declaring a lang item with the wrong number
2-
// of generic arguments crashes the compiler (issue #83893, #87573, and part of #9307).
1+
// Checks that declaring a lang item with the wrong number
2+
// of generic arguments errors rather than crashing (issue #83893, #87573, part of #9307, #79559).
33

44
#![feature(lang_items, no_core)]
55
#![no_core]
6-
#![crate_type = "lib"]
76

87
#[lang = "sized"]
98
trait MySized {}
@@ -26,6 +25,14 @@ struct MyPhantomData<T, U>;
2625
//~^ ERROR parameter `T` is never used
2726
//~| ERROR parameter `U` is never used
2827

28+
// When the `start` lang item is missing generics very odd things can happen, especially when
29+
// it comes to cross-crate monomorphization
30+
#[lang = "start"]
31+
//~^ ERROR `start` language item must be applied to a function with 1 generic argument [E0718]
32+
fn start(_: *const u8, _: isize, _: *const *const u8) -> isize {
33+
0
34+
}
35+
2936
fn ice() {
3037
// Use add
3138
let r = 5;
@@ -42,3 +49,6 @@ fn ice() {
4249
// Use phantomdata
4350
let _ = MyPhantomData::<(), i32>;
4451
}
52+
53+
// use `start`
54+
fn main() {}
Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0718]: `add` language item must be applied to a trait with 1 generic argument
2-
--> $DIR/lang-item-generic-requirements.rs:11:1
2+
--> $DIR/lang-item-generic-requirements.rs:10:1
33
|
44
LL | #[lang = "add"]
55
| ^^^^^^^^^^^^^^^
66
LL | trait MyAdd<'a, T> {}
77
| ------- this trait has 2 generic arguments
88

99
error[E0718]: `drop_in_place` language item must be applied to a function with at least 1 generic argument
10-
--> $DIR/lang-item-generic-requirements.rs:15:1
10+
--> $DIR/lang-item-generic-requirements.rs:14:1
1111
|
1212
LL | #[lang = "drop_in_place"]
1313
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,24 +16,33 @@ LL | fn my_ptr_drop() {}
1616
| - this function has 0 generic arguments
1717

1818
error[E0718]: `index` language item must be applied to a trait with 1 generic argument
19-
--> $DIR/lang-item-generic-requirements.rs:19:1
19+
--> $DIR/lang-item-generic-requirements.rs:18:1
2020
|
2121
LL | #[lang = "index"]
2222
| ^^^^^^^^^^^^^^^^^
2323
LL | trait MyIndex<'a, T> {}
2424
| ------- this trait has 2 generic arguments
2525

2626
error[E0718]: `phantom_data` language item must be applied to a struct with 1 generic argument
27-
--> $DIR/lang-item-generic-requirements.rs:23:1
27+
--> $DIR/lang-item-generic-requirements.rs:22:1
2828
|
2929
LL | #[lang = "phantom_data"]
3030
| ^^^^^^^^^^^^^^^^^^^^^^^^
3131
LL |
3232
LL | struct MyPhantomData<T, U>;
3333
| ------ this struct has 2 generic arguments
3434

35+
error[E0718]: `start` language item must be applied to a function with 1 generic argument
36+
--> $DIR/lang-item-generic-requirements.rs:30:1
37+
|
38+
LL | #[lang = "start"]
39+
| ^^^^^^^^^^^^^^^^^
40+
LL |
41+
LL | fn start(_: *const u8, _: isize, _: *const *const u8) -> isize {
42+
| - this function has 0 generic arguments
43+
3544
error[E0392]: parameter `T` is never used
36-
--> $DIR/lang-item-generic-requirements.rs:25:22
45+
--> $DIR/lang-item-generic-requirements.rs:24:22
3746
|
3847
LL | struct MyPhantomData<T, U>;
3948
| ^ unused parameter
@@ -42,15 +51,15 @@ LL | struct MyPhantomData<T, U>;
4251
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
4352

4453
error[E0392]: parameter `U` is never used
45-
--> $DIR/lang-item-generic-requirements.rs:25:25
54+
--> $DIR/lang-item-generic-requirements.rs:24:25
4655
|
4756
LL | struct MyPhantomData<T, U>;
4857
| ^ unused parameter
4958
|
5059
= help: consider removing `U` or referring to it in a field
5160
= help: if you intended `U` to be a const parameter, use `const U: usize` instead
5261

53-
error: aborting due to 6 previous errors
62+
error: aborting due to 7 previous errors
5463

5564
Some errors have detailed explanations: E0392, E0718.
5665
For more information about an error, try `rustc --explain E0392`.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// edition:2018
2+
#![deny(must_not_suspend)]
3+
4+
async fn other() {}
5+
6+
pub async fn uhoh(m: std::sync::Mutex<()>) {
7+
let _guard = m.lock().unwrap(); //~ ERROR `MutexGuard` held across
8+
other().await;
9+
}
10+
11+
fn main() {
12+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error: `MutexGuard` held across a suspend point, but should not be
2+
--> $DIR/mutex.rs:7:9
3+
|
4+
LL | let _guard = m.lock().unwrap();
5+
| ^^^^^^
6+
LL | other().await;
7+
| ------------- the value is held across this suspend point
8+
|
9+
note: the lint level is defined here
10+
--> $DIR/mutex.rs:2:9
11+
|
12+
LL | #![deny(must_not_suspend)]
13+
| ^^^^^^^^^^^^^^^^
14+
note: Holding a MutexGuard across suspend points can cause deadlocks, delays, and cause Futures to not implement `Send`
15+
--> $DIR/mutex.rs:7:9
16+
|
17+
LL | let _guard = m.lock().unwrap();
18+
| ^^^^^^
19+
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
20+
--> $DIR/mutex.rs:7:9
21+
|
22+
LL | let _guard = m.lock().unwrap();
23+
| ^^^^^^
24+
25+
error: aborting due to previous error
26+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![allow(unused, nonstandard_style)]
2+
#![deny(bindings_with_variant_name)]
3+
4+
// If an enum has two different variants,
5+
// then it cannot be matched upon in a function argument.
6+
// It still gets a warning, but no suggestions.
7+
enum Foo {
8+
C,
9+
D,
10+
}
11+
12+
fn foo(C: Foo) {} //~ERROR
13+
14+
fn main() {
15+
let C = Foo::D; //~ERROR
16+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0170]: pattern binding `C` is named the same as one of the variants of the type `Foo`
2+
--> $DIR/issue-88730.rs:12:8
3+
|
4+
LL | fn foo(C: Foo) {}
5+
| ^
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/issue-88730.rs:2:9
9+
|
10+
LL | #![deny(bindings_with_variant_name)]
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error[E0170]: pattern binding `C` is named the same as one of the variants of the type `Foo`
14+
--> $DIR/issue-88730.rs:15:9
15+
|
16+
LL | let C = Foo::D;
17+
| ^
18+
19+
error: aborting due to 2 previous errors
20+
21+
For more information about this error, try `rustc --explain E0170`.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
trait Foo {
2+
type Type;
3+
4+
fn foo();
5+
fn bar();
6+
fn qux();
7+
}
8+
9+
struct A;
10+
11+
impl Foo for A {
12+
//~^ ERROR not all trait items implemented
13+
type Typ = ();
14+
//~^ ERROR type `Typ` is not a member of trait
15+
//~| HELP there is an associated type with a similar name
16+
17+
fn fooo() {}
18+
//~^ ERROR method `fooo` is not a member of trait
19+
//~| HELP there is an associated function with a similar name
20+
21+
fn barr() {}
22+
//~^ ERROR method `barr` is not a member of trait
23+
//~| HELP there is an associated function with a similar name
24+
25+
fn quux() {}
26+
//~^ ERROR method `quux` is not a member of trait
27+
//~| HELP there is an associated function with a similar name
28+
}
29+
//~^ HELP implement the missing item
30+
//~| HELP implement the missing item
31+
//~| HELP implement the missing item
32+
//~| HELP implement the missing item
33+
34+
trait Bar {
35+
const Const: i32;
36+
}
37+
38+
struct B;
39+
40+
impl Bar for B {
41+
//~^ ERROR not all trait items implemented
42+
const Cnst: i32 = 0;
43+
//~^ ERROR const `Cnst` is not a member of trait
44+
//~| HELP there is an associated constant with a similar name
45+
}
46+
//~^ HELP implement the missing item
47+
48+
fn main() {}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
error[E0437]: type `Typ` is not a member of trait `Foo`
2+
--> $DIR/suggest-trait-items.rs:13:5
3+
|
4+
LL | type Typ = ();
5+
| ^^^^^---^^^^^^
6+
| | |
7+
| | help: there is an associated type with a similar name: `Type`
8+
| not a member of trait `Foo`
9+
10+
error[E0407]: method `fooo` is not a member of trait `Foo`
11+
--> $DIR/suggest-trait-items.rs:17:5
12+
|
13+
LL | fn fooo() {}
14+
| ^^^----^^^^^
15+
| | |
16+
| | help: there is an associated function with a similar name: `foo`
17+
| not a member of trait `Foo`
18+
19+
error[E0407]: method `barr` is not a member of trait `Foo`
20+
--> $DIR/suggest-trait-items.rs:21:5
21+
|
22+
LL | fn barr() {}
23+
| ^^^----^^^^^
24+
| | |
25+
| | help: there is an associated function with a similar name: `bar`
26+
| not a member of trait `Foo`
27+
28+
error[E0407]: method `quux` is not a member of trait `Foo`
29+
--> $DIR/suggest-trait-items.rs:25:5
30+
|
31+
LL | fn quux() {}
32+
| ^^^----^^^^^
33+
| | |
34+
| | help: there is an associated function with a similar name: `qux`
35+
| not a member of trait `Foo`
36+
37+
error[E0438]: const `Cnst` is not a member of trait `Bar`
38+
--> $DIR/suggest-trait-items.rs:42:5
39+
|
40+
LL | const Cnst: i32 = 0;
41+
| ^^^^^^----^^^^^^^^^^
42+
| | |
43+
| | help: there is an associated constant with a similar name: `Const`
44+
| not a member of trait `Bar`
45+
46+
error[E0046]: not all trait items implemented, missing: `Type`, `foo`, `bar`, `qux`
47+
--> $DIR/suggest-trait-items.rs:11:1
48+
|
49+
LL | type Type;
50+
| ---------- `Type` from trait
51+
LL |
52+
LL | fn foo();
53+
| --------- `foo` from trait
54+
LL | fn bar();
55+
| --------- `bar` from trait
56+
LL | fn qux();
57+
| --------- `qux` from trait
58+
...
59+
LL | impl Foo for A {
60+
| ^^^^^^^^^^^^^^ missing `Type`, `foo`, `bar`, `qux` in implementation
61+
62+
error[E0046]: not all trait items implemented, missing: `Const`
63+
--> $DIR/suggest-trait-items.rs:40:1
64+
|
65+
LL | const Const: i32;
66+
| ----------------- `Const` from trait
67+
...
68+
LL | impl Bar for B {
69+
| ^^^^^^^^^^^^^^ missing `Const` in implementation
70+
71+
error: aborting due to 7 previous errors
72+
73+
Some errors have detailed explanations: E0046, E0407, E0437, E0438.
74+
For more information about an error, try `rustc --explain E0046`.

‎src/test/ui/typeck/call-block.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
let _ = {42}(); //~ ERROR expected function, found `{integer}`
3+
}

‎src/test/ui/typeck/call-block.stderr

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0618]: expected function, found `{integer}`
2+
--> $DIR/call-block.rs:2:13
3+
|
4+
LL | let _ = {42}();
5+
| ^^^^--
6+
| |
7+
| call expression requires function
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0618`.

‎src/tools/clippy/tests/ui/def_id_nocore.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ pub trait Copy {}
1515
pub unsafe trait Freeze {}
1616

1717
#[lang = "start"]
18-
#[start]
19-
fn start(_argc: isize, _argv: *const *const u8) -> isize {
18+
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize {
2019
0
2120
}
2221

22+
fn main() {}
23+
2324
struct A;
2425

2526
impl A {

‎src/tools/clippy/tests/ui/def_id_nocore.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: methods called `as_*` usually take `self` by reference or `self` by mutable reference
2-
--> $DIR/def_id_nocore.rs:26:19
2+
--> $DIR/def_id_nocore.rs:27:19
33
|
44
LL | pub fn as_ref(self) -> &'static str {
55
| ^^^^

0 commit comments

Comments
 (0)
This repository has been archived.