Auto merge of #123762 - fmease:rollup-jdfx54z, r=fmease
Rollup of 8 pull requests Successful merges: - #122470 (`f16` and `f128` step 4: basic library support) - #122954 (Be more specific when flagging imports as redundant due to the extern prelude) - #123314 (Skip `unused_parens` report for `Paren(Path(..))` in macro.) - #123360 (Document restricted_std) - #123661 (Stabilize `cstr_count_bytes`) - #123703 (Use `fn` ptr signature instead of `{closure@..}` in infer error) - #123756 (clean up docs for `File::sync_*`) - #123761 (Use `suggest_impl_trait` in return type suggestion on type error) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
4435924bb6
70 changed files with 872 additions and 186 deletions
|
@ -30,7 +30,7 @@ use rustc_middle::query::Providers;
|
|||
use rustc_middle::ty::util::{Discr, IntTypeExt};
|
||||
use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, ToPredicate, Ty, TyCtxt};
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_target::abi::FieldIdx;
|
||||
use rustc_target::spec::abi;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
|
@ -1383,7 +1383,9 @@ fn infer_return_ty_for_fn_sig<'tcx>(
|
|||
Applicability::MachineApplicable,
|
||||
);
|
||||
should_recover = true;
|
||||
} else if let Some(sugg) = suggest_impl_trait(tcx, ret_ty, ty.span, def_id) {
|
||||
} else if let Some(sugg) =
|
||||
suggest_impl_trait(&tcx.infer_ctxt().build(), tcx.param_env(def_id), ret_ty)
|
||||
{
|
||||
diag.span_suggestion(
|
||||
ty.span,
|
||||
"replace with an appropriate return type",
|
||||
|
@ -1426,11 +1428,10 @@ fn infer_return_ty_for_fn_sig<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
fn suggest_impl_trait<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
pub fn suggest_impl_trait<'tcx>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
ret_ty: Ty<'tcx>,
|
||||
span: Span,
|
||||
def_id: LocalDefId,
|
||||
) -> Option<String> {
|
||||
let format_as_assoc: fn(_, _, _, _, _) -> _ =
|
||||
|tcx: TyCtxt<'tcx>,
|
||||
|
@ -1464,24 +1465,28 @@ fn suggest_impl_trait<'tcx>(
|
|||
|
||||
for (trait_def_id, assoc_item_def_id, formatter) in [
|
||||
(
|
||||
tcx.get_diagnostic_item(sym::Iterator),
|
||||
tcx.get_diagnostic_item(sym::IteratorItem),
|
||||
infcx.tcx.get_diagnostic_item(sym::Iterator),
|
||||
infcx.tcx.get_diagnostic_item(sym::IteratorItem),
|
||||
format_as_assoc,
|
||||
),
|
||||
(
|
||||
tcx.lang_items().future_trait(),
|
||||
tcx.get_diagnostic_item(sym::FutureOutput),
|
||||
infcx.tcx.lang_items().future_trait(),
|
||||
infcx.tcx.get_diagnostic_item(sym::FutureOutput),
|
||||
format_as_assoc,
|
||||
),
|
||||
(tcx.lang_items().fn_trait(), tcx.lang_items().fn_once_output(), format_as_parenthesized),
|
||||
(
|
||||
tcx.lang_items().fn_mut_trait(),
|
||||
tcx.lang_items().fn_once_output(),
|
||||
infcx.tcx.lang_items().fn_trait(),
|
||||
infcx.tcx.lang_items().fn_once_output(),
|
||||
format_as_parenthesized,
|
||||
),
|
||||
(
|
||||
tcx.lang_items().fn_once_trait(),
|
||||
tcx.lang_items().fn_once_output(),
|
||||
infcx.tcx.lang_items().fn_mut_trait(),
|
||||
infcx.tcx.lang_items().fn_once_output(),
|
||||
format_as_parenthesized,
|
||||
),
|
||||
(
|
||||
infcx.tcx.lang_items().fn_once_trait(),
|
||||
infcx.tcx.lang_items().fn_once_output(),
|
||||
format_as_parenthesized,
|
||||
),
|
||||
] {
|
||||
|
@ -1491,36 +1496,45 @@ fn suggest_impl_trait<'tcx>(
|
|||
let Some(assoc_item_def_id) = assoc_item_def_id else {
|
||||
continue;
|
||||
};
|
||||
if tcx.def_kind(assoc_item_def_id) != DefKind::AssocTy {
|
||||
if infcx.tcx.def_kind(assoc_item_def_id) != DefKind::AssocTy {
|
||||
continue;
|
||||
}
|
||||
let param_env = tcx.param_env(def_id);
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
let args = ty::GenericArgs::for_item(tcx, trait_def_id, |param, _| {
|
||||
if param.index == 0 { ret_ty.into() } else { infcx.var_for_def(span, param) }
|
||||
let sugg = infcx.probe(|_| {
|
||||
let args = ty::GenericArgs::for_item(infcx.tcx, trait_def_id, |param, _| {
|
||||
if param.index == 0 { ret_ty.into() } else { infcx.var_for_def(DUMMY_SP, param) }
|
||||
});
|
||||
if !infcx
|
||||
.type_implements_trait(trait_def_id, args, param_env)
|
||||
.must_apply_modulo_regions()
|
||||
{
|
||||
return None;
|
||||
}
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
let item_ty = ocx.normalize(
|
||||
&ObligationCause::dummy(),
|
||||
param_env,
|
||||
Ty::new_projection(infcx.tcx, assoc_item_def_id, args),
|
||||
);
|
||||
// FIXME(compiler-errors): We may benefit from resolving regions here.
|
||||
if ocx.select_where_possible().is_empty()
|
||||
&& let item_ty = infcx.resolve_vars_if_possible(item_ty)
|
||||
&& let Some(item_ty) = item_ty.make_suggestable(infcx.tcx, false, None)
|
||||
&& let Some(sugg) = formatter(
|
||||
infcx.tcx,
|
||||
infcx.resolve_vars_if_possible(args),
|
||||
trait_def_id,
|
||||
assoc_item_def_id,
|
||||
item_ty,
|
||||
)
|
||||
{
|
||||
return Some(sugg);
|
||||
}
|
||||
|
||||
None
|
||||
});
|
||||
if !infcx.type_implements_trait(trait_def_id, args, param_env).must_apply_modulo_regions() {
|
||||
continue;
|
||||
}
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
let item_ty = ocx.normalize(
|
||||
&ObligationCause::misc(span, def_id),
|
||||
param_env,
|
||||
Ty::new_projection(tcx, assoc_item_def_id, args),
|
||||
);
|
||||
// FIXME(compiler-errors): We may benefit from resolving regions here.
|
||||
if ocx.select_where_possible().is_empty()
|
||||
&& let item_ty = infcx.resolve_vars_if_possible(item_ty)
|
||||
&& let Some(item_ty) = item_ty.make_suggestable(tcx, false, None)
|
||||
&& let Some(sugg) = formatter(
|
||||
tcx,
|
||||
infcx.resolve_vars_if_possible(args),
|
||||
trait_def_id,
|
||||
assoc_item_def_id,
|
||||
item_ty,
|
||||
)
|
||||
{
|
||||
return Some(sugg);
|
||||
|
||||
if sugg.is_some() {
|
||||
return sugg;
|
||||
}
|
||||
}
|
||||
None
|
||||
|
|
|
@ -20,6 +20,7 @@ use rustc_hir::{
|
|||
CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, GenericBound, HirId, Node,
|
||||
Path, QPath, Stmt, StmtKind, TyKind, WherePredicate,
|
||||
};
|
||||
use rustc_hir_analysis::collect::suggest_impl_trait;
|
||||
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
|
||||
use rustc_infer::traits::{self};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
|
@ -814,17 +815,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
errors::AddReturnTypeSuggestion::Add { span, found: found.to_string() },
|
||||
);
|
||||
return true;
|
||||
} else if let ty::Closure(_, args) = found.kind()
|
||||
// FIXME(compiler-errors): Get better at printing binders...
|
||||
&& let closure = args.as_closure()
|
||||
&& closure.sig().is_suggestable(self.tcx, false)
|
||||
{
|
||||
} else if let Some(sugg) = suggest_impl_trait(self, self.param_env, found) {
|
||||
err.subdiagnostic(
|
||||
self.dcx(),
|
||||
errors::AddReturnTypeSuggestion::Add {
|
||||
span,
|
||||
found: closure.print_as_impl_trait().to_string(),
|
||||
},
|
||||
errors::AddReturnTypeSuggestion::Add { span, found: sugg },
|
||||
);
|
||||
return true;
|
||||
} else {
|
||||
|
|
|
@ -144,6 +144,9 @@ infer_fps_items_are_distinct = fn items are distinct from fn pointers
|
|||
infer_fps_remove_ref = consider removing the reference
|
||||
infer_fps_use_ref = consider using a reference
|
||||
infer_fulfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime
|
||||
|
||||
infer_full_type_written = the full type name has been written to '{$path}'
|
||||
|
||||
infer_implicit_static_lifetime_note = this has an implicit `'static` lifetime requirement
|
||||
infer_implicit_static_lifetime_suggestion = consider relaxing the implicit `'static` requirement
|
||||
infer_label_bad = {$bad_kind ->
|
||||
|
|
|
@ -18,6 +18,8 @@ use crate::infer::error_reporting::{
|
|||
ObligationCauseAsDiagArg,
|
||||
};
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub mod note_and_explain;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -47,6 +49,9 @@ pub struct AnnotationRequired<'a> {
|
|||
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
|
||||
#[subdiagnostic]
|
||||
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
|
||||
#[note(infer_full_type_written)]
|
||||
pub was_written: Option<()>,
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
||||
// Copy of `AnnotationRequired` for E0283
|
||||
|
@ -65,6 +70,9 @@ pub struct AmbiguousImpl<'a> {
|
|||
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
|
||||
#[subdiagnostic]
|
||||
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
|
||||
#[note(infer_full_type_written)]
|
||||
pub was_written: Option<()>,
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
||||
// Copy of `AnnotationRequired` for E0284
|
||||
|
@ -83,6 +91,9 @@ pub struct AmbiguousReturn<'a> {
|
|||
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
|
||||
#[subdiagnostic]
|
||||
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
|
||||
#[note(infer_full_type_written)]
|
||||
pub was_written: Option<()>,
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
||||
// Used when a better one isn't available
|
||||
|
|
|
@ -18,13 +18,15 @@ use rustc_middle::infer::unify_key::{
|
|||
};
|
||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
|
||||
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
|
||||
use rustc_middle::ty::{self, InferConst};
|
||||
use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgsRef};
|
||||
use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeckResults};
|
||||
use rustc_middle::ty::{
|
||||
self, GenericArg, GenericArgKind, GenericArgsRef, InferConst, IsSuggestable, Ty, TyCtxt,
|
||||
TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults,
|
||||
};
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::{BytePos, Span};
|
||||
use rustc_span::{BytePos, Span, DUMMY_SP};
|
||||
use std::borrow::Cow;
|
||||
use std::iter;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub enum TypeAnnotationNeeded {
|
||||
/// ```compile_fail,E0282
|
||||
|
@ -153,6 +155,29 @@ impl UnderspecifiedArgKind {
|
|||
}
|
||||
}
|
||||
|
||||
struct ClosureEraser<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ClosureEraser<'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match ty.kind() {
|
||||
ty::Closure(_, args) => {
|
||||
let closure_sig = args.as_closure().sig();
|
||||
Ty::new_fn_ptr(
|
||||
self.tcx,
|
||||
self.tcx.signature_unclosure(closure_sig, hir::Unsafety::Normal),
|
||||
)
|
||||
}
|
||||
_ => ty.super_fold_with(self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinter<'a, 'tcx> {
|
||||
let mut printer = FmtPrinter::new(infcx.tcx, ns);
|
||||
let ty_getter = move |ty_vid| {
|
||||
|
@ -209,6 +234,10 @@ fn ty_to_string<'tcx>(
|
|||
) -> String {
|
||||
let mut printer = fmt_printer(infcx, Namespace::TypeNS);
|
||||
let ty = infcx.resolve_vars_if_possible(ty);
|
||||
// We use `fn` ptr syntax for closures, but this only works when the closure
|
||||
// does not capture anything.
|
||||
let ty = ty.fold_with(&mut ClosureEraser { tcx: infcx.tcx });
|
||||
|
||||
match (ty.kind(), called_method_def_id) {
|
||||
// We don't want the regular output for `fn`s because it includes its path in
|
||||
// invalid pseudo-syntax, we want the `fn`-pointer output instead.
|
||||
|
@ -223,11 +252,6 @@ fn ty_to_string<'tcx>(
|
|||
"Vec<_>".to_string()
|
||||
}
|
||||
_ if ty.is_ty_or_numeric_infer() => "/* Type */".to_string(),
|
||||
// FIXME: The same thing for closures, but this only works when the closure
|
||||
// does not capture anything.
|
||||
//
|
||||
// We do have to hide the `extern "rust-call"` ABI in that case though,
|
||||
// which is too much of a bother for now.
|
||||
_ => {
|
||||
ty.print(&mut printer).unwrap();
|
||||
printer.into_buffer()
|
||||
|
@ -387,6 +411,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
infer_subdiags,
|
||||
multi_suggestions,
|
||||
bad_label,
|
||||
was_written: None,
|
||||
path: Default::default(),
|
||||
}),
|
||||
TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
|
||||
span,
|
||||
|
@ -396,6 +422,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
infer_subdiags,
|
||||
multi_suggestions,
|
||||
bad_label,
|
||||
was_written: None,
|
||||
path: Default::default(),
|
||||
}),
|
||||
TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn {
|
||||
span,
|
||||
|
@ -405,6 +433,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
infer_subdiags,
|
||||
multi_suggestions,
|
||||
bad_label,
|
||||
was_written: None,
|
||||
path: Default::default(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
@ -442,7 +472,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
return self.bad_inference_failure_err(failure_span, arg_data, error_code);
|
||||
};
|
||||
|
||||
let (source_kind, name) = kind.ty_localized_msg(self);
|
||||
let (source_kind, name, path) = kind.ty_localized_msg(self);
|
||||
let failure_span = if should_label_span && !failure_span.overlaps(span) {
|
||||
Some(failure_span)
|
||||
} else {
|
||||
|
@ -518,7 +548,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
|
||||
GenericArgKind::Type(_) => self
|
||||
.next_ty_var(TypeVariableOrigin {
|
||||
span: rustc_span::DUMMY_SP,
|
||||
span: DUMMY_SP,
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
})
|
||||
.into(),
|
||||
|
@ -526,7 +556,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
.next_const_var(
|
||||
arg.ty(),
|
||||
ConstVariableOrigin {
|
||||
span: rustc_span::DUMMY_SP,
|
||||
span: DUMMY_SP,
|
||||
kind: ConstVariableOriginKind::MiscVariable,
|
||||
},
|
||||
)
|
||||
|
@ -547,7 +577,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
}
|
||||
InferSourceKind::FullyQualifiedMethodCall { receiver, successor, args, def_id } => {
|
||||
let placeholder = Some(self.next_ty_var(TypeVariableOrigin {
|
||||
span: rustc_span::DUMMY_SP,
|
||||
span: DUMMY_SP,
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
}));
|
||||
if let Some(args) = args.make_suggestable(self.infcx.tcx, true, placeholder) {
|
||||
|
@ -584,7 +614,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
}
|
||||
InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => {
|
||||
let placeholder = Some(self.next_ty_var(TypeVariableOrigin {
|
||||
span: rustc_span::DUMMY_SP,
|
||||
span: DUMMY_SP,
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
}));
|
||||
if let Some(ty) = ty.make_suggestable(self.infcx.tcx, true, placeholder) {
|
||||
|
@ -606,6 +636,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
infer_subdiags,
|
||||
multi_suggestions,
|
||||
bad_label: None,
|
||||
was_written: path.as_ref().map(|_| ()),
|
||||
path: path.unwrap_or_default(),
|
||||
}),
|
||||
TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
|
||||
span,
|
||||
|
@ -615,6 +647,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
infer_subdiags,
|
||||
multi_suggestions,
|
||||
bad_label: None,
|
||||
was_written: path.as_ref().map(|_| ()),
|
||||
path: path.unwrap_or_default(),
|
||||
}),
|
||||
TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn {
|
||||
span,
|
||||
|
@ -624,6 +658,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
infer_subdiags,
|
||||
multi_suggestions,
|
||||
bad_label: None,
|
||||
was_written: path.as_ref().map(|_| ()),
|
||||
path: path.unwrap_or_default(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
@ -688,22 +724,23 @@ impl<'tcx> InferSource<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> InferSourceKind<'tcx> {
|
||||
fn ty_localized_msg(&self, infcx: &InferCtxt<'tcx>) -> (&'static str, String) {
|
||||
fn ty_localized_msg(&self, infcx: &InferCtxt<'tcx>) -> (&'static str, String, Option<PathBuf>) {
|
||||
let mut path = None;
|
||||
match *self {
|
||||
InferSourceKind::LetBinding { ty, .. }
|
||||
| InferSourceKind::ClosureArg { ty, .. }
|
||||
| InferSourceKind::ClosureReturn { ty, .. } => {
|
||||
if ty.is_closure() {
|
||||
("closure", closure_as_fn_str(infcx, ty))
|
||||
("closure", closure_as_fn_str(infcx, ty), path)
|
||||
} else if !ty.is_ty_or_numeric_infer() {
|
||||
("normal", ty_to_string(infcx, ty, None))
|
||||
("normal", infcx.tcx.short_ty_string(ty, &mut path), path)
|
||||
} else {
|
||||
("other", String::new())
|
||||
("other", String::new(), path)
|
||||
}
|
||||
}
|
||||
// FIXME: We should be able to add some additional info here.
|
||||
InferSourceKind::GenericArg { .. }
|
||||
| InferSourceKind::FullyQualifiedMethodCall { .. } => ("other", String::new()),
|
||||
| InferSourceKind::FullyQualifiedMethodCall { .. } => ("other", String::new(), path),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di
|
|||
BuiltinLintDiag::RedundantImport(spans, ident) => {
|
||||
for (span, is_imported) in spans {
|
||||
let introduced = if is_imported { "imported" } else { "defined" };
|
||||
let span_msg = if span.is_dummy() { "by prelude" } else { "here" };
|
||||
let span_msg = if span.is_dummy() { "by the extern prelude" } else { "here" };
|
||||
diag.span_label(
|
||||
span,
|
||||
format!("the item `{ident}` is already {introduced} {span_msg}"),
|
||||
|
|
|
@ -1074,10 +1074,14 @@ impl UnusedParens {
|
|||
// Otherwise proceed with linting.
|
||||
_ => {}
|
||||
}
|
||||
let spans = inner
|
||||
.span
|
||||
.find_ancestor_inside(value.span)
|
||||
.map(|inner| (value.span.with_hi(inner.lo()), value.span.with_lo(inner.hi())));
|
||||
let spans = if !value.span.from_expansion() {
|
||||
inner
|
||||
.span
|
||||
.find_ancestor_inside(value.span)
|
||||
.map(|inner| (value.span.with_hi(inner.lo()), value.span.with_lo(inner.hi())))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.emit_unused_delims(cx, value.span, spans, "pattern", keep_space, false);
|
||||
}
|
||||
}
|
||||
|
@ -1233,11 +1237,13 @@ impl EarlyLintPass for UnusedParens {
|
|||
if self.with_self_ty_parens && b.generic_params.len() > 0 => {}
|
||||
ast::TyKind::ImplTrait(_, bounds) if bounds.len() > 1 => {}
|
||||
_ => {
|
||||
let spans = r
|
||||
.span
|
||||
.find_ancestor_inside(ty.span)
|
||||
.map(|r| (ty.span.with_hi(r.lo()), ty.span.with_lo(r.hi())));
|
||||
|
||||
let spans = if !ty.span.from_expansion() {
|
||||
r.span
|
||||
.find_ancestor_inside(ty.span)
|
||||
.map(|r| (ty.span.with_hi(r.lo()), ty.span.with_lo(r.hi())))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.emit_unused_delims(cx, ty.span, spans, "type", (false, false), false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -227,13 +227,10 @@ mod impls {
|
|||
impl_clone! {
|
||||
usize u8 u16 u32 u64 u128
|
||||
isize i8 i16 i32 i64 i128
|
||||
f32 f64
|
||||
f16 f32 f64 f128
|
||||
bool char
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
impl_clone! { f16 f128 }
|
||||
|
||||
#[unstable(feature = "never_type", issue = "35121")]
|
||||
impl Clone for ! {
|
||||
#[inline]
|
||||
|
|
|
@ -1497,12 +1497,9 @@ mod impls {
|
|||
}
|
||||
|
||||
partial_eq_impl! {
|
||||
bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64
|
||||
bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
partial_eq_impl! { f16 f128 }
|
||||
|
||||
macro_rules! eq_impl {
|
||||
($($t:ty)*) => ($(
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -1553,10 +1550,7 @@ mod impls {
|
|||
}
|
||||
}
|
||||
|
||||
partial_ord_impl! { f32 f64 }
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
partial_ord_impl! { f16 f128 }
|
||||
partial_ord_impl! { f16 f32 f64 f128 }
|
||||
|
||||
macro_rules! ord_impl {
|
||||
($($t:ty)*) => ($(
|
||||
|
|
|
@ -34,8 +34,10 @@ macro_rules! impl_float_to_int {
|
|||
}
|
||||
}
|
||||
|
||||
impl_float_to_int!(f16 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
|
||||
impl_float_to_int!(f32 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
|
||||
impl_float_to_int!(f64 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
|
||||
impl_float_to_int!(f128 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
|
||||
|
||||
// Conversion traits for primitive integer and float types
|
||||
// Conversions T -> T are covered by a blanket impl and therefore excluded
|
||||
|
@ -163,7 +165,12 @@ impl_from!(u16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0"
|
|||
impl_from!(u32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
|
||||
// float -> float
|
||||
impl_from!(f16 => f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
impl_from!(f16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
impl_from!(f16 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
impl_from!(f32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
impl_from!(f32 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
impl_from!(f64 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
|
||||
macro_rules! impl_float_from_bool {
|
||||
($float:ty) => {
|
||||
|
|
|
@ -517,8 +517,6 @@ impl CStr {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(cstr_count_bytes)]
|
||||
///
|
||||
/// use std::ffi::CStr;
|
||||
///
|
||||
/// let cstr = CStr::from_bytes_with_nul(b"foo\0").unwrap();
|
||||
|
@ -530,7 +528,7 @@ impl CStr {
|
|||
#[inline]
|
||||
#[must_use]
|
||||
#[doc(alias("len", "strlen"))]
|
||||
#[unstable(feature = "cstr_count_bytes", issue = "114441")]
|
||||
#[stable(feature = "cstr_count_bytes", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_const_unstable(feature = "const_cstr_from_ptr", issue = "113219")]
|
||||
pub const fn count_bytes(&self) -> usize {
|
||||
self.inner.len() - 1
|
||||
|
|
|
@ -11,5 +11,7 @@ macro_rules! floating {
|
|||
};
|
||||
}
|
||||
|
||||
floating! { f16 }
|
||||
floating! { f32 }
|
||||
floating! { f64 }
|
||||
floating! { f128 }
|
||||
|
|
|
@ -200,8 +200,6 @@
|
|||
//
|
||||
// Language features:
|
||||
// tidy-alphabetical-start
|
||||
#![cfg_attr(not(bootstrap), feature(f128))]
|
||||
#![cfg_attr(not(bootstrap), feature(f16))]
|
||||
#![feature(abi_unadjusted)]
|
||||
#![feature(adt_const_params)]
|
||||
#![feature(allow_internal_unsafe)]
|
||||
|
@ -226,6 +224,8 @@
|
|||
#![feature(doc_notable_trait)]
|
||||
#![feature(effects)]
|
||||
#![feature(extern_types)]
|
||||
#![feature(f128)]
|
||||
#![feature(f16)]
|
||||
#![feature(freeze_impls)]
|
||||
#![feature(fundamental)]
|
||||
#![feature(generic_arg_infer)]
|
||||
|
@ -347,6 +347,10 @@ pub mod u8;
|
|||
#[path = "num/shells/usize.rs"]
|
||||
pub mod usize;
|
||||
|
||||
#[path = "num/f128.rs"]
|
||||
pub mod f128;
|
||||
#[path = "num/f16.rs"]
|
||||
pub mod f16;
|
||||
#[path = "num/f32.rs"]
|
||||
pub mod f32;
|
||||
#[path = "num/f64.rs"]
|
||||
|
|
|
@ -422,17 +422,11 @@ marker_impls! {
|
|||
Copy for
|
||||
usize, u8, u16, u32, u64, u128,
|
||||
isize, i8, i16, i32, i64, i128,
|
||||
f32, f64,
|
||||
f16, f32, f64, f128,
|
||||
bool, char,
|
||||
{T: ?Sized} *const T,
|
||||
{T: ?Sized} *mut T,
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
marker_impls! {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
Copy for
|
||||
f16, f128,
|
||||
}
|
||||
|
||||
#[unstable(feature = "never_type", issue = "35121")]
|
||||
|
|
16
library/core/src/num/f128.rs
Normal file
16
library/core/src/num/f128.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
//! Constants for the `f128` quadruple-precision floating point type.
|
||||
//!
|
||||
//! *[See also the `f128` primitive type][f128].*
|
||||
//!
|
||||
//! Mathematically significant numbers are provided in the `consts` sub-module.
|
||||
//!
|
||||
//! For the constants defined directly in this module
|
||||
//! (as distinct from those defined in the `consts` sub-module),
|
||||
//! new code should instead use the associated constants
|
||||
//! defined directly on the `f128` type.
|
||||
|
||||
#![unstable(feature = "f128", issue = "116909")]
|
||||
|
||||
/// Basic mathematical constants.
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
pub mod consts {}
|
16
library/core/src/num/f16.rs
Normal file
16
library/core/src/num/f16.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
//! Constants for the `f16` half-precision floating point type.
|
||||
//!
|
||||
//! *[See also the `f16` primitive type][f16].*
|
||||
//!
|
||||
//! Mathematically significant numbers are provided in the `consts` sub-module.
|
||||
//!
|
||||
//! For the constants defined directly in this module
|
||||
//! (as distinct from those defined in the `consts` sub-module),
|
||||
//! new code should instead use the associated constants
|
||||
//! defined directly on the `f16` type.
|
||||
|
||||
#![unstable(feature = "f16", issue = "116909")]
|
||||
|
||||
/// Basic mathematical constants.
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
pub mod consts {}
|
|
@ -109,7 +109,7 @@ macro_rules! add_impl {
|
|||
)*)
|
||||
}
|
||||
|
||||
add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
||||
/// The subtraction operator `-`.
|
||||
///
|
||||
|
@ -218,7 +218,7 @@ macro_rules! sub_impl {
|
|||
)*)
|
||||
}
|
||||
|
||||
sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
||||
/// The multiplication operator `*`.
|
||||
///
|
||||
|
@ -348,7 +348,7 @@ macro_rules! mul_impl {
|
|||
)*)
|
||||
}
|
||||
|
||||
mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
||||
/// The division operator `/`.
|
||||
///
|
||||
|
@ -506,7 +506,7 @@ macro_rules! div_impl_float {
|
|||
)*)
|
||||
}
|
||||
|
||||
div_impl_float! { f32 f64 }
|
||||
div_impl_float! { f16 f32 f64 f128 }
|
||||
|
||||
/// The remainder operator `%`.
|
||||
///
|
||||
|
@ -623,7 +623,7 @@ macro_rules! rem_impl_float {
|
|||
)*)
|
||||
}
|
||||
|
||||
rem_impl_float! { f32 f64 }
|
||||
rem_impl_float! { f16 f32 f64 f128 }
|
||||
|
||||
/// The unary negation operator `-`.
|
||||
///
|
||||
|
@ -698,7 +698,7 @@ macro_rules! neg_impl {
|
|||
)*)
|
||||
}
|
||||
|
||||
neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
neg_impl! { isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
||||
/// The addition assignment operator `+=`.
|
||||
///
|
||||
|
@ -765,7 +765,7 @@ macro_rules! add_assign_impl {
|
|||
)+)
|
||||
}
|
||||
|
||||
add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
||||
/// The subtraction assignment operator `-=`.
|
||||
///
|
||||
|
@ -832,7 +832,7 @@ macro_rules! sub_assign_impl {
|
|||
)+)
|
||||
}
|
||||
|
||||
sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
||||
/// The multiplication assignment operator `*=`.
|
||||
///
|
||||
|
@ -890,7 +890,7 @@ macro_rules! mul_assign_impl {
|
|||
)+)
|
||||
}
|
||||
|
||||
mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
||||
/// The division assignment operator `/=`.
|
||||
///
|
||||
|
@ -947,7 +947,7 @@ macro_rules! div_assign_impl {
|
|||
)+)
|
||||
}
|
||||
|
||||
div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
||||
/// The remainder assignment operator `%=`.
|
||||
///
|
||||
|
@ -1008,4 +1008,4 @@ macro_rules! rem_assign_impl {
|
|||
)+)
|
||||
}
|
||||
|
||||
rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
|
|
@ -1074,7 +1074,22 @@ mod prim_tuple {}
|
|||
#[doc(hidden)]
|
||||
impl<T> (T,) {}
|
||||
|
||||
#[rustc_doc_primitive = "f16"]
|
||||
#[doc(alias = "half")]
|
||||
/// A 16-bit floating point type (specifically, the "binary16" type defined in IEEE 754-2008).
|
||||
///
|
||||
/// This type is very similar to [`prim@f32`] but has decreased precision because it uses half as many
|
||||
/// bits. Please see [the documentation for [`prim@f32`] or [Wikipedia on
|
||||
/// half-precision values][wikipedia] for more information.
|
||||
///
|
||||
/// *[See also the `std::f16::consts` module](crate::f16::consts).*
|
||||
///
|
||||
/// [wikipedia]: https://en.wikipedia.org/wiki/Half-precision_floating-point_format
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
mod prim_f16 {}
|
||||
|
||||
#[rustc_doc_primitive = "f32"]
|
||||
#[doc(alias = "single")]
|
||||
/// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008).
|
||||
///
|
||||
/// This type can represent a wide range of decimal numbers, like `3.5`, `27`,
|
||||
|
@ -1143,6 +1158,7 @@ impl<T> (T,) {}
|
|||
mod prim_f32 {}
|
||||
|
||||
#[rustc_doc_primitive = "f64"]
|
||||
#[doc(alias = "double")]
|
||||
/// A 64-bit floating point type (specifically, the "binary64" type defined in IEEE 754-2008).
|
||||
///
|
||||
/// This type is very similar to [`f32`], but has increased
|
||||
|
@ -1157,6 +1173,20 @@ mod prim_f32 {}
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
mod prim_f64 {}
|
||||
|
||||
#[rustc_doc_primitive = "f128"]
|
||||
#[doc(alias = "quad")]
|
||||
/// A 128-bit floating point type (specifically, the "binary128" type defined in IEEE 754-2008).
|
||||
///
|
||||
/// This type is very similar to [`prim@f32`] and [`prim@f64`], but has increased precision by using twice
|
||||
/// as many bits as `f64`. Please see [the documentation for [`prim@f32`] or [Wikipedia on
|
||||
/// quad-precision values][wikipedia] for more information.
|
||||
///
|
||||
/// *[See also the `std::f128::consts` module](crate::f128::consts).*
|
||||
///
|
||||
/// [wikipedia]: https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
mod prim_f128 {}
|
||||
|
||||
#[rustc_doc_primitive = "i8"]
|
||||
//
|
||||
/// The 8-bit signed integer type.
|
||||
|
|
11
library/std/src/f128.rs
Normal file
11
library/std/src/f128.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
//! Constants for the `f128` double-precision floating point type.
|
||||
//!
|
||||
//! *[See also the `f128` primitive type](primitive@f128).*
|
||||
//!
|
||||
//! Mathematically significant numbers are provided in the `consts` sub-module.
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
pub use core::f128::consts;
|
40
library/std/src/f128/tests.rs
Normal file
40
library/std/src/f128/tests.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
#![allow(dead_code)] // FIXME(f16_f128): remove once constants are used
|
||||
|
||||
/// Smallest number
|
||||
const TINY_BITS: u128 = 0x1;
|
||||
/// Next smallest number
|
||||
const TINY_UP_BITS: u128 = 0x2;
|
||||
/// Exponent = 0b11...10, Sifnificand 0b1111..10. Min val > 0
|
||||
const MAX_DOWN_BITS: u128 = 0x7ffeffffffffffffffffffffffffffff;
|
||||
/// Zeroed exponent, full significant
|
||||
const LARGEST_SUBNORMAL_BITS: u128 = 0x0000ffffffffffffffffffffffffffff;
|
||||
/// Exponent = 0b1, zeroed significand
|
||||
const SMALLEST_NORMAL_BITS: u128 = 0x00010000000000000000000000000000;
|
||||
/// First pattern over the mantissa
|
||||
const NAN_MASK1: u128 = 0x0000aaaaaaaaaaaaaaaaaaaaaaaaaaaa;
|
||||
/// Second pattern over the mantissa
|
||||
const NAN_MASK2: u128 = 0x00005555555555555555555555555555;
|
||||
|
||||
/// Compare by value
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! assert_f128_eq {
|
||||
($a:expr, $b:expr) => {
|
||||
let (l, r): (&f128, &f128) = (&$a, &$b);
|
||||
assert_eq!(*l, *r, "\na: {:#0130x}\nb: {:#0130x}", l.to_bits(), r.to_bits())
|
||||
};
|
||||
}
|
||||
|
||||
/// Compare by representation
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! assert_f128_biteq {
|
||||
($a:expr, $b:expr) => {
|
||||
let (l, r): (&f128, &f128) = (&$a, &$b);
|
||||
let lb = l.to_bits();
|
||||
let rb = r.to_bits();
|
||||
assert_eq!(
|
||||
lb, rb,
|
||||
"float {:?} is not bitequal to {:?}.\na: {:#0130x}\nb: {:#0130x}",
|
||||
*l, *r, lb, rb
|
||||
);
|
||||
};
|
||||
}
|
11
library/std/src/f16.rs
Normal file
11
library/std/src/f16.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
//! Constants for the `f16` double-precision floating point type.
|
||||
//!
|
||||
//! *[See also the `f16` primitive type](primitive@f16).*
|
||||
//!
|
||||
//! Mathematically significant numbers are provided in the `consts` sub-module.
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
pub use core::f16::consts;
|
46
library/std/src/f16/tests.rs
Normal file
46
library/std/src/f16/tests.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
#![allow(dead_code)] // FIXME(f16_f128): remove once constants are used
|
||||
|
||||
// We run out of precision pretty quickly with f16
|
||||
const F16_APPROX_L1: f16 = 0.001;
|
||||
const F16_APPROX_L2: f16 = 0.01;
|
||||
const F16_APPROX_L3: f16 = 0.1;
|
||||
const F16_APPROX_L4: f16 = 0.5;
|
||||
|
||||
/// Smallest number
|
||||
const TINY_BITS: u16 = 0x1;
|
||||
/// Next smallest number
|
||||
const TINY_UP_BITS: u16 = 0x2;
|
||||
/// Exponent = 0b11...10, Sifnificand 0b1111..10. Min val > 0
|
||||
const MAX_DOWN_BITS: u16 = 0x7bfe;
|
||||
/// Zeroed exponent, full significant
|
||||
const LARGEST_SUBNORMAL_BITS: u16 = 0x03ff;
|
||||
/// Exponent = 0b1, zeroed significand
|
||||
const SMALLEST_NORMAL_BITS: u16 = 0x0400;
|
||||
/// First pattern over the mantissa
|
||||
const NAN_MASK1: u16 = 0x02aa;
|
||||
/// Second pattern over the mantissa
|
||||
const NAN_MASK2: u16 = 0x0155;
|
||||
|
||||
/// Compare by value
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! assert_f16_eq {
|
||||
($a:expr, $b:expr) => {
|
||||
let (l, r): (&f16, &f16) = (&$a, &$b);
|
||||
assert_eq!(*l, *r, "\na: {:#018x}\nb: {:#018x}", l.to_bits(), r.to_bits())
|
||||
};
|
||||
}
|
||||
|
||||
/// Compare by representation
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! assert_f16_biteq {
|
||||
($a:expr, $b:expr) => {
|
||||
let (l, r): (&f16, &f16) = (&$a, &$b);
|
||||
let lb = l.to_bits();
|
||||
let rb = r.to_bits();
|
||||
assert_eq!(
|
||||
lb, rb,
|
||||
"float {:?} is not bitequal to {:?}.\na: {:#018x}\nb: {:#018x}",
|
||||
*l, *r, lb, rb
|
||||
);
|
||||
};
|
||||
}
|
|
@ -465,14 +465,20 @@ impl File {
|
|||
OpenOptions::new()
|
||||
}
|
||||
|
||||
/// Attempts to sync all OS-internal metadata to disk.
|
||||
/// Attempts to sync all OS-internal file content and metadata to disk.
|
||||
///
|
||||
/// This function will attempt to ensure that all in-memory data reaches the
|
||||
/// filesystem before returning.
|
||||
///
|
||||
/// This can be used to handle errors that would otherwise only be caught
|
||||
/// when the `File` is closed. Dropping a file will ignore errors in
|
||||
/// synchronizing this in-memory data.
|
||||
/// when the `File` is closed, as dropping a `File` will ignore all errors.
|
||||
/// Note, however, that `sync_all` is generally more expensive than closing
|
||||
/// a file by dropping it, because the latter is not required to block until
|
||||
/// the data has been written to the filesystem.
|
||||
///
|
||||
/// If synchronizing the metadata is not required, use [`sync_data`] instead.
|
||||
///
|
||||
/// [`sync_data`]: File::sync_data
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -489,6 +495,7 @@ impl File {
|
|||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[doc(alias = "fsync")]
|
||||
pub fn sync_all(&self) -> io::Result<()> {
|
||||
self.inner.fsync()
|
||||
}
|
||||
|
@ -520,6 +527,7 @@ impl File {
|
|||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[doc(alias = "fdatasync")]
|
||||
pub fn sync_data(&self) -> io::Result<()> {
|
||||
self.inner.datasync()
|
||||
}
|
||||
|
|
|
@ -214,7 +214,16 @@
|
|||
//! [slice]: prim@slice
|
||||
|
||||
#![cfg_attr(not(feature = "restricted-std"), stable(feature = "rust1", since = "1.0.0"))]
|
||||
#![cfg_attr(feature = "restricted-std", unstable(feature = "restricted_std", issue = "none"))]
|
||||
#![cfg_attr(
|
||||
feature = "restricted-std",
|
||||
unstable(
|
||||
feature = "restricted_std",
|
||||
issue = "none",
|
||||
reason = "You have attempted to use a standard library built for a platform that it doesn't \
|
||||
know how to support. Consider building it for a known environment, disabling it with \
|
||||
`#![no_std]` or overriding this warning by enabling this feature".
|
||||
)
|
||||
)]
|
||||
#![cfg_attr(not(bootstrap), rustc_preserve_ub_checks)]
|
||||
#![doc(
|
||||
html_playground_url = "https://play.rust-lang.org/",
|
||||
|
@ -283,6 +292,8 @@
|
|||
#![feature(doc_masked)]
|
||||
#![feature(doc_notable_trait)]
|
||||
#![feature(dropck_eyepatch)]
|
||||
#![feature(f128)]
|
||||
#![feature(f16)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(intra_doc_pointers)]
|
||||
#![feature(lang_items)]
|
||||
|
@ -558,6 +569,10 @@ pub use core::u8;
|
|||
#[allow(deprecated, deprecated_in_future)]
|
||||
pub use core::usize;
|
||||
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
pub mod f128;
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
pub mod f16;
|
||||
pub mod f32;
|
||||
pub mod f64;
|
||||
|
||||
|
|
129
tests/codegen/float/f128.rs
Normal file
129
tests/codegen/float/f128.rs
Normal file
|
@ -0,0 +1,129 @@
|
|||
// Verify that our intrinsics generate the correct LLVM calls for f128
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(f128)]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
// CHECK-LABEL: i1 @f128_eq(
|
||||
#[no_mangle]
|
||||
pub fn f128_eq(a: f128, b: f128) -> bool {
|
||||
// CHECK: fcmp oeq fp128 %{{.+}}, %{{.+}}
|
||||
a == b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f128_ne(
|
||||
#[no_mangle]
|
||||
pub fn f128_ne(a: f128, b: f128) -> bool {
|
||||
// CHECK: fcmp une fp128 %{{.+}}, %{{.+}}
|
||||
a != b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f128_gt(
|
||||
#[no_mangle]
|
||||
pub fn f128_gt(a: f128, b: f128) -> bool {
|
||||
// CHECK: fcmp ogt fp128 %{{.+}}, %{{.+}}
|
||||
a > b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f128_ge(
|
||||
#[no_mangle]
|
||||
pub fn f128_ge(a: f128, b: f128) -> bool {
|
||||
// CHECK: fcmp oge fp128 %{{.+}}, %{{.+}}
|
||||
a >= b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f128_lt(
|
||||
#[no_mangle]
|
||||
pub fn f128_lt(a: f128, b: f128) -> bool {
|
||||
// CHECK: fcmp olt fp128 %{{.+}}, %{{.+}}
|
||||
a < b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f128_le(
|
||||
#[no_mangle]
|
||||
pub fn f128_le(a: f128, b: f128) -> bool {
|
||||
// CHECK: fcmp ole fp128 %{{.+}}, %{{.+}}
|
||||
a <= b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: fp128 @f128_neg(
|
||||
#[no_mangle]
|
||||
pub fn f128_neg(a: f128) -> f128 {
|
||||
// CHECK: fneg fp128
|
||||
-a
|
||||
}
|
||||
|
||||
// CHECK-LABEL: fp128 @f128_add(
|
||||
#[no_mangle]
|
||||
pub fn f128_add(a: f128, b: f128) -> f128 {
|
||||
// CHECK: fadd fp128 %{{.+}}, %{{.+}}
|
||||
a + b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: fp128 @f128_sub(
|
||||
#[no_mangle]
|
||||
pub fn f128_sub(a: f128, b: f128) -> f128 {
|
||||
// CHECK: fsub fp128 %{{.+}}, %{{.+}}
|
||||
a - b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: fp128 @f128_mul(
|
||||
#[no_mangle]
|
||||
pub fn f128_mul(a: f128, b: f128) -> f128 {
|
||||
// CHECK: fmul fp128 %{{.+}}, %{{.+}}
|
||||
a * b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: fp128 @f128_div(
|
||||
#[no_mangle]
|
||||
pub fn f128_div(a: f128, b: f128) -> f128 {
|
||||
// CHECK: fdiv fp128 %{{.+}}, %{{.+}}
|
||||
a / b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: fp128 @f128_rem(
|
||||
#[no_mangle]
|
||||
pub fn f128_rem(a: f128, b: f128) -> f128 {
|
||||
// CHECK: frem fp128 %{{.+}}, %{{.+}}
|
||||
a % b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f128_add_assign(
|
||||
#[no_mangle]
|
||||
pub fn f128_add_assign(a: &mut f128, b: f128) {
|
||||
// CHECK: fadd fp128 %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
|
||||
*a += b;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f128_sub_assign(
|
||||
#[no_mangle]
|
||||
pub fn f128_sub_assign(a: &mut f128, b: f128) {
|
||||
// CHECK: fsub fp128 %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
|
||||
*a -= b;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f128_mul_assign(
|
||||
#[no_mangle]
|
||||
pub fn f128_mul_assign(a: &mut f128, b: f128) {
|
||||
// CHECK: fmul fp128 %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
|
||||
*a *= b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f128_div_assign(
|
||||
#[no_mangle]
|
||||
pub fn f128_div_assign(a: &mut f128, b: f128) {
|
||||
// CHECK: fdiv fp128 %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
|
||||
*a /= b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f128_rem_assign(
|
||||
#[no_mangle]
|
||||
pub fn f128_rem_assign(a: &mut f128, b: f128) {
|
||||
// CHECK: frem fp128 %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
|
||||
*a %= b
|
||||
}
|
129
tests/codegen/float/f16.rs
Normal file
129
tests/codegen/float/f16.rs
Normal file
|
@ -0,0 +1,129 @@
|
|||
// Verify that our intrinsics generate the correct LLVM calls for f16
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(f16)]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
// CHECK-LABEL: i1 @f16_eq(
|
||||
#[no_mangle]
|
||||
pub fn f16_eq(a: f16, b: f16) -> bool {
|
||||
// CHECK: fcmp oeq half %{{.+}}, %{{.+}}
|
||||
a == b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f16_ne(
|
||||
#[no_mangle]
|
||||
pub fn f16_ne(a: f16, b: f16) -> bool {
|
||||
// CHECK: fcmp une half %{{.+}}, %{{.+}}
|
||||
a != b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f16_gt(
|
||||
#[no_mangle]
|
||||
pub fn f16_gt(a: f16, b: f16) -> bool {
|
||||
// CHECK: fcmp ogt half %{{.+}}, %{{.+}}
|
||||
a > b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f16_ge(
|
||||
#[no_mangle]
|
||||
pub fn f16_ge(a: f16, b: f16) -> bool {
|
||||
// CHECK: fcmp oge half %{{.+}}, %{{.+}}
|
||||
a >= b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f16_lt(
|
||||
#[no_mangle]
|
||||
pub fn f16_lt(a: f16, b: f16) -> bool {
|
||||
// CHECK: fcmp olt half %{{.+}}, %{{.+}}
|
||||
a < b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f16_le(
|
||||
#[no_mangle]
|
||||
pub fn f16_le(a: f16, b: f16) -> bool {
|
||||
// CHECK: fcmp ole half %{{.+}}, %{{.+}}
|
||||
a <= b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: half @f16_neg(
|
||||
#[no_mangle]
|
||||
pub fn f16_neg(a: f16) -> f16 {
|
||||
// CHECK: fneg half %{{.+}}
|
||||
-a
|
||||
}
|
||||
|
||||
// CHECK-LABEL: half @f16_add(
|
||||
#[no_mangle]
|
||||
pub fn f16_add(a: f16, b: f16) -> f16 {
|
||||
// CHECK: fadd half %{{.+}}, %{{.+}}
|
||||
a + b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: half @f16_sub(
|
||||
#[no_mangle]
|
||||
pub fn f16_sub(a: f16, b: f16) -> f16 {
|
||||
// CHECK: fsub half %{{.+}}, %{{.+}}
|
||||
a - b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: half @f16_mul(
|
||||
#[no_mangle]
|
||||
pub fn f16_mul(a: f16, b: f16) -> f16 {
|
||||
// CHECK: fmul half %{{.+}}, %{{.+}}
|
||||
a * b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: half @f16_div(
|
||||
#[no_mangle]
|
||||
pub fn f16_div(a: f16, b: f16) -> f16 {
|
||||
// CHECK: fdiv half %{{.+}}, %{{.+}}
|
||||
a / b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: half @f16_rem(
|
||||
#[no_mangle]
|
||||
pub fn f16_rem(a: f16, b: f16) -> f16 {
|
||||
// CHECK: frem half %{{.+}}, %{{.+}}
|
||||
a % b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f16_add_assign(
|
||||
#[no_mangle]
|
||||
pub fn f16_add_assign(a: &mut f16, b: f16) {
|
||||
// CHECK: fadd half %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
|
||||
*a += b;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f16_sub_assign(
|
||||
#[no_mangle]
|
||||
pub fn f16_sub_assign(a: &mut f16, b: f16) {
|
||||
// CHECK: fsub half %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
|
||||
*a -= b;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f16_mul_assign(
|
||||
#[no_mangle]
|
||||
pub fn f16_mul_assign(a: &mut f16, b: f16) {
|
||||
// CHECK: fmul half %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
|
||||
*a *= b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f16_div_assign(
|
||||
#[no_mangle]
|
||||
pub fn f16_div_assign(a: &mut f16, b: f16) {
|
||||
// CHECK: fdiv half %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
|
||||
*a /= b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f16_rem_assign(
|
||||
#[no_mangle]
|
||||
pub fn f16_rem_assign(a: &mut f16, b: f16) {
|
||||
// CHECK: frem half %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
|
||||
*a %= b
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
error[E0282]: type annotations needed for `Vec<T>`
|
||||
error[E0282]: type annotations needed for `Vec<_>`
|
||||
--> $DIR/vector-no-ann.rs:2:9
|
||||
|
|
||||
LL | let _foo = Vec::new();
|
||||
|
|
|
@ -62,7 +62,7 @@ error[E0308]: mismatched types
|
|||
--> $DIR/async-closure-gate.rs:27:5
|
||||
|
|
||||
LL | fn foo3() {
|
||||
| - help: a return type might be missing here: `-> _`
|
||||
| - help: try adding a return type: `-> impl Future<Output = ()>`
|
||||
LL | / async {
|
||||
LL | |
|
||||
LL | | let _ = #[track_caller] || {
|
||||
|
@ -78,7 +78,7 @@ error[E0308]: mismatched types
|
|||
--> $DIR/async-closure-gate.rs:44:5
|
||||
|
|
||||
LL | fn foo5() {
|
||||
| - help: a return type might be missing here: `-> _`
|
||||
| - help: try adding a return type: `-> impl Future<Output = ()>`
|
||||
LL | / async {
|
||||
LL | |
|
||||
LL | | let _ = || {
|
||||
|
|
|
@ -62,7 +62,7 @@ error[E0308]: mismatched types
|
|||
--> $DIR/async-closure-gate.rs:27:5
|
||||
|
|
||||
LL | fn foo3() {
|
||||
| - help: a return type might be missing here: `-> _`
|
||||
| - help: try adding a return type: `-> impl Future<Output = ()>`
|
||||
LL | / async {
|
||||
LL | |
|
||||
LL | | let _ = #[track_caller] || {
|
||||
|
@ -78,7 +78,7 @@ error[E0308]: mismatched types
|
|||
--> $DIR/async-closure-gate.rs:44:5
|
||||
|
|
||||
LL | fn foo5() {
|
||||
| - help: a return type might be missing here: `-> _`
|
||||
| - help: try adding a return type: `-> impl Future<Output = ()>`
|
||||
LL | / async {
|
||||
LL | |
|
||||
LL | | let _ = || {
|
||||
|
|
|
@ -9,5 +9,5 @@ impl<const N: u32> Foo<N> {
|
|||
fn main() {
|
||||
let foo = Foo::<1>::foo();
|
||||
let foo = Foo::foo();
|
||||
//~^ error: type annotations needed for `Foo<N>`
|
||||
//~^ ERROR type annotations needed for `Foo<_>`
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0282]: type annotations needed for `Foo<N>`
|
||||
error[E0282]: type annotations needed for `Foo<_>`
|
||||
--> $DIR/doesnt_infer.rs:11:9
|
||||
|
|
||||
LL | let foo = Foo::foo();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0283]: type annotations needed for `Mask<_, N>`
|
||||
error[E0283]: type annotations needed for `Mask<_, _>`
|
||||
--> $DIR/issue-91614.rs:6:9
|
||||
|
|
||||
LL | let y = Mask::<_, _>::splat(false);
|
||||
|
|
|
@ -18,7 +18,7 @@ help: try adding a `where` bound
|
|||
LL | pub const fn new() -> Self where [(); Self::SIZE]: {
|
||||
| +++++++++++++++++++++++
|
||||
|
||||
error[E0282]: type annotations needed for `ArrayHolder<X>`
|
||||
error[E0282]: type annotations needed for `ArrayHolder<_>`
|
||||
--> $DIR/issue-62504.rs:26:9
|
||||
|
|
||||
LL | let mut array = ArrayHolder::new();
|
||||
|
|
|
@ -22,7 +22,7 @@ note: tuple struct defined here
|
|||
LL | struct ArrayHolder<const X: usize>([u32; X]);
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error[E0282]: type annotations needed for `ArrayHolder<X>`
|
||||
error[E0282]: type annotations needed for `ArrayHolder<_>`
|
||||
--> $DIR/issue-62504.rs:26:9
|
||||
|
|
||||
LL | let mut array = ArrayHolder::new();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0282]: type annotations needed for `Option<T>`
|
||||
error[E0282]: type annotations needed for `Option<_>`
|
||||
--> $DIR/inference-failure.rs:8:9
|
||||
|
|
||||
LL | let _ = NONE;
|
||||
|
|
|
@ -4,7 +4,7 @@ error: defaults for type parameters are only allowed in `struct`, `enum`, `type`
|
|||
LL | const NONE<T = ()>: Option<T> = None::<T>;
|
||||
| ^^^^^^
|
||||
|
||||
error[E0282]: type annotations needed for `Option<T>`
|
||||
error[E0282]: type annotations needed for `Option<_>`
|
||||
--> $DIR/parameter-defaults.rs:13:9
|
||||
|
|
||||
LL | let _ = NONE;
|
||||
|
|
17
tests/ui/imports/redundant-import-extern-prelude.rs
Normal file
17
tests/ui/imports/redundant-import-extern-prelude.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
// Check that we detect imports that are redundant due to the extern prelude
|
||||
// and that we emit a reasonable diagnostic.
|
||||
// issue: rust-lang/rust#121915
|
||||
//~^^^ NOTE the item `aux_issue_121915` is already defined by the extern prelude
|
||||
|
||||
// See also the discussion in <https://github.com/rust-lang/rust/pull/122954>.
|
||||
|
||||
//@ compile-flags: --extern aux_issue_121915 --edition 2018
|
||||
//@ aux-build: aux-issue-121915.rs
|
||||
|
||||
#[deny(unused_imports)]
|
||||
//~^ NOTE the lint level is defined here
|
||||
fn main() {
|
||||
use aux_issue_121915;
|
||||
//~^ ERROR the item `aux_issue_121915` is imported redundantly
|
||||
aux_issue_121915::item();
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
error: the item `aux_issue_121915` is imported redundantly
|
||||
--> $DIR/redundant-import-issue-121915.rs:6:9
|
||||
--> $DIR/redundant-import-extern-prelude.rs:14:9
|
||||
|
|
||||
LL | use aux_issue_121915;
|
||||
| ^^^^^^^^^^^^^^^^ the item `aux_issue_121915` is already defined by prelude
|
||||
| ^^^^^^^^^^^^^^^^ the item `aux_issue_121915` is already defined by the extern prelude
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/redundant-import-issue-121915.rs:4:8
|
||||
--> $DIR/redundant-import-extern-prelude.rs:11:8
|
||||
|
|
||||
LL | #[deny(unused_imports)]
|
||||
| ^^^^^^^^^^^^^^
|
|
@ -1,9 +0,0 @@
|
|||
//@ compile-flags: --extern aux_issue_121915 --edition 2018
|
||||
//@ aux-build: aux-issue-121915.rs
|
||||
|
||||
#[deny(unused_imports)]
|
||||
fn main() {
|
||||
use aux_issue_121915;
|
||||
//~^ ERROR the item `aux_issue_121915` is imported redundantly
|
||||
aux_issue_121915::item();
|
||||
}
|
18
tests/ui/imports/redundant-import-lang-prelude-attr.rs
Normal file
18
tests/ui/imports/redundant-import-lang-prelude-attr.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Check that we detect imports (of built-in attributes) that are redundant due to
|
||||
// the language prelude and that we emit a reasonable diagnostic.
|
||||
//~^^ NOTE the item `allow` is already defined by the extern prelude
|
||||
|
||||
// Note that we use the term "extern prelude" in the label even though "language prelude"
|
||||
// would be more correct. However, it's not worth special-casing this.
|
||||
|
||||
// See also the discussion in <https://github.com/rust-lang/rust/pull/122954>.
|
||||
|
||||
//@ edition: 2018
|
||||
|
||||
#![deny(unused_imports)]
|
||||
//~^ NOTE the lint level is defined here
|
||||
|
||||
use allow; //~ ERROR the item `allow` is imported redundantly
|
||||
|
||||
#[allow(unused)]
|
||||
fn main() {}
|
14
tests/ui/imports/redundant-import-lang-prelude-attr.stderr
Normal file
14
tests/ui/imports/redundant-import-lang-prelude-attr.stderr
Normal file
|
@ -0,0 +1,14 @@
|
|||
error: the item `allow` is imported redundantly
|
||||
--> $DIR/redundant-import-lang-prelude-attr.rs:15:5
|
||||
|
|
||||
LL | use allow;
|
||||
| ^^^^^ the item `allow` is already defined by the extern prelude
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/redundant-import-lang-prelude-attr.rs:12:9
|
||||
|
|
||||
LL | #![deny(unused_imports)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
18
tests/ui/imports/redundant-import-lang-prelude.rs
Normal file
18
tests/ui/imports/redundant-import-lang-prelude.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Check that we detect imports that are redundant due to the language prelude
|
||||
// and that we emit a reasonable diagnostic.
|
||||
//~^^ NOTE the item `u8` is already defined by the extern prelude
|
||||
|
||||
// Note that we use the term "extern prelude" in the label even though "language prelude"
|
||||
// would be more correct. However, it's not worth special-casing this.
|
||||
|
||||
// See also the discussion in <https://github.com/rust-lang/rust/pull/122954>.
|
||||
|
||||
#![deny(unused_imports)]
|
||||
//~^ NOTE the lint level is defined here
|
||||
|
||||
use std::primitive::u8;
|
||||
//~^ ERROR the item `u8` is imported redundantly
|
||||
|
||||
const _: u8 = 0;
|
||||
|
||||
fn main() {}
|
14
tests/ui/imports/redundant-import-lang-prelude.stderr
Normal file
14
tests/ui/imports/redundant-import-lang-prelude.stderr
Normal file
|
@ -0,0 +1,14 @@
|
|||
error: the item `u8` is imported redundantly
|
||||
--> $DIR/redundant-import-lang-prelude.rs:13:5
|
||||
|
|
||||
LL | use std::primitive::u8;
|
||||
| ^^^^^^^^^^^^^^^^^^ the item `u8` is already defined by the extern prelude
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/redundant-import-lang-prelude.rs:10:9
|
||||
|
|
||||
LL | #![deny(unused_imports)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// This test demonstrates that we currently don't make an effort to detect
|
||||
// imports made redundant by the `#[macro_use]` prelude.
|
||||
// See also the discussion in <https://github.com/rust-lang/rust/pull/122954>.
|
||||
|
||||
//@ check-pass
|
||||
//@ aux-build:two_macros.rs
|
||||
#![deny(unused_imports)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate two_macros;
|
||||
|
||||
// This import is actually redundant due to the `#[macro_use]` above.
|
||||
use two_macros::n;
|
||||
|
||||
// We intentionally reference two items from the `#[macro_use]`'d crate because
|
||||
// if we were to reference only item `n`, we would flag the `#[macro_use]`
|
||||
// attribute as redundant which would be correct of course.
|
||||
// That's interesting on its own -- we prefer "blaming" the `#[macro_use]`
|
||||
// over the import (here, `use two_macros::n`) when it comes to redundancy.
|
||||
n!();
|
||||
m!();
|
||||
|
||||
fn main() {}
|
|
@ -4,7 +4,7 @@ fn main() {
|
|||
// error handles this gracefully, and in particular doesn't generate an extra
|
||||
// note about the `?` operator in the closure body, which isn't relevant to
|
||||
// the inference.
|
||||
let x = |r| { //~ ERROR type annotations needed for `Result<(), E>`
|
||||
let x = |r| { //~ ERROR type annotations needed for `Result<(), _>`
|
||||
let v = r?;
|
||||
Ok(v)
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0282]: type annotations needed for `Result<(), E>`
|
||||
error[E0282]: type annotations needed for `Result<(), _>`
|
||||
--> $DIR/cannot-infer-closure-circular.rs:7:14
|
||||
|
|
||||
LL | let x = |r| {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0283]: type annotations needed for `Foo<i32, &str, W, Z>`
|
||||
error[E0283]: type annotations needed for `Foo<i32, &str, _, _>`
|
||||
--> $DIR/erase-type-params-in-label.rs:2:9
|
||||
|
|
||||
LL | let foo = foo(1, "");
|
||||
|
@ -15,7 +15,7 @@ help: consider giving `foo` an explicit type, where the type for type parameter
|
|||
LL | let foo: Foo<i32, &str, W, Z> = foo(1, "");
|
||||
| ++++++++++++++++++++++
|
||||
|
||||
error[E0283]: type annotations needed for `Bar<i32, &str, Z>`
|
||||
error[E0283]: type annotations needed for `Bar<i32, &str, _>`
|
||||
--> $DIR/erase-type-params-in-label.rs:5:9
|
||||
|
|
||||
LL | let bar = bar(1, "");
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0282]: type annotations needed for `A<std::result::Result<std::result::Result<(), E>, Error>>`
|
||||
error[E0282]: type annotations needed for `A<std::result::Result<std::result::Result<(), _>, Error>>`
|
||||
--> $DIR/issue-104649.rs:24:9
|
||||
|
|
||||
LL | let a = A(Result::Ok(Result::Ok(())));
|
||||
|
|
|
@ -50,7 +50,7 @@ help: try using a fully qualified path to specify the expected types
|
|||
LL | |x| String::from(<str as AsRef<T>>::as_ref("x"));
|
||||
| ++++++++++++++++++++++++++ ~
|
||||
|
||||
error[E0283]: type annotations needed for `&T`
|
||||
error[E0283]: type annotations needed for `&_`
|
||||
--> $DIR/issue-72690.rs:17:9
|
||||
|
|
||||
LL | let _ = "x".as_ref();
|
||||
|
|
|
@ -6,5 +6,5 @@ fn foo<const N: usize>(_: impl std::fmt::Display) -> [usize; N] {
|
|||
|
||||
fn main() {
|
||||
let _ = foo("foo");
|
||||
//~^ ERROR: type annotations needed for `[usize; N]`
|
||||
//~^ ERROR type annotations needed for `[usize; _]`
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0282]: type annotations needed for `[usize; N]`
|
||||
error[E0282]: type annotations needed for `[usize; _]`
|
||||
--> $DIR/issue-83606.rs:8:9
|
||||
|
|
||||
LL | let _ = foo("foo");
|
||||
|
|
|
@ -6,15 +6,15 @@ LL | 1 +
|
|||
|
|
||||
= help: the trait `Add<()>` is not implemented for `{integer}`
|
||||
= help: the following other types implement trait `Add<Rhs>`:
|
||||
<&'a f128 as Add<f128>>
|
||||
<&'a f16 as Add<f16>>
|
||||
<&'a f32 as Add<f32>>
|
||||
<&'a f64 as Add<f64>>
|
||||
<&'a i128 as Add<i128>>
|
||||
<&'a i16 as Add<i16>>
|
||||
<&'a i32 as Add<i32>>
|
||||
<&'a i64 as Add<i64>>
|
||||
<&'a i8 as Add<i8>>
|
||||
<&'a isize as Add<isize>>
|
||||
and 48 others
|
||||
and 56 others
|
||||
|
||||
error[E0277]: cannot add `()` to `{integer}`
|
||||
--> $DIR/issue-11771.rs:8:7
|
||||
|
@ -24,15 +24,15 @@ LL | 1 +
|
|||
|
|
||||
= help: the trait `Add<()>` is not implemented for `{integer}`
|
||||
= help: the following other types implement trait `Add<Rhs>`:
|
||||
<&'a f128 as Add<f128>>
|
||||
<&'a f16 as Add<f16>>
|
||||
<&'a f32 as Add<f32>>
|
||||
<&'a f64 as Add<f64>>
|
||||
<&'a i128 as Add<i128>>
|
||||
<&'a i16 as Add<i16>>
|
||||
<&'a i32 as Add<i32>>
|
||||
<&'a i64 as Add<i64>>
|
||||
<&'a i8 as Add<i8>>
|
||||
<&'a isize as Add<isize>>
|
||||
and 48 others
|
||||
and 56 others
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0282]: type annotations needed for `&T`
|
||||
error[E0282]: type annotations needed for `&_`
|
||||
--> $DIR/issue-12187-1.rs:6:9
|
||||
|
|
||||
LL | let &v = new();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0282]: type annotations needed for `&T`
|
||||
error[E0282]: type annotations needed for `&_`
|
||||
--> $DIR/issue-12187-2.rs:6:9
|
||||
|
|
||||
LL | let &v = new();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0282]: type annotations needed for `B<T>`
|
||||
error[E0282]: type annotations needed for `B<_>`
|
||||
--> $DIR/issue-17551.rs:6:9
|
||||
|
|
||||
LL | let foo = B(marker::PhantomData);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0282]: type annotations needed for `Expr<'_, VAR>`
|
||||
error[E0282]: type annotations needed for `Expr<'_, _>`
|
||||
--> $DIR/issue-23046.rs:17:15
|
||||
|
|
||||
LL | let ex = |x| {
|
||||
|
|
|
@ -16,15 +16,15 @@ LL | Vec::<[(); 1 + for x in 0..1 {}]>::new();
|
|||
|
|
||||
= help: the trait `Add<()>` is not implemented for `{integer}`
|
||||
= help: the following other types implement trait `Add<Rhs>`:
|
||||
<&'a f128 as Add<f128>>
|
||||
<&'a f16 as Add<f16>>
|
||||
<&'a f32 as Add<f32>>
|
||||
<&'a f64 as Add<f64>>
|
||||
<&'a i128 as Add<i128>>
|
||||
<&'a i16 as Add<i16>>
|
||||
<&'a i32 as Add<i32>>
|
||||
<&'a i64 as Add<i64>>
|
||||
<&'a i8 as Add<i8>>
|
||||
<&'a isize as Add<isize>>
|
||||
and 48 others
|
||||
and 56 others
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0282]: type annotations needed for `SmallCString<N>`
|
||||
error[E0282]: type annotations needed for `SmallCString<_>`
|
||||
--> $DIR/issue-98299.rs:4:36
|
||||
|
|
||||
LL | SmallCString::try_from(p).map(|cstr| cstr);
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
//@ run-pass
|
||||
|
||||
#![warn(unused_parens)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait Foo {
|
||||
fn bar();
|
||||
fn tar();
|
||||
}
|
||||
|
||||
macro_rules! unused_parens {
|
||||
($ty:ident) => {
|
||||
impl<$ty: Foo> Foo for ($ty,) {
|
||||
fn bar() { <$ty>::bar() }
|
||||
fn tar() {}
|
||||
}
|
||||
};
|
||||
|
||||
($ty:ident $(, $rest:ident)*) => {
|
||||
impl<$ty: Foo, $($rest: Foo),*> Foo for ($ty, $($rest),*) {
|
||||
fn bar() {
|
||||
<$ty>::bar();
|
||||
<($($rest),*)>::bar() //~WARN unnecessary parentheses around type
|
||||
}
|
||||
fn tar() {
|
||||
let (_t) = 1; //~WARN unnecessary parentheses around pattern
|
||||
//~| WARN unnecessary parentheses around pattern
|
||||
let (_t1,) = (1,);
|
||||
let (_t2, _t3) = (1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
unused_parens!($($rest),*);
|
||||
}
|
||||
}
|
||||
|
||||
unused_parens!(T1, T2, T3);
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,40 @@
|
|||
warning: unnecessary parentheses around pattern
|
||||
--> $DIR/unused-parens-in-macro-issue-120642.rs:26:19
|
||||
|
|
||||
LL | let (_t) = 1;
|
||||
| ^^^^
|
||||
...
|
||||
LL | unused_parens!(T1, T2, T3);
|
||||
| -------------------------- in this macro invocation
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unused-parens-in-macro-issue-120642.rs:3:9
|
||||
|
|
||||
LL | #![warn(unused_parens)]
|
||||
| ^^^^^^^^^^^^^
|
||||
= note: this warning originates in the macro `unused_parens` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
warning: unnecessary parentheses around type
|
||||
--> $DIR/unused-parens-in-macro-issue-120642.rs:23:18
|
||||
|
|
||||
LL | <($($rest),*)>::bar()
|
||||
| ^^^^^^^^^^^^
|
||||
...
|
||||
LL | unused_parens!(T1, T2, T3);
|
||||
| -------------------------- in this macro invocation
|
||||
|
|
||||
= note: this warning originates in the macro `unused_parens` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
warning: unnecessary parentheses around pattern
|
||||
--> $DIR/unused-parens-in-macro-issue-120642.rs:26:19
|
||||
|
|
||||
LL | let (_t) = 1;
|
||||
| ^^^^
|
||||
...
|
||||
LL | unused_parens!(T1, T2, T3);
|
||||
| -------------------------- in this macro invocation
|
||||
|
|
||||
= note: this warning originates in the macro `unused_parens` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
warning: 3 warnings emitted
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
error[E0282]: type annotations needed for `Vec<T>`
|
||||
error[E0282]: type annotations needed for `Vec<_>`
|
||||
--> $DIR/method-ambig-one-trait-unknown-int-type.rs:24:9
|
||||
|
|
||||
LL | let mut x = Vec::new();
|
||||
|
|
|
@ -6,15 +6,15 @@ LL | 1 + Some(1);
|
|||
|
|
||||
= help: the trait `Add<Option<{integer}>>` is not implemented for `{integer}`
|
||||
= help: the following other types implement trait `Add<Rhs>`:
|
||||
<&'a f128 as Add<f128>>
|
||||
<&'a f16 as Add<f16>>
|
||||
<&'a f32 as Add<f32>>
|
||||
<&'a f64 as Add<f64>>
|
||||
<&'a i128 as Add<i128>>
|
||||
<&'a i16 as Add<i16>>
|
||||
<&'a i32 as Add<i32>>
|
||||
<&'a i64 as Add<i64>>
|
||||
<&'a i8 as Add<i8>>
|
||||
<&'a isize as Add<isize>>
|
||||
and 48 others
|
||||
and 56 others
|
||||
|
||||
error[E0277]: cannot subtract `Option<{integer}>` from `usize`
|
||||
--> $DIR/binops.rs:3:16
|
||||
|
@ -37,15 +37,15 @@ LL | 3 * ();
|
|||
|
|
||||
= help: the trait `Mul<()>` is not implemented for `{integer}`
|
||||
= help: the following other types implement trait `Mul<Rhs>`:
|
||||
<&'a f128 as Mul<f128>>
|
||||
<&'a f16 as Mul<f16>>
|
||||
<&'a f32 as Mul<f32>>
|
||||
<&'a f64 as Mul<f64>>
|
||||
<&'a i128 as Mul<i128>>
|
||||
<&'a i16 as Mul<i16>>
|
||||
<&'a i32 as Mul<i32>>
|
||||
<&'a i64 as Mul<i64>>
|
||||
<&'a i8 as Mul<i8>>
|
||||
<&'a isize as Mul<isize>>
|
||||
and 49 others
|
||||
and 57 others
|
||||
|
||||
error[E0277]: cannot divide `{integer}` by `&str`
|
||||
--> $DIR/binops.rs:5:7
|
||||
|
@ -55,15 +55,15 @@ LL | 4 / "";
|
|||
|
|
||||
= help: the trait `Div<&str>` is not implemented for `{integer}`
|
||||
= help: the following other types implement trait `Div<Rhs>`:
|
||||
<&'a f128 as Div<f128>>
|
||||
<&'a f16 as Div<f16>>
|
||||
<&'a f32 as Div<f32>>
|
||||
<&'a f64 as Div<f64>>
|
||||
<&'a i128 as Div<i128>>
|
||||
<&'a i16 as Div<i16>>
|
||||
<&'a i32 as Div<i32>>
|
||||
<&'a i64 as Div<i64>>
|
||||
<&'a i8 as Div<i8>>
|
||||
<&'a isize as Div<isize>>
|
||||
and 54 others
|
||||
and 62 others
|
||||
|
||||
error[E0277]: can't compare `{integer}` with `String`
|
||||
--> $DIR/binops.rs:6:7
|
||||
|
|
|
@ -2,7 +2,7 @@ error[E0308]: mismatched types
|
|||
--> $DIR/return-closures.rs:3:5
|
||||
|
|
||||
LL | fn foo() {
|
||||
| - help: try adding a return type: `-> impl for<'a> Fn(&'a i32) -> i32`
|
||||
| - help: try adding a return type: `-> impl FnOnce(&i32) -> i32`
|
||||
LL |
|
||||
LL | |x: &i32| 1i32
|
||||
| ^^^^^^^^^^^^^^ expected `()`, found closure
|
||||
|
|
|
@ -18,7 +18,7 @@ fn assert_impls_fn<R,T: Fn()->R>(_: &T){}
|
|||
|
||||
fn main() {
|
||||
let n = None;
|
||||
//~^ ERROR type annotations needed for `Option<T>`
|
||||
//~^ ERROR type annotations needed for `Option<_>`
|
||||
let e = S(&n);
|
||||
let f = || {
|
||||
// S being copy is critical for this to work
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0282]: type annotations needed for `Option<T>`
|
||||
error[E0282]: type annotations needed for `Option<_>`
|
||||
--> $DIR/copy-guessing.rs:20:9
|
||||
|
|
||||
LL | let n = None;
|
||||
|
|
|
@ -55,7 +55,7 @@ help: try using a fully qualified path to specify the expected types
|
|||
LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(<u32 as Into<T>>::into(0u32))).collect();
|
||||
| +++++++++++++++++++++++ ~
|
||||
|
||||
error[E0283]: type annotations needed for `Box<T>`
|
||||
error[E0283]: type annotations needed for `Box<_>`
|
||||
--> $DIR/issue-77982.rs:37:9
|
||||
|
|
||||
LL | let _ = ().foo();
|
||||
|
@ -73,7 +73,7 @@ help: consider giving this pattern a type, where the type for type parameter `T`
|
|||
LL | let _: Box<T> = ().foo();
|
||||
| ++++++++
|
||||
|
||||
error[E0283]: type annotations needed for `Box<T>`
|
||||
error[E0283]: type annotations needed for `Box<_>`
|
||||
--> $DIR/issue-77982.rs:41:9
|
||||
|
|
||||
LL | let _ = (&()).bar();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0282]: type annotations needed for `Result<Child, F>`
|
||||
error[E0282]: type annotations needed for `Result<Child, _>`
|
||||
--> $DIR/or_else-multiple-type-params.rs:7:18
|
||||
|
|
||||
LL | .or_else(|err| {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#[allow(unused)]
|
||||
fn foo() { //~ HELP a return type might be missing here
|
||||
fn foo() { //~ HELP try adding a return type
|
||||
vec!['a'].iter().map(|c| c)
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
//~| NOTE expected `()`, found `Map<Iter<'_, char>, ...>`
|
||||
|
|
|
@ -10,10 +10,10 @@ help: consider using a semicolon here
|
|||
|
|
||||
LL | vec!['a'].iter().map(|c| c);
|
||||
| +
|
||||
help: a return type might be missing here
|
||||
help: try adding a return type
|
||||
|
|
||||
LL | fn foo() -> _ {
|
||||
| ++++
|
||||
LL | fn foo() -> impl Iterator<Item = &char> {
|
||||
| ++++++++++++++++++++++++++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0282]: type annotations needed for `Option<T>`
|
||||
error[E0282]: type annotations needed for `Option<_>`
|
||||
--> $DIR/unboxed-closures-failed-recursive-fn-2.rs:8:9
|
||||
|
|
||||
LL | let mut closure0 = None;
|
||||
|
|
Loading…
Add table
Reference in a new issue