Skip to content

Rollup of 8 pull requests #89414

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

Merged
merged 22 commits into from
Oct 1, 2021
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
16c0a84
Fix ICE when `start` lang item has wrong generics
asquared31415 Sep 6, 2021
05460d0
update test
asquared31415 Sep 10, 2021
b8deb93
Add test
estebank Sep 23, 2021
072d107
Resolve infered types when complaining about unexpected call type
estebank Sep 23, 2021
0f9c349
lock types
guswynn Sep 27, 2021
4cc3297
#[feature] not required for lint result
guswynn Sep 27, 2021
5d4048b
thread: implements available_concurrency on haiku
devnexen Sep 27, 2021
cef736f
Suggest similarly named assoc items in trait impls
hkmatsumoto Sep 25, 2021
cb8e83c
ref/refmut
guswynn Sep 29, 2021
6e973f0
fix(lint): don't suggest refutable patterns to "fix" irrefutable bind
notriddle Sep 28, 2021
35f74c2
remove outdated comment
RalfJung Sep 29, 2021
268bb46
CTFE: extra assertions for Aggregate rvalues; remove unnecessarily ea…
RalfJung Sep 29, 2021
1cf905f
bootstrap: Update comment in config.library.toml.
BGR360 Sep 30, 2021
098d862
bootstrap: Update comment (again) in config.library.toml
BGR360 Sep 30, 2021
3d86aac
Rollup merge of #88782 - asquared31415:issue-79559, r=cjgillot
Manishearth Oct 1, 2021
b437be4
Rollup merge of #89202 - estebank:infer-call-type, r=oli-obk
Manishearth Oct 1, 2021
837ac87
Rollup merge of #89248 - hkmatsumoto:suggest-similarly-named-assoc-it…
Manishearth Oct 1, 2021
7b40d42
Rollup merge of #89303 - guswynn:std_suspend, r=dtolnay
Manishearth Oct 1, 2021
fccfc98
Rollup merge of #89306 - devnexen:haiku_ncpus, r=nagisa
Manishearth Oct 1, 2021
fbc67b5
Rollup merge of #89314 - notriddle:notriddle/lint-fix-enum-variant-ma…
Manishearth Oct 1, 2021
4661464
Rollup merge of #89370 - RalfJung:ctfe-aggregate-rvalue, r=oli-obk
Manishearth Oct 1, 2021
9ea439d
Rollup merge of #89392 - BGR360:master, r=jyn514
Manishearth Oct 1, 2021
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
17 changes: 9 additions & 8 deletions compiler/rustc_const_eval/src/interpret/step.rs
Original file line number Diff line number Diff line change
@@ -197,12 +197,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}

Aggregate(ref kind, ref operands) => {
// active_field_index is for union initialization.
let (dest, active_field_index) = match **kind {
mir::AggregateKind::Adt(adt_def, variant_index, _, _, active_field_index) => {
self.write_discriminant(variant_index, &dest)?;
if adt_def.is_enum() {
(self.place_downcast(&dest, variant_index)?, active_field_index)
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)
}
}
@@ -211,12 +216,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {

for (i, operand) in operands.iter().enumerate() {
let op = self.eval_operand(operand, None)?;
// Ignore zero-sized fields.
if !op.layout.is_zst() {
let field_index = active_field_index.unwrap_or(i);
let field_dest = self.place_field(&dest, field_index)?;
self.copy_op(&op, &field_dest)?;
}
let field_index = active_field_index.unwrap_or(i);
let field_dest = self.place_field(&dest, field_index)?;
self.copy_op(&op, &field_dest)?;
}
}

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

Len(place) => {
// FIXME(CTFE): don't allow computing the length of arrays in const eval
let src = self.eval_place(place)?;
let mplace = self.force_allocation(&src)?;
let len = mplace.len(self)?;
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
@@ -300,7 +300,7 @@ language_item_table! {
Oom, sym::oom, oom, Target::Fn, GenericRequirement::None;
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;

Start, sym::start, start_fn, Target::Fn, GenericRequirement::None;
Start, sym::start, start_fn, Target::Fn, GenericRequirement::Exact(1);

EhPersonality, sym::eh_personality, eh_personality, Target::Fn, GenericRequirement::None;
EhCatchTypeinfo, sym::eh_catch_typeinfo, eh_catch_typeinfo, Target::Static, GenericRequirement::None;
55 changes: 36 additions & 19 deletions compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
@@ -39,6 +39,13 @@ fn create_e0004(sess: &Session, sp: Span, error_message: String) -> DiagnosticBu
struct_span_err!(sess, sp, E0004, "{}", &error_message)
}

#[derive(PartialEq)]
enum RefutableFlag {
Irrefutable,
Refutable,
}
use RefutableFlag::*;

struct MatchVisitor<'a, 'p, 'tcx> {
tcx: TyCtxt<'tcx>,
typeck_results: &'a ty::TypeckResults<'tcx>,
@@ -73,13 +80,13 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, '_, 'tcx> {
hir::LocalSource::AssignDesugar(_) => ("destructuring assignment binding", None),
};
self.check_irrefutable(&loc.pat, msg, sp);
self.check_patterns(&loc.pat);
self.check_patterns(&loc.pat, Irrefutable);
}

fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
intravisit::walk_param(self, param);
self.check_irrefutable(&param.pat, "function argument", None);
self.check_patterns(&param.pat);
self.check_patterns(&param.pat, Irrefutable);
}
}

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

impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
fn check_patterns(&self, pat: &Pat<'_>) {
fn check_patterns(&self, pat: &Pat<'_>, rf: RefutableFlag) {
pat.walk_always(|pat| check_borrow_conflicts_in_at_patterns(self, pat));
check_for_bindings_named_same_as_variants(self, pat);
check_for_bindings_named_same_as_variants(self, pat, rf);
}

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

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

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

fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_, '_>, pat: &Pat<'_>) {
fn check_for_bindings_named_same_as_variants(
cx: &MatchVisitor<'_, '_, '_>,
pat: &Pat<'_>,
rf: RefutableFlag,
) {
pat.walk_always(|p| {
if let hir::PatKind::Binding(_, _, ident, None) = p.kind {
if let Some(ty::BindByValue(hir::Mutability::Not)) =
@@ -310,25 +321,31 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_, '_>, pat:
variant.ident == ident && variant.ctor_kind == CtorKind::Const
})
{
let variant_count = edef.variants.len();
cx.tcx.struct_span_lint_hir(
BINDINGS_WITH_VARIANT_NAME,
p.hir_id,
p.span,
|lint| {
let ty_path = cx.tcx.def_path_str(edef.did);
lint.build(&format!(
let mut err = lint.build(&format!(
"pattern binding `{}` is named the same as one \
of the variants of the type `{}`",
of the variants of the type `{}`",
ident, ty_path
))
.code(error_code!(E0170))
.span_suggestion(
p.span,
"to match on the variant, qualify the path",
format!("{}::{}", ty_path, ident),
Applicability::MachineApplicable,
)
.emit();
));
err.code(error_code!(E0170));
// If this is an irrefutable pattern, and there's > 1 variant,
// then we can't actually match on this. Applying the below
// suggestion would produce code that breaks on `check_irrefutable`.
if rf == Refutable || variant_count == 1 {
err.span_suggestion(
p.span,
"to match on the variant, qualify the path",
format!("{}::{}", ty_path, ident),
Applicability::MachineApplicable,
);
}
err.emit();
},
)
}
30 changes: 27 additions & 3 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -198,7 +198,7 @@ impl<'a> Resolver<'a> {
err.span_label(first_use_span, format!("first use of `{}`", name));
err
}
ResolutionError::MethodNotMemberOfTrait(method, trait_) => {
ResolutionError::MethodNotMemberOfTrait(method, trait_, candidate) => {
let mut err = struct_span_err!(
self.session,
span,
@@ -208,9 +208,17 @@ impl<'a> Resolver<'a> {
trait_
);
err.span_label(span, format!("not a member of trait `{}`", trait_));
if let Some(candidate) = candidate {
err.span_suggestion(
method.span,
"there is an associated function with a similar name",
candidate.to_ident_string(),
Applicability::MaybeIncorrect,
);
}
err
}
ResolutionError::TypeNotMemberOfTrait(type_, trait_) => {
ResolutionError::TypeNotMemberOfTrait(type_, trait_, candidate) => {
let mut err = struct_span_err!(
self.session,
span,
@@ -220,9 +228,17 @@ impl<'a> Resolver<'a> {
trait_
);
err.span_label(span, format!("not a member of trait `{}`", trait_));
if let Some(candidate) = candidate {
err.span_suggestion(
type_.span,
"there is an associated type with a similar name",
candidate.to_ident_string(),
Applicability::MaybeIncorrect,
);
}
err
}
ResolutionError::ConstNotMemberOfTrait(const_, trait_) => {
ResolutionError::ConstNotMemberOfTrait(const_, trait_, candidate) => {
let mut err = struct_span_err!(
self.session,
span,
@@ -232,6 +248,14 @@ impl<'a> Resolver<'a> {
trait_
);
err.span_label(span, format!("not a member of trait `{}`", trait_));
if let Some(candidate) = candidate {
err.span_suggestion(
const_.span,
"there is an associated constant with a similar name",
candidate.to_ident_string(),
Applicability::MaybeIncorrect,
);
}
err
}
ResolutionError::VariableNotBoundInPattern(binding_error) => {
28 changes: 20 additions & 8 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
@@ -1309,14 +1309,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
use crate::ResolutionError::*;
match &item.kind {
AssocItemKind::Const(_default, _ty, _expr) => {
debug!("resolve_implementation AssocItemKind::Const",);
debug!("resolve_implementation AssocItemKind::Const");
// If this is a trait impl, ensure the const
// exists in trait
this.check_trait_item(
item.ident,
&item.kind,
ValueNS,
item.span,
|n, s| ConstNotMemberOfTrait(n, s),
|i, s, c| ConstNotMemberOfTrait(i, s, c),
);

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

visit::walk_assoc_item(
@@ -1366,6 +1369,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
_,
_,
)) => {
debug!("resolve_implementation AssocItemKind::TyAlias");
// We also need a new scope for the impl item type parameters.
this.with_generic_param_rib(
generics,
@@ -1375,9 +1379,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
// exists in trait
this.check_trait_item(
item.ident,
&item.kind,
TypeNS,
item.span,
|n, s| TypeNotMemberOfTrait(n, s),
|i, s, c| TypeNotMemberOfTrait(i, s, c),
);

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

fn check_trait_item<F>(&mut self, ident: Ident, ns: Namespace, span: Span, err: F)
where
F: FnOnce(Symbol, &str) -> ResolutionError<'_>,
fn check_trait_item<F>(
&mut self,
ident: Ident,
kind: &AssocItemKind,
ns: Namespace,
span: Span,
err: F,
) where
F: FnOnce(Ident, &str, Option<Symbol>) -> ResolutionError<'_>,
{
// If there is a TraitRef in scope for an impl, then the method must be in the
// trait.
@@ -1420,8 +1431,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
)
.is_err()
{
let candidate = self.find_similarly_named_assoc_item(ident.name, kind);
let path = &self.current_trait_ref.as_ref().unwrap().1.path;
self.report_error(span, err(ident.name, &path_names_to_string(path)));
self.report_error(span, err(ident, &path_names_to_string(path), candidate));
}
}
}
38 changes: 36 additions & 2 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -7,8 +7,8 @@ use crate::{PathResult, PathSource, Segment};

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

/// Given the target `ident` and `kind`, search for the similarly named associated item
/// in `self.current_trait_ref`.
crate fn find_similarly_named_assoc_item(
&mut self,
ident: Symbol,
kind: &AssocItemKind,
) -> Option<Symbol> {
let module = if let Some((module, _)) = self.current_trait_ref {
module
} else {
return None;
};
if ident == kw::Underscore {
// We do nothing for `_`.
return None;
}

let resolutions = self.r.resolutions(module);
let targets = resolutions
.borrow()
.iter()
.filter_map(|(key, res)| res.borrow().binding.map(|binding| (key, binding.res())))
.filter(|(_, res)| match (kind, res) {
(AssocItemKind::Const(..), Res::Def(DefKind::AssocConst, _)) => true,
(AssocItemKind::Fn(_), Res::Def(DefKind::AssocFn, _)) => true,
(AssocItemKind::TyAlias(..), Res::Def(DefKind::AssocTy, _)) => true,
_ => false,
})
.map(|(key, _)| key.ident.name)
.collect::<Vec<_>>();

find_best_match_for_name(&targets, ident, None)
}

fn lookup_assoc_candidate<FilterFn>(
&mut self,
ident: Ident,
6 changes: 3 additions & 3 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
@@ -206,11 +206,11 @@ enum ResolutionError<'a> {
/// parameter list.
NameAlreadyUsedInParameterList(Symbol, Span),
/// Error E0407: method is not a member of trait.
MethodNotMemberOfTrait(Symbol, &'a str),
MethodNotMemberOfTrait(Ident, &'a str, Option<Symbol>),
/// Error E0437: type is not a member of trait.
TypeNotMemberOfTrait(Symbol, &'a str),
TypeNotMemberOfTrait(Ident, &'a str, Option<Symbol>),
/// Error E0438: const is not a member of trait.
ConstNotMemberOfTrait(Symbol, &'a str),
ConstNotMemberOfTrait(Ident, &'a str, Option<Symbol>),
/// Error E0408: variable `{}` is not bound in all patterns.
VariableNotBoundInPattern(&'a BindingError),
/// Error E0409: variable `{}` is bound in inconsistent ways within the same match arm.
1 change: 1 addition & 0 deletions compiler/rustc_typeck/src/check/callee.rs
Original file line number Diff line number Diff line change
@@ -356,6 +356,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

let callee_ty = self.resolve_vars_if_possible(callee_ty);
let mut err = type_error_struct!(
self.tcx.sess,
callee_expr.span,
10 changes: 10 additions & 0 deletions library/core/src/cell.rs
Original file line number Diff line number Diff line change
@@ -1303,6 +1303,11 @@ impl Clone for BorrowRef<'_> {
///
/// See the [module-level documentation](self) for more.
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(
not(bootstrap),
must_not_suspend = "Holding a Ref across suspend \
points can cause BorrowErrors"
)]
pub struct Ref<'b, T: ?Sized + 'b> {
value: &'b T,
borrow: BorrowRef<'b>,
@@ -1679,6 +1684,11 @@ impl<'b> BorrowRefMut<'b> {
///
/// See the [module-level documentation](self) for more.
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(
not(bootstrap),
must_not_suspend = "Holding a RefMut across suspend \
points can cause BorrowErrors"
)]
pub struct RefMut<'b, T: ?Sized + 'b> {
value: &'b mut T,
borrow: BorrowRefMut<'b>,
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -142,6 +142,7 @@
#![feature(link_llvm_intrinsics)]
#![feature(llvm_asm)]
#![feature(min_specialization)]
#![cfg_attr(not(bootstrap), feature(must_not_suspend))]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(no_core)]
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
@@ -297,6 +297,7 @@
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array)]
#![feature(min_specialization)]
#![cfg_attr(not(bootstrap), feature(must_not_suspend))]
#![feature(needs_panic_runtime)]
#![feature(negative_impls)]
#![feature(never_type)]
6 changes: 6 additions & 0 deletions library/std/src/sync/mutex.rs
Original file line number Diff line number Diff line change
@@ -188,6 +188,12 @@ unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
/// [`lock`]: Mutex::lock
/// [`try_lock`]: Mutex::try_lock
#[must_use = "if unused the Mutex will immediately unlock"]
#[cfg_attr(
not(bootstrap),
must_not_suspend = "Holding a MutexGuard across suspend \
points can cause deadlocks, delays, \
and cause Futures to not implement `Send`"
)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct MutexGuard<'a, T: ?Sized + 'a> {
lock: &'a Mutex<T>,
12 changes: 12 additions & 0 deletions library/std/src/sync/rwlock.rs
Original file line number Diff line number Diff line change
@@ -95,6 +95,12 @@ unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
/// [`read`]: RwLock::read
/// [`try_read`]: RwLock::try_read
#[must_use = "if unused the RwLock will immediately unlock"]
#[cfg_attr(
not(bootstrap),
must_not_suspend = "Holding a RwLockReadGuard across suspend \
points can cause deadlocks, delays, \
and cause Futures to not implement `Send`"
)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
lock: &'a RwLock<T>,
@@ -115,6 +121,12 @@ unsafe impl<T: ?Sized + Sync> Sync for RwLockReadGuard<'_, T> {}
/// [`write`]: RwLock::write
/// [`try_write`]: RwLock::try_write
#[must_use = "if unused the RwLock will immediately unlock"]
#[cfg_attr(
not(bootstrap),
must_not_suspend = "Holding a RwLockWriteGuard across suspend \
points can cause deadlocks, delays, \
and cause Future's to not implement `Send`"
)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
lock: &'a RwLock<T>,
11 changes: 10 additions & 1 deletion library/std/src/sys/unix/thread.rs
Original file line number Diff line number Diff line change
@@ -338,8 +338,17 @@ pub fn available_concurrency() -> io::Result<NonZeroUsize> {
}

Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) })
} else if #[cfg(target_os = "haiku")] {
let mut sinfo: libc::system_info = crate::mem::zeroed();
let res = libc::get_system_info(&mut sinfo);

if res != libc::B_OK {
return Err(io::Error::last_os_error());
}

Ok(unsafe { NonZeroUsize::new_unchecked(sinfo.cpu_count as usize) })
} else {
// FIXME: implement on vxWorks, Redox, Haiku, l4re
// FIXME: implement on vxWorks, Redox, l4re
Err(io::Error::new_const(io::ErrorKind::Unsupported, &"Getting the number of hardware threads is not supported on the target platform"))
}
}
3 changes: 1 addition & 2 deletions src/bootstrap/defaults/config.library.toml
Original file line number Diff line number Diff line change
@@ -10,6 +10,5 @@ bench-stage = 0
incremental = true

[llvm]
# Will download LLVM from CI if available on your platform (Linux only for now)
# https://github.com/rust-lang/rust/issues/77084 tracks support for more platforms
# Will download LLVM from CI if available on your platform.
download-ci-llvm = "if-available"
2 changes: 1 addition & 1 deletion src/test/run-make-fulldeps/target-specs/foo.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ trait Sized {}
auto trait Freeze {}

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

5 changes: 4 additions & 1 deletion src/test/ui/error-codes/E0407.stderr
Original file line number Diff line number Diff line change
@@ -2,7 +2,10 @@ error[E0407]: method `b` is not a member of trait `Foo`
--> $DIR/E0407.rs:9:5
|
LL | fn b() {}
| ^^^^^^^^^ not a member of trait `Foo`
| ^^^-^^^^^
| | |
| | help: there is an associated function with a similar name: `a`
| not a member of trait `Foo`

error: aborting due to previous error

5 changes: 4 additions & 1 deletion src/test/ui/hygiene/assoc_item_ctxt.stderr
Original file line number Diff line number Diff line change
@@ -2,7 +2,10 @@ error[E0407]: method `method` is not a member of trait `Tr`
--> $DIR/assoc_item_ctxt.rs:35:13
|
LL | fn method() {}
| ^^^^^^^^^^^^^^ not a member of trait `Tr`
| ^^^------^^^^^
| | |
| | help: there is an associated function with a similar name: `method`
| not a member of trait `Tr`
...
LL | mac_trait_impl!();
| ------------------ in this macro invocation
16 changes: 13 additions & 3 deletions src/test/ui/lang-items/lang-item-generic-requirements.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// Checks whether declaring a lang item with the wrong number
// of generic arguments crashes the compiler (issue #83893, #87573, and part of #9307).
// Checks that declaring a lang item with the wrong number
// of generic arguments errors rather than crashing (issue #83893, #87573, part of #9307, #79559).

#![feature(lang_items, no_core)]
#![no_core]
#![crate_type = "lib"]

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

// When the `start` lang item is missing generics very odd things can happen, especially when
// it comes to cross-crate monomorphization
#[lang = "start"]
//~^ ERROR `start` language item must be applied to a function with 1 generic argument [E0718]
fn start(_: *const u8, _: isize, _: *const *const u8) -> isize {
0
}

fn ice() {
// Use add
let r = 5;
@@ -42,3 +49,6 @@ fn ice() {
// Use phantomdata
let _ = MyPhantomData::<(), i32>;
}

// use `start`
fn main() {}
23 changes: 16 additions & 7 deletions src/test/ui/lang-items/lang-item-generic-requirements.stderr
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
error[E0718]: `add` language item must be applied to a trait with 1 generic argument
--> $DIR/lang-item-generic-requirements.rs:11:1
--> $DIR/lang-item-generic-requirements.rs:10:1
|
LL | #[lang = "add"]
| ^^^^^^^^^^^^^^^
LL | trait MyAdd<'a, T> {}
| ------- this trait has 2 generic arguments

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

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

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

error[E0718]: `start` language item must be applied to a function with 1 generic argument
--> $DIR/lang-item-generic-requirements.rs:30:1
|
LL | #[lang = "start"]
| ^^^^^^^^^^^^^^^^^
LL |
LL | fn start(_: *const u8, _: isize, _: *const *const u8) -> isize {
| - this function has 0 generic arguments

error[E0392]: parameter `T` is never used
--> $DIR/lang-item-generic-requirements.rs:25:22
--> $DIR/lang-item-generic-requirements.rs:24:22
|
LL | struct MyPhantomData<T, U>;
| ^ unused parameter
@@ -42,15 +51,15 @@ LL | struct MyPhantomData<T, U>;
= help: if you intended `T` to be a const parameter, use `const T: usize` instead

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

error: aborting due to 6 previous errors
error: aborting due to 7 previous errors

Some errors have detailed explanations: E0392, E0718.
For more information about an error, try `rustc --explain E0392`.
12 changes: 12 additions & 0 deletions src/test/ui/lint/must_not_suspend/mutex.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// edition:2018
#![deny(must_not_suspend)]

async fn other() {}

pub async fn uhoh(m: std::sync::Mutex<()>) {
let _guard = m.lock().unwrap(); //~ ERROR `MutexGuard` held across
other().await;
}

fn main() {
}
26 changes: 26 additions & 0 deletions src/test/ui/lint/must_not_suspend/mutex.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error: `MutexGuard` held across a suspend point, but should not be
--> $DIR/mutex.rs:7:9
|
LL | let _guard = m.lock().unwrap();
| ^^^^^^
LL | other().await;
| ------------- the value is held across this suspend point
|
note: the lint level is defined here
--> $DIR/mutex.rs:2:9
|
LL | #![deny(must_not_suspend)]
| ^^^^^^^^^^^^^^^^
note: Holding a MutexGuard across suspend points can cause deadlocks, delays, and cause Futures to not implement `Send`
--> $DIR/mutex.rs:7:9
|
LL | let _guard = m.lock().unwrap();
| ^^^^^^
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
--> $DIR/mutex.rs:7:9
|
LL | let _guard = m.lock().unwrap();
| ^^^^^^

error: aborting due to previous error

16 changes: 16 additions & 0 deletions src/test/ui/suggestions/issue-88730.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#![allow(unused, nonstandard_style)]
#![deny(bindings_with_variant_name)]

// If an enum has two different variants,
// then it cannot be matched upon in a function argument.
// It still gets a warning, but no suggestions.
enum Foo {
C,
D,
}

fn foo(C: Foo) {} //~ERROR

fn main() {
let C = Foo::D; //~ERROR
}
21 changes: 21 additions & 0 deletions src/test/ui/suggestions/issue-88730.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0170]: pattern binding `C` is named the same as one of the variants of the type `Foo`
--> $DIR/issue-88730.rs:12:8
|
LL | fn foo(C: Foo) {}
| ^
|
note: the lint level is defined here
--> $DIR/issue-88730.rs:2:9
|
LL | #![deny(bindings_with_variant_name)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0170]: pattern binding `C` is named the same as one of the variants of the type `Foo`
--> $DIR/issue-88730.rs:15:9
|
LL | let C = Foo::D;
| ^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0170`.
48 changes: 48 additions & 0 deletions src/test/ui/suggestions/suggest-trait-items.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
trait Foo {
type Type;

fn foo();
fn bar();
fn qux();
}

struct A;

impl Foo for A {
//~^ ERROR not all trait items implemented
type Typ = ();
//~^ ERROR type `Typ` is not a member of trait
//~| HELP there is an associated type with a similar name

fn fooo() {}
//~^ ERROR method `fooo` is not a member of trait
//~| HELP there is an associated function with a similar name

fn barr() {}
//~^ ERROR method `barr` is not a member of trait
//~| HELP there is an associated function with a similar name

fn quux() {}
//~^ ERROR method `quux` is not a member of trait
//~| HELP there is an associated function with a similar name
}
//~^ HELP implement the missing item
//~| HELP implement the missing item
//~| HELP implement the missing item
//~| HELP implement the missing item

trait Bar {
const Const: i32;
}

struct B;

impl Bar for B {
//~^ ERROR not all trait items implemented
const Cnst: i32 = 0;
//~^ ERROR const `Cnst` is not a member of trait
//~| HELP there is an associated constant with a similar name
}
//~^ HELP implement the missing item

fn main() {}
74 changes: 74 additions & 0 deletions src/test/ui/suggestions/suggest-trait-items.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
error[E0437]: type `Typ` is not a member of trait `Foo`
--> $DIR/suggest-trait-items.rs:13:5
|
LL | type Typ = ();
| ^^^^^---^^^^^^
| | |
| | help: there is an associated type with a similar name: `Type`
| not a member of trait `Foo`

error[E0407]: method `fooo` is not a member of trait `Foo`
--> $DIR/suggest-trait-items.rs:17:5
|
LL | fn fooo() {}
| ^^^----^^^^^
| | |
| | help: there is an associated function with a similar name: `foo`
| not a member of trait `Foo`

error[E0407]: method `barr` is not a member of trait `Foo`
--> $DIR/suggest-trait-items.rs:21:5
|
LL | fn barr() {}
| ^^^----^^^^^
| | |
| | help: there is an associated function with a similar name: `bar`
| not a member of trait `Foo`

error[E0407]: method `quux` is not a member of trait `Foo`
--> $DIR/suggest-trait-items.rs:25:5
|
LL | fn quux() {}
| ^^^----^^^^^
| | |
| | help: there is an associated function with a similar name: `qux`
| not a member of trait `Foo`

error[E0438]: const `Cnst` is not a member of trait `Bar`
--> $DIR/suggest-trait-items.rs:42:5
|
LL | const Cnst: i32 = 0;
| ^^^^^^----^^^^^^^^^^
| | |
| | help: there is an associated constant with a similar name: `Const`
| not a member of trait `Bar`

error[E0046]: not all trait items implemented, missing: `Type`, `foo`, `bar`, `qux`
--> $DIR/suggest-trait-items.rs:11:1
|
LL | type Type;
| ---------- `Type` from trait
LL |
LL | fn foo();
| --------- `foo` from trait
LL | fn bar();
| --------- `bar` from trait
LL | fn qux();
| --------- `qux` from trait
...
LL | impl Foo for A {
| ^^^^^^^^^^^^^^ missing `Type`, `foo`, `bar`, `qux` in implementation

error[E0046]: not all trait items implemented, missing: `Const`
--> $DIR/suggest-trait-items.rs:40:1
|
LL | const Const: i32;
| ----------------- `Const` from trait
...
LL | impl Bar for B {
| ^^^^^^^^^^^^^^ missing `Const` in implementation

error: aborting due to 7 previous errors

Some errors have detailed explanations: E0046, E0407, E0437, E0438.
For more information about an error, try `rustc --explain E0046`.
3 changes: 3 additions & 0 deletions src/test/ui/typeck/call-block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
let _ = {42}(); //~ ERROR expected function, found `{integer}`
}
11 changes: 11 additions & 0 deletions src/test/ui/typeck/call-block.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0618]: expected function, found `{integer}`
--> $DIR/call-block.rs:2:13
|
LL | let _ = {42}();
| ^^^^--
| |
| call expression requires function

error: aborting due to previous error

For more information about this error, try `rustc --explain E0618`.
5 changes: 3 additions & 2 deletions src/tools/clippy/tests/ui/def_id_nocore.rs
Original file line number Diff line number Diff line change
@@ -15,11 +15,12 @@ pub trait Copy {}
pub unsafe trait Freeze {}

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

fn main() {}

struct A;

impl A {
2 changes: 1 addition & 1 deletion src/tools/clippy/tests/ui/def_id_nocore.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: methods called `as_*` usually take `self` by reference or `self` by mutable reference
--> $DIR/def_id_nocore.rs:26:19
--> $DIR/def_id_nocore.rs:27:19
|
LL | pub fn as_ref(self) -> &'static str {
| ^^^^