diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index bb09f701531cf..e79392adf74b8 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -754,7 +754,7 @@ fn validate_generic_param_order( GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident), GenericParamKind::Const { ref ty, kw_span: _, default: _ } => { let ty = pprust::ty_to_string(ty); - let unordered = sess.features_untracked().const_generics; + let unordered = sess.features_untracked().unordered_const_ty_params(); (ParamKindOrd::Const { unordered }, Some(format!("const {}: {}", param.ident, ty))) } }; diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index c803c8a83b15c..0679ccabe726c 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -727,16 +727,46 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { } fn maybe_stage_features(sess: &Session, krate: &ast::Crate) { + use rustc_errors::Applicability; + if !sess.opts.unstable_features.is_nightly_build() { + let lang_features = &sess.features_untracked().declared_lang_features; for attr in krate.attrs.iter().filter(|attr| sess.check_name(attr, sym::feature)) { - struct_span_err!( + let mut err = struct_span_err!( sess.parse_sess.span_diagnostic, attr.span, E0554, "`#![feature]` may not be used on the {} release channel", option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)") - ) - .emit(); + ); + let mut all_stable = true; + for ident in + attr.meta_item_list().into_iter().flatten().map(|nested| nested.ident()).flatten() + { + let name = ident.name; + let stable_since = lang_features + .iter() + .flat_map(|&(feature, _, since)| if feature == name { since } else { None }) + .next(); + if let Some(since) = stable_since { + err.help(&format!( + "the feature `{}` has been stable since {} and no longer requires \ + an attribute to enable", + name, since + )); + } else { + all_stable = false; + } + } + if all_stable { + err.span_suggestion( + attr.span, + "remove the attribute", + String::new(), + Applicability::MachineApplicable, + ); + } + err.emit(); } } } diff --git a/compiler/rustc_error_codes/src/error_codes/E0404.md b/compiler/rustc_error_codes/src/error_codes/E0404.md index 1360cc99afcc4..d6fa51e618c4c 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0404.md +++ b/compiler/rustc_error_codes/src/error_codes/E0404.md @@ -8,14 +8,15 @@ struct Foo; struct Bar; impl Foo for Bar {} // error: `Foo` is not a trait +fn baz(t: T) {} // error: `Foo` is not a trait ``` Another erroneous code example: ```compile_fail,E0404 -struct Foo; +type Foo = Iterator; -fn bar(t: T) {} // error: `Foo` is not a trait +fn bar(t: T) {} // error: `Foo` is a type alias ``` Please verify that the trait's name was not misspelled or that the right @@ -30,14 +31,27 @@ struct Bar; impl Foo for Bar { // ok! // functions implementation } + +fn baz(t: T) {} // ok! ``` -or: +Alternatively, you could introduce a new trait with your desired restrictions +as a super trait: ``` -trait Foo { - // some functions -} +# trait Foo {} +# struct Bar; +# impl Foo for Bar {} +trait Qux: Foo {} // Anything that implements Qux also needs to implement Foo +fn baz(t: T) {} // also ok! +``` + +Finally, if you are on nightly and want to use a trait alias +instead of a type alias, you should use `#![feature(trait_alias)]`: + +``` +#![feature(trait_alias)] +trait Foo = Iterator; fn bar(t: T) {} // ok! ``` diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index a410826d3fda6..cb0615746012f 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -63,6 +63,10 @@ macro_rules! declare_features { _ => panic!("`{}` was not listed in `declare_features`", feature), } } + + pub fn unordered_const_ty_params(&self) -> bool { + self.const_generics || self.const_generics_defaults + } } }; } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 1051fb8cea279..a70be14546b41 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -296,7 +296,9 @@ impl GenericArg<'_> { match self { GenericArg::Lifetime(_) => ast::ParamKindOrd::Lifetime, GenericArg::Type(_) => ast::ParamKindOrd::Type, - GenericArg::Const(_) => ast::ParamKindOrd::Const { unordered: feats.const_generics }, + GenericArg::Const(_) => { + ast::ParamKindOrd::Const { unordered: feats.unordered_const_ty_params() } + } } } } diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index 3ced3920cfdfe..4036f4da1a76b 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -1,4 +1,5 @@ #![feature(allow_internal_unstable)] +#![feature(bench_black_box)] #![feature(const_fn)] #![feature(const_panic)] #![feature(extend_one)] diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index a1a56eb1b5b44..08fa12aa3718f 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -564,7 +564,7 @@ rustc_queries! { } /// Collects the associated items defined on a trait or impl. - query associated_items(key: DefId) -> ty::AssociatedItems<'tcx> { + query associated_items(key: DefId) -> ty::AssocItems<'tcx> { storage(ArenaCacheSelector<'tcx>) desc { |tcx| "collecting associated items of {}", tcx.def_path_str(key) } } diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index d3770fa416b53..d005f63ed4383 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -96,15 +96,15 @@ impl AssocKind { /// it is relatively expensive. Instead, items are indexed by `Symbol` and hygienic comparison is /// done only on items with the same name. #[derive(Debug, Clone, PartialEq, HashStable)] -pub struct AssociatedItems<'tcx> { +pub struct AssocItems<'tcx> { pub(super) items: SortedIndexMultiMap, } -impl<'tcx> AssociatedItems<'tcx> { +impl<'tcx> AssocItems<'tcx> { /// Constructs an `AssociatedItems` map from a series of `ty::AssocItem`s in definition order. pub fn new(items_in_def_order: impl IntoIterator) -> Self { let items = items_in_def_order.into_iter().map(|item| (item.ident.name, item)).collect(); - AssociatedItems { items } + AssocItems { items } } /// Returns a slice of associated items in the order they were defined. diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index d30a8693959f3..c8fdbc30d1591 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -36,7 +36,7 @@ impl GenericParamDefKind { GenericParamDefKind::Lifetime => ast::ParamKindOrd::Lifetime, GenericParamDefKind::Type { .. } => ast::ParamKindOrd::Type, GenericParamDefKind::Const { .. } => { - ast::ParamKindOrd::Const { unordered: tcx.features().const_generics } + ast::ParamKindOrd::Const { unordered: tcx.features().unordered_const_ty_params() } } } } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index c63edf365a1aa..70b019e8468e7 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -3,6 +3,7 @@ // from live codes are live, and everything else is dead. use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; @@ -15,7 +16,7 @@ use rustc_middle::middle::privacy; use rustc_middle::ty::{self, DefIdTree, TyCtxt}; use rustc_session::lint; -use rustc_span::symbol::{sym, Symbol}; +use rustc_span::symbol::{sym, Ident, Symbol}; // Any local node that may call something in its body block should be // explored. For example, if it's a live Node::Item that is a @@ -505,6 +506,13 @@ fn find_live<'tcx>( symbol_visitor.live_symbols } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum ExtraNote { + /// Use this to provide some examples in the diagnostic of potential other purposes for a value + /// or field that is dead code + OtherPurposeExamples, +} + struct DeadVisitor<'tcx> { tcx: TyCtxt<'tcx>, live_symbols: FxHashSet, @@ -570,14 +578,42 @@ impl DeadVisitor<'tcx> { &mut self, id: hir::HirId, span: rustc_span::Span, - name: Symbol, + name: Ident, participle: &str, + extra_note: Option, ) { if !name.as_str().starts_with('_') { self.tcx.struct_span_lint_hir(lint::builtin::DEAD_CODE, id, span, |lint| { let def_id = self.tcx.hir().local_def_id(id); let descr = self.tcx.def_kind(def_id).descr(def_id.to_def_id()); - lint.build(&format!("{} is never {}: `{}`", descr, participle, name)).emit() + + let prefixed = vec![(name.span, format!("_{}", name))]; + + let mut diag = + lint.build(&format!("{} is never {}: `{}`", descr, participle, name)); + + diag.multipart_suggestion( + "if this is intentional, prefix it with an underscore", + prefixed, + Applicability::MachineApplicable, + ); + + let mut note = format!( + "the leading underscore signals that this {} serves some other \ + purpose even if it isn't used in a way that we can detect.", + descr, + ); + if matches!(extra_note, Some(ExtraNote::OtherPurposeExamples)) { + note += " (e.g. for its effect when dropped or in foreign code)"; + } + + diag.note(¬e); + + // Force the note we added to the front, before any other subdiagnostics + // added in lint.build(...) + diag.children.rotate_right(1); + + diag.emit() }); } } @@ -623,7 +659,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { hir::ItemKind::Struct(..) => "constructed", // Issue #52325 _ => "used", }; - self.warn_dead_code(item.hir_id(), span, item.ident.name, participle); + self.warn_dead_code(item.hir_id(), span, item.ident, participle, None); } else { // Only continue if we didn't warn intravisit::walk_item(self, item); @@ -637,7 +673,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { id: hir::HirId, ) { if self.should_warn_about_variant(&variant) { - self.warn_dead_code(variant.id, variant.span, variant.ident.name, "constructed"); + self.warn_dead_code(variant.id, variant.span, variant.ident, "constructed", None); } else { intravisit::walk_variant(self, variant, g, id); } @@ -645,14 +681,20 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { fn visit_foreign_item(&mut self, fi: &'tcx hir::ForeignItem<'tcx>) { if self.should_warn_about_foreign_item(fi) { - self.warn_dead_code(fi.hir_id(), fi.span, fi.ident.name, "used"); + self.warn_dead_code(fi.hir_id(), fi.span, fi.ident, "used", None); } intravisit::walk_foreign_item(self, fi); } fn visit_field_def(&mut self, field: &'tcx hir::FieldDef<'tcx>) { if self.should_warn_about_field(&field) { - self.warn_dead_code(field.hir_id, field.span, field.ident.name, "read"); + self.warn_dead_code( + field.hir_id, + field.span, + field.ident, + "read", + Some(ExtraNote::OtherPurposeExamples), + ); } intravisit::walk_field_def(self, field); } @@ -664,8 +706,9 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { self.warn_dead_code( impl_item.hir_id(), impl_item.span, - impl_item.ident.name, + impl_item.ident, "used", + None, ); } self.visit_nested_body(body_id) @@ -683,7 +726,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { } else { impl_item.ident.span }; - self.warn_dead_code(impl_item.hir_id(), span, impl_item.ident.name, "used"); + self.warn_dead_code(impl_item.hir_id(), span, impl_item.ident, "used", None); } self.visit_nested_body(body_id) } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 87e28f7fcc592..c5f12c0c691b3 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -472,17 +472,6 @@ impl<'a> Resolver<'a> { ); err } - ResolutionError::ParamInAnonConstInTyDefault(name) => { - let mut err = self.session.struct_span_err( - span, - "constant values inside of type parameter defaults must not depend on generic parameters", - ); - err.span_label( - span, - format!("the anonymous constant must not depend on the parameter `{}`", name), - ); - err - } ResolutionError::ParamInNonTrivialAnonConst { name, is_type } => { let mut err = self.session.struct_span_err( span, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 9321f11f65933..92f21191de430 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -555,18 +555,23 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { // provide previous type parameters as they're built. We // put all the parameters on the ban list and then remove // them one by one as they are processed and become available. - let mut default_ban_rib = Rib::new(ForwardGenericParamBanRibKind); - let mut found_default = false; - default_ban_rib.bindings.extend(generics.params.iter().filter_map( - |param| match param.kind { - GenericParamKind::Type { default: Some(_), .. } - | GenericParamKind::Const { default: Some(_), .. } => { - found_default = true; - Some((Ident::with_dummy_span(param.ident.name), Res::Err)) + let mut forward_ty_ban_rib = Rib::new(ForwardGenericParamBanRibKind); + let mut forward_const_ban_rib = Rib::new(ForwardGenericParamBanRibKind); + for param in generics.params.iter() { + match param.kind { + GenericParamKind::Type { .. } => { + forward_ty_ban_rib + .bindings + .insert(Ident::with_dummy_span(param.ident.name), Res::Err); } - _ => None, - }, - )); + GenericParamKind::Const { .. } => { + forward_const_ban_rib + .bindings + .insert(Ident::with_dummy_span(param.ident.name), Res::Err); + } + GenericParamKind::Lifetime => {} + } + } // rust-lang/rust#61631: The type `Self` is essentially // another type parameter. For ADTs, we consider it @@ -579,7 +584,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { // such as in the case of `trait Add`.) if self.diagnostic_metadata.current_self_item.is_some() { // (`Some` if + only if we are in ADT's generics.) - default_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err); + forward_ty_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err); } for param in &generics.params { @@ -591,32 +596,38 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { } if let Some(ref ty) = default { - self.ribs[TypeNS].push(default_ban_rib); - self.with_rib(ValueNS, ForwardGenericParamBanRibKind, |this| { - // HACK: We use an empty `ForwardGenericParamBanRibKind` here which - // is only used to forbid the use of const parameters inside of - // type defaults. - // - // While the rib name doesn't really fit here, it does allow us to use the same - // code for both const and type parameters. - this.visit_ty(ty); - }); - default_ban_rib = self.ribs[TypeNS].pop().unwrap(); + self.ribs[TypeNS].push(forward_ty_ban_rib); + self.ribs[ValueNS].push(forward_const_ban_rib); + self.visit_ty(ty); + forward_const_ban_rib = self.ribs[ValueNS].pop().unwrap(); + forward_ty_ban_rib = self.ribs[TypeNS].pop().unwrap(); } // Allow all following defaults to refer to this type parameter. - default_ban_rib.bindings.remove(&Ident::with_dummy_span(param.ident.name)); + forward_ty_ban_rib.bindings.remove(&Ident::with_dummy_span(param.ident.name)); } - GenericParamKind::Const { ref ty, kw_span: _, default: _ } => { - // FIXME(const_generics_defaults): handle `default` value here - for bound in ¶m.bounds { - self.visit_param_bound(bound); - } + GenericParamKind::Const { ref ty, kw_span: _, ref default } => { + // Const parameters can't have param bounds. + assert!(param.bounds.is_empty()); + self.ribs[TypeNS].push(Rib::new(ConstParamTyRibKind)); self.ribs[ValueNS].push(Rib::new(ConstParamTyRibKind)); self.visit_ty(ty); self.ribs[TypeNS].pop().unwrap(); self.ribs[ValueNS].pop().unwrap(); + + if let Some(ref expr) = default { + self.ribs[TypeNS].push(forward_ty_ban_rib); + self.ribs[ValueNS].push(forward_const_ban_rib); + self.visit_anon_const(expr); + forward_const_ban_rib = self.ribs[ValueNS].pop().unwrap(); + forward_ty_ban_rib = self.ribs[TypeNS].pop().unwrap(); + } + + // Allow all following defaults to refer to this const parameter. + forward_const_ban_rib + .bindings + .remove(&Ident::with_dummy_span(param.ident.name)); } } } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 6fae6921fc9b2..e33c374f562e2 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -930,7 +930,14 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { let msg = "you might have meant to use `#![feature(trait_alias)]` instead of a \ `type` alias"; if let Some(span) = self.def_span(def_id) { - err.span_help(span, msg); + if let Ok(snip) = self.r.session.source_map().span_to_snippet(span) { + // The span contains a type alias so we should be able to + // replace `type` with `trait`. + let snip = snip.replacen("type", "trait", 1); + err.span_suggestion(span, msg, snip, Applicability::MaybeIncorrect); + } else { + err.span_help(span, msg); + } } else { err.help(msg); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 129954381c9ba..1d1969f7e78ab 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -239,8 +239,6 @@ enum ResolutionError<'a> { ForwardDeclaredTyParam, // FIXME(const_generics_defaults) /// ERROR E0770: the type of const parameters must not depend on other generic parameters. ParamInTyOfConstParam(Symbol), - /// constant values inside of type parameter defaults must not depend on generic parameters. - ParamInAnonConstInTyDefault(Symbol), /// generic parameters must not be used inside const evaluations. /// /// This error is only emitted when using `min_const_generics`. @@ -2672,26 +2670,18 @@ impl<'a> Resolver<'a> { } } Res::Def(DefKind::TyParam, _) | Res::SelfTy(..) => { - let mut in_ty_param_default = false; for rib in ribs { - let has_generic_params = match rib.kind { + let has_generic_params: HasGenericParams = match rib.kind { NormalRibKind | ClosureOrAsyncRibKind | AssocItemRibKind | ModuleRibKind(..) - | MacroDefinition(..) => { + | MacroDefinition(..) + | ForwardGenericParamBanRibKind => { // Nothing to do. Continue. continue; } - // We only forbid constant items if we are inside of type defaults, - // for example `struct Foo()]>` - ForwardGenericParamBanRibKind => { - // FIXME(const_generic_defaults): we may need to distinguish between - // being in type parameter defaults and const parameter defaults - in_ty_param_default = true; - continue; - } ConstantItemRibKind(trivial, _) => { let features = self.session.features_untracked(); // HACK(min_const_generics): We currently only allow `N` or `{ N }`. @@ -2720,19 +2710,7 @@ impl<'a> Resolver<'a> { } } - if in_ty_param_default { - if record_used { - self.report_error( - span, - ResolutionError::ParamInAnonConstInTyDefault( - rib_ident.name, - ), - ); - } - return Res::Err; - } else { - continue; - } + continue; } // This was an attempt to use a type parameter outside its scope. @@ -2770,23 +2748,15 @@ impl<'a> Resolver<'a> { ribs.next(); } - let mut in_ty_param_default = false; for rib in ribs { let has_generic_params = match rib.kind { NormalRibKind | ClosureOrAsyncRibKind | AssocItemRibKind | ModuleRibKind(..) - | MacroDefinition(..) => continue, - - // We only forbid constant items if we are inside of type defaults, - // for example `struct Foo()]>` - ForwardGenericParamBanRibKind => { - // FIXME(const_generic_defaults): we may need to distinguish between - // being in type parameter defaults and const parameter defaults - in_ty_param_default = true; - continue; - } + | MacroDefinition(..) + | ForwardGenericParamBanRibKind => continue, + ConstantItemRibKind(trivial, _) => { let features = self.session.features_untracked(); // HACK(min_const_generics): We currently only allow `N` or `{ N }`. @@ -2808,19 +2778,7 @@ impl<'a> Resolver<'a> { return Res::Err; } - if in_ty_param_default { - if record_used { - self.report_error( - span, - ResolutionError::ParamInAnonConstInTyDefault( - rib_ident.name, - ), - ); - } - return Res::Err; - } else { - continue; - } + continue; } ItemRibKind(has_generic_params) => has_generic_params, diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 29f1761b84d2b..38e5ce6fd831c 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -210,9 +210,9 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] { } } -fn associated_items(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssociatedItems<'_> { +fn associated_items(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItems<'_> { let items = tcx.associated_item_def_ids(def_id).iter().map(|did| tcx.associated_item(*did)); - ty::AssociatedItems::new(items) + ty::AssocItems::new(items) } fn def_ident_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option { diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index 7a297f2c65f13..2bbb38c294d57 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -286,7 +286,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ParamKindOrd::Const { unordered: tcx .features() - .const_generics, + .unordered_const_ty_params(), } } }, @@ -309,7 +309,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { GenericArg::Lifetime(_) => ParamKindOrd::Lifetime, GenericArg::Type(_) => ParamKindOrd::Type, GenericArg::Const(_) => ParamKindOrd::Const { - unordered: tcx.features().const_generics, + unordered: tcx + .features() + .unordered_const_ty_params(), }, }), Some(&format!( diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index b6de491911ab7..62a1584d16be0 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -513,7 +513,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { GenericParamDefKind::Const { has_default } => { let ty = tcx.at(self.span).type_of(param.def_id); if !infer_args && has_default { - tcx.const_param_default(param.def_id).into() + tcx.const_param_default(param.def_id) + .subst_spanned(tcx, substs.unwrap(), Some(self.span)) + .into() } else { if infer_args { self.astconv.ct_infer(ty, Some(param), self.span).into() diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 9ace455042103..a50f8e1c65599 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1446,7 +1446,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } GenericParamDefKind::Const { has_default, .. } => { if !infer_args && has_default { - tcx.const_param_default(param.def_id).into() + tcx.const_param_default(param.def_id) + .subst_spanned(tcx, substs.unwrap(), Some(self.span)) + .into() } else { self.fcx.var_for_def(self.span, param) } diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 887cc42a1dd27..26871d6f0285c 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -728,20 +728,36 @@ fn check_where_clauses<'tcx, 'fcx>( // // Here, the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold. for param in &generics.params { - if let GenericParamDefKind::Type { .. } = param.kind { - if is_our_default(¶m) { - let ty = fcx.tcx.type_of(param.def_id); - // Ignore dependent defaults -- that is, where the default of one type - // parameter includes another (e.g., ``). In those cases, we can't - // be sure if it will error or not as user might always specify the other. - if !ty.needs_subst() { + match param.kind { + GenericParamDefKind::Type { .. } => { + if is_our_default(¶m) { + let ty = fcx.tcx.type_of(param.def_id); + // Ignore dependent defaults -- that is, where the default of one type + // parameter includes another (e.g., ``). In those cases, we can't + // be sure if it will error or not as user might always specify the other. + if !ty.needs_subst() { + fcx.register_wf_obligation( + ty.into(), + fcx.tcx.def_span(param.def_id), + ObligationCauseCode::MiscObligation, + ); + } + } + } + GenericParamDefKind::Const { .. } => { + // FIXME(const_generics_defaults): Figure out if this + // is the behavior we want, see the comment further below. + if is_our_default(¶m) { + let default_ct = tcx.const_param_default(param.def_id); fcx.register_wf_obligation( - ty.into(), + default_ct.into(), fcx.tcx.def_span(param.def_id), ObligationCauseCode::MiscObligation, ); } } + // Doesn't have defaults. + GenericParamDefKind::Lifetime => {} } } @@ -774,14 +790,25 @@ fn check_where_clauses<'tcx, 'fcx>( fcx.tcx.mk_param_from_def(param) } GenericParamDefKind::Const { .. } => { + // FIXME(const_generics_defaults): I(@lcnr) feel like always + // using the const parameter is the right choice here, even + // if it needs substs. + // + // Before stabilizing this we probably want to get some tests + // where this makes a difference and figure out what's the exact + // behavior we want here. + + // If the param has a default, ... if is_our_default(param) { let default_ct = tcx.const_param_default(param.def_id); - // Const params currently have to be concrete. - assert!(!default_ct.needs_subst()); - default_ct.into() - } else { - fcx.tcx.mk_param_from_def(param) + // ... and it's not a dependent default, ... + if !default_ct.needs_subst() { + // ... then substitute it with the default. + return default_ct.into(); + } } + + fcx.tcx.mk_param_from_def(param) } } }); diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs index 2965409999202..c69389e7b432b 100644 --- a/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs @@ -24,8 +24,8 @@ impl InherentOverlapChecker<'tcx> { /// namespace. fn impls_have_common_items( &self, - impl_items1: &ty::AssociatedItems<'_>, - impl_items2: &ty::AssociatedItems<'_>, + impl_items1: &ty::AssocItems<'_>, + impl_items2: &ty::AssocItems<'_>, ) -> bool { let mut impl_items1 = &impl_items1; let mut impl_items2 = &impl_items2; diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 1477418d5d8cf..927d8c57191a7 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1316,13 +1316,13 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option Visitor<'v> for AnonConstInParamListDetector { +impl<'v> Visitor<'v> for AnonConstInParamTyDetector { type Map = intravisit::ErasedMap<'v>; fn nested_visit_map(&mut self) -> NestedVisitorMap { @@ -1330,15 +1330,17 @@ impl<'v> Visitor<'v> for AnonConstInParamListDetector { } fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) { - let prev = self.in_param_list; - self.in_param_list = true; - intravisit::walk_generic_param(self, p); - self.in_param_list = prev; + if let GenericParamKind::Const { ref ty, default: _ } = p.kind { + let prev = self.in_param_ty; + self.in_param_ty = true; + self.visit_ty(ty); + self.in_param_ty = prev; + } } fn visit_anon_const(&mut self, c: &'v hir::AnonConst) { - if self.in_param_list && self.ct == c.hir_id { - self.found_anon_const_in_list = true; + if self.in_param_ty && self.ct == c.hir_id { + self.found_anon_const_in_param_ty = true; } else { intravisit::walk_anon_const(self, c) } @@ -1366,27 +1368,24 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { let parent_id = tcx.hir().get_parent_item(hir_id); let parent_def_id = tcx.hir().local_def_id(parent_id); - let mut in_param_list = false; + let mut in_param_ty = false; for (_parent, node) in tcx.hir().parent_iter(hir_id) { if let Some(generics) = node.generics() { - let mut visitor = AnonConstInParamListDetector { - in_param_list: false, - found_anon_const_in_list: false, + let mut visitor = AnonConstInParamTyDetector { + in_param_ty: false, + found_anon_const_in_param_ty: false, ct: hir_id, }; visitor.visit_generics(generics); - in_param_list = visitor.found_anon_const_in_list; + in_param_ty = visitor.found_anon_const_in_param_ty; break; } } - if in_param_list { + if in_param_ty { // We do not allow generic parameters in anon consts if we are inside - // of a param list. - // - // This affects both default type bindings, e.g. `struct()]>(T, U)`, - // and the types of const parameters, e.g. `struct V();`. + // of a const parameter type, e.g. `struct Foo` is not allowed. None } else if tcx.lazy_normalization() { // HACK(eddyb) this provides the correct generics when diff --git a/library/core/benches/fmt.rs b/library/core/benches/fmt.rs index 2792181acc352..9df66263459b1 100644 --- a/library/core/benches/fmt.rs +++ b/library/core/benches/fmt.rs @@ -112,7 +112,7 @@ fn write_str_macro_debug(bh: &mut Bencher) { #[bench] fn write_u128_max(bh: &mut Bencher) { bh.iter(|| { - std::hint::black_box(format!("{}", u128::MAX)); + test::black_box(format!("{}", u128::MAX)); }); } @@ -120,20 +120,20 @@ fn write_u128_max(bh: &mut Bencher) { fn write_u128_min(bh: &mut Bencher) { bh.iter(|| { let s = format!("{}", 0u128); - std::hint::black_box(s); + test::black_box(s); }); } #[bench] fn write_u64_max(bh: &mut Bencher) { bh.iter(|| { - std::hint::black_box(format!("{}", u64::MAX)); + test::black_box(format!("{}", u64::MAX)); }); } #[bench] fn write_u64_min(bh: &mut Bencher) { bh.iter(|| { - std::hint::black_box(format!("{}", 0u64)); + test::black_box(format!("{}", 0u64)); }); } diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 313729581acd9..f7aec73644921 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -154,7 +154,7 @@ pub fn spin_loop() { /// [`std::convert::identity`]: crate::convert::identity #[cfg_attr(not(miri), inline)] #[cfg_attr(miri, inline(never))] -#[unstable(feature = "test", issue = "50297")] +#[unstable(feature = "bench_black_box", issue = "64102")] #[cfg_attr(miri, allow(unused_mut))] pub fn black_box(mut dummy: T) -> T { // We need to "use" the argument in some way LLVM can't introspect, and on diff --git a/library/core/src/iter/adapters/take.rs b/library/core/src/iter/adapters/take.rs index 9efc7a480aeb4..54a47f1323ebf 100644 --- a/library/core/src/iter/adapters/take.rs +++ b/library/core/src/iter/adapters/take.rs @@ -1,5 +1,8 @@ use crate::cmp; -use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen}; +use crate::iter::{ + adapters::zip::try_get_unchecked, adapters::SourceIter, FusedIterator, InPlaceIterable, + TrustedLen, TrustedRandomAccess, +}; use crate::ops::{ControlFlow, Try}; /// An iterator that only iterates over the first `n` iterations of `iter`. @@ -111,6 +114,15 @@ where self.try_fold(init, ok(fold)).unwrap() } + + unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> ::Item + where + Self: TrustedRandomAccess, + { + // SAFETY: the caller must uphold the contract for + // `Iterator::__iterator_get_unchecked`. + unsafe { try_get_unchecked(&mut self.iter, idx) } + } } #[unstable(issue = "none", feature = "inplace_iteration")] @@ -207,3 +219,12 @@ impl FusedIterator for Take where I: FusedIterator {} #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for Take {} + +#[doc(hidden)] +#[unstable(feature = "trusted_random_access", issue = "none")] +unsafe impl TrustedRandomAccess for Take +where + I: TrustedRandomAccess, +{ + const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT; +} diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index d0c52a4459190..9f8a6f3d3b54f 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -137,6 +137,7 @@ #![feature(stmt_expr_attributes)] #![feature(str_split_as_str)] #![feature(str_split_inclusive_as_str)] +#![feature(char_indices_offset)] #![feature(trait_alias)] #![feature(transparent_unions)] #![feature(try_blocks)] diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index c92b37b14be4f..f722430354991 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -81,6 +81,8 @@ mod private_slice_index { impl Sealed for ops::RangeInclusive {} #[stable(feature = "slice_get_slice", since = "1.28.0")] impl Sealed for ops::RangeToInclusive {} + #[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")] + impl Sealed for (ops::Bound, ops::Bound) {} } /// A helper trait used for indexing operations. @@ -546,3 +548,113 @@ where ops::Range { start, end } } + +/// Convert pair of `ops::Bound`s into `ops::Range` without performing any bounds checking and (in debug) overflow checking +fn into_range_unchecked( + len: usize, + (start, end): (ops::Bound, ops::Bound), +) -> ops::Range { + use ops::Bound; + let start = match start { + Bound::Included(i) => i, + Bound::Excluded(i) => i + 1, + Bound::Unbounded => 0, + }; + let end = match end { + Bound::Included(i) => i + 1, + Bound::Excluded(i) => i, + Bound::Unbounded => len, + }; + start..end +} + +/// Convert pair of `ops::Bound`s into `ops::Range`. +/// Returns `None` on overflowing indices. +fn into_range( + len: usize, + (start, end): (ops::Bound, ops::Bound), +) -> Option> { + use ops::Bound; + let start = match start { + Bound::Included(start) => start, + Bound::Excluded(start) => start.checked_add(1)?, + Bound::Unbounded => 0, + }; + + let end = match end { + Bound::Included(end) => end.checked_add(1)?, + Bound::Excluded(end) => end, + Bound::Unbounded => len, + }; + + // Don't bother with checking `start < end` and `end <= len` + // since these checks are handled by `Range` impls + + Some(start..end) +} + +/// Convert pair of `ops::Bound`s into `ops::Range`. +/// Panics on overflowing indices. +fn into_slice_range( + len: usize, + (start, end): (ops::Bound, ops::Bound), +) -> ops::Range { + use ops::Bound; + let start = match start { + Bound::Included(start) => start, + Bound::Excluded(start) => { + start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail()) + } + Bound::Unbounded => 0, + }; + + let end = match end { + Bound::Included(end) => { + end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail()) + } + Bound::Excluded(end) => end, + Bound::Unbounded => len, + }; + + // Don't bother with checking `start < end` and `end <= len` + // since these checks are handled by `Range` impls + + start..end +} + +#[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")] +unsafe impl SliceIndex<[T]> for (ops::Bound, ops::Bound) { + type Output = [T]; + + #[inline] + fn get(self, slice: &[T]) -> Option<&Self::Output> { + into_range(slice.len(), self)?.get(slice) + } + + #[inline] + fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> { + into_range(slice.len(), self)?.get_mut(slice) + } + + #[inline] + unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. + unsafe { into_range_unchecked(slice.len(), self).get_unchecked(slice) } + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. + unsafe { into_range_unchecked(slice.len(), self).get_unchecked_mut(slice) } + } + + #[inline] + fn index(self, slice: &[T]) -> &Self::Output { + into_slice_range(slice.len(), self).index(slice) + } + + #[inline] + fn index_mut(self, slice: &mut [T]) -> &mut Self::Output { + into_slice_range(slice.len(), self).index_mut(slice) + } +} diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs index 7ebff180f9d73..724137aba9f3c 100644 --- a/library/core/src/str/iter.rs +++ b/library/core/src/str/iter.rs @@ -189,6 +189,30 @@ impl<'a> CharIndices<'a> { pub fn as_str(&self) -> &'a str { self.iter.as_str() } + + /// Returns the byte position of the next character, or the length + /// of the underlying string if there are no more characters. + /// + /// # Examples + /// + /// ``` + /// #![feature(char_indices_offset)] + /// let mut chars = "a楽".char_indices(); + /// + /// assert_eq!(chars.offset(), 0); + /// assert_eq!(chars.next(), Some((0, 'a'))); + /// + /// assert_eq!(chars.offset(), 1); + /// assert_eq!(chars.next(), Some((1, '楽'))); + /// + /// assert_eq!(chars.offset(), 4); + /// assert_eq!(chars.next(), None); + /// ``` + #[inline] + #[unstable(feature = "char_indices_offset", issue = "83871")] + pub fn offset(&self) -> usize { + self.front_offset + } } /// An iterator over the bytes of a string slice. diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 7e198631cc7eb..3a98cd9d2ee91 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -1280,6 +1280,9 @@ mod slice_index { } )*) => {$( mod $case_name { + #[allow(unused_imports)] + use core::ops::Bound; + #[test] fn pass() { let mut v = $data; @@ -1376,6 +1379,24 @@ mod slice_index { bad: data[7..=6]; message: "out of range"; } + + in mod boundpair_len { + data: [0, 1, 2, 3, 4, 5]; + + good: data[(Bound::Included(6), Bound::Unbounded)] == []; + good: data[(Bound::Unbounded, Bound::Included(5))] == [0, 1, 2, 3, 4, 5]; + good: data[(Bound::Unbounded, Bound::Excluded(6))] == [0, 1, 2, 3, 4, 5]; + good: data[(Bound::Included(0), Bound::Included(5))] == [0, 1, 2, 3, 4, 5]; + good: data[(Bound::Included(0), Bound::Excluded(6))] == [0, 1, 2, 3, 4, 5]; + good: data[(Bound::Included(2), Bound::Excluded(4))] == [2, 3]; + good: data[(Bound::Excluded(1), Bound::Included(4))] == [2, 3, 4]; + good: data[(Bound::Excluded(5), Bound::Excluded(6))] == []; + good: data[(Bound::Included(6), Bound::Excluded(6))] == []; + good: data[(Bound::Excluded(5), Bound::Included(5))] == []; + good: data[(Bound::Included(6), Bound::Included(5))] == []; + bad: data[(Bound::Unbounded, Bound::Included(6))]; + message: "out of range"; + } } panic_cases! { @@ -1416,6 +1437,14 @@ mod slice_index { bad: data[4..=2]; message: "but ends at"; } + + in mod boundpair_neg_width { + data: [0, 1, 2, 3, 4, 5]; + + good: data[(Bound::Included(4), Bound::Excluded(4))] == []; + bad: data[(Bound::Included(4), Bound::Excluded(3))]; + message: "but ends at"; + } } panic_cases! { @@ -1434,6 +1463,20 @@ mod slice_index { bad: data[..= usize::MAX]; message: "maximum usize"; } + + in mod boundpair_overflow_end { + data: [0; 1]; + + bad: data[(Bound::Unbounded, Bound::Included(usize::MAX))]; + message: "maximum usize"; + } + + in mod boundpair_overflow_start { + data: [0; 1]; + + bad: data[(Bound::Excluded(usize::MAX), Bound::Unbounded)]; + message: "maximum usize"; + } } // panic_cases! } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 089d43483fcb3..0ab9f490fd420 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -233,6 +233,7 @@ #![feature(assert_matches)] #![feature(associated_type_bounds)] #![feature(atomic_mut_ptr)] +#![feature(bench_black_box)] #![feature(box_syntax)] #![feature(c_variadic)] #![feature(cfg_accessible)] diff --git a/library/std/src/sys/hermit/args.rs b/library/std/src/sys/hermit/args.rs index 7727293927282..17b27c50bb2d3 100644 --- a/library/std/src/sys/hermit/args.rs +++ b/library/std/src/sys/hermit/args.rs @@ -1,5 +1,4 @@ use crate::ffi::OsString; -use crate::marker::PhantomData; use crate::vec; /// One-time global initialization. @@ -19,7 +18,6 @@ pub fn args() -> Args { pub struct Args { iter: vec::IntoIter, - _dont_send_or_sync_me: PhantomData<*mut ()>, } impl Args { @@ -28,6 +26,9 @@ impl Args { } } +impl !Send for Args {} +impl !Sync for Args {} + impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { @@ -53,7 +54,6 @@ impl DoubleEndedIterator for Args { mod imp { use super::Args; use crate::ffi::{CStr, OsString}; - use crate::marker::PhantomData; use crate::ptr; use crate::sys_common::os_str_bytes::*; @@ -76,7 +76,7 @@ mod imp { } pub fn args() -> Args { - Args { iter: clone().into_iter(), _dont_send_or_sync_me: PhantomData } + Args { iter: clone().into_iter() } } fn clone() -> Vec { diff --git a/library/std/src/sys/hermit/os.rs b/library/std/src/sys/hermit/os.rs index 4487e9d636cb0..2d60c4f98ee50 100644 --- a/library/std/src/sys/hermit/os.rs +++ b/library/std/src/sys/hermit/os.rs @@ -3,7 +3,6 @@ use crate::error::Error as StdError; use crate::ffi::{CStr, OsStr, OsString}; use crate::fmt; use crate::io; -use crate::marker::PhantomData; use crate::memchr; use crate::path::{self, PathBuf}; use crate::str; @@ -110,9 +109,11 @@ pub fn init_environment(env: *const *const i8) { pub struct Env { iter: vec::IntoIter<(OsString, OsString)>, - _dont_send_or_sync_me: PhantomData<*mut ()>, } +impl !Send for Env {} +impl !Sync for Env {} + impl Iterator for Env { type Item = (OsString, OsString); fn next(&mut self) -> Option<(OsString, OsString)> { @@ -134,7 +135,7 @@ pub fn env() -> Env { result.push((key.clone(), value.clone())); } - return Env { iter: result.into_iter(), _dont_send_or_sync_me: PhantomData }; + return Env { iter: result.into_iter() }; } } diff --git a/library/std/src/sys/unix/args.rs b/library/std/src/sys/unix/args.rs index 6967647249390..4fca0d0752fe8 100644 --- a/library/std/src/sys/unix/args.rs +++ b/library/std/src/sys/unix/args.rs @@ -6,7 +6,6 @@ #![allow(dead_code)] // runtime init functions not used during testing use crate::ffi::OsString; -use crate::marker::PhantomData; use crate::vec; /// One-time global initialization. @@ -26,9 +25,11 @@ pub fn args() -> Args { pub struct Args { iter: vec::IntoIter, - _dont_send_or_sync_me: PhantomData<*mut ()>, } +impl !Send for Args {} +impl !Sync for Args {} + impl Args { pub fn inner_debug(&self) -> &[OsString] { self.iter.as_slice() @@ -76,7 +77,6 @@ impl DoubleEndedIterator for Args { mod imp { use super::Args; use crate::ffi::{CStr, OsString}; - use crate::marker::PhantomData; use crate::os::unix::prelude::*; use crate::ptr; use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering}; @@ -133,7 +133,7 @@ mod imp { } pub fn args() -> Args { - Args { iter: clone().into_iter(), _dont_send_or_sync_me: PhantomData } + Args { iter: clone().into_iter() } } fn clone() -> Vec { @@ -155,7 +155,6 @@ mod imp { mod imp { use super::Args; use crate::ffi::CStr; - use crate::marker::PhantomData; pub unsafe fn init(_argc: isize, _argv: *const *const u8) {} @@ -180,7 +179,7 @@ mod imp { }) .collect::>() }; - Args { iter: vec.into_iter(), _dont_send_or_sync_me: PhantomData } + Args { iter: vec.into_iter() } } // As _NSGetArgc and _NSGetArgv aren't mentioned in iOS docs @@ -247,6 +246,6 @@ mod imp { } } - Args { iter: res.into_iter(), _dont_send_or_sync_me: PhantomData } + Args { iter: res.into_iter() } } } diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs index bf649f6d76f81..7dfdca84f2549 100644 --- a/library/std/src/sys/unix/os.rs +++ b/library/std/src/sys/unix/os.rs @@ -12,7 +12,6 @@ use crate::ffi::{CStr, CString, OsStr, OsString}; use crate::fmt; use crate::io; use crate::iter; -use crate::marker::PhantomData; use crate::mem; use crate::memchr; use crate::path::{self, PathBuf}; @@ -460,9 +459,11 @@ pub fn current_exe() -> io::Result { pub struct Env { iter: vec::IntoIter<(OsString, OsString)>, - _dont_send_or_sync_me: PhantomData<*mut ()>, } +impl !Send for Env {} +impl !Sync for Env {} + impl Iterator for Env { type Item = (OsString, OsString); fn next(&mut self) -> Option<(OsString, OsString)> { @@ -510,7 +511,7 @@ pub fn env() -> Env { environ = environ.add(1); } } - return Env { iter: result.into_iter(), _dont_send_or_sync_me: PhantomData }; + return Env { iter: result.into_iter() }; } fn parse(input: &[u8]) -> Option<(OsString, OsString)> { diff --git a/library/std/src/sys/wasi/args.rs b/library/std/src/sys/wasi/args.rs index 9a27218e1fb70..61a9bd28fd812 100644 --- a/library/std/src/sys/wasi/args.rs +++ b/library/std/src/sys/wasi/args.rs @@ -1,7 +1,6 @@ #![deny(unsafe_op_in_unsafe_fn)] use crate::ffi::{CStr, OsStr, OsString}; -use crate::marker::PhantomData; use crate::os::wasi::ffi::OsStrExt; use crate::vec; @@ -11,15 +10,14 @@ pub unsafe fn cleanup() {} pub struct Args { iter: vec::IntoIter, - _dont_send_or_sync_me: PhantomData<*mut ()>, } +impl !Send for Args {} +impl !Sync for Args {} + /// Returns the command line arguments pub fn args() -> Args { - Args { - iter: maybe_args().unwrap_or(Vec::new()).into_iter(), - _dont_send_or_sync_me: PhantomData, - } + Args { iter: maybe_args().unwrap_or(Vec::new()).into_iter() } } fn maybe_args() -> Option> { diff --git a/library/std/src/sys/wasi/os.rs b/library/std/src/sys/wasi/os.rs index cf17ac0ba5f2b..78e97765693dc 100644 --- a/library/std/src/sys/wasi/os.rs +++ b/library/std/src/sys/wasi/os.rs @@ -5,7 +5,6 @@ use crate::error::Error as StdError; use crate::ffi::{CStr, CString, OsStr, OsString}; use crate::fmt; use crate::io; -use crate::marker::PhantomData; use crate::os::wasi::prelude::*; use crate::path::{self, PathBuf}; use crate::str; @@ -129,9 +128,11 @@ pub fn current_exe() -> io::Result { } pub struct Env { iter: vec::IntoIter<(OsString, OsString)>, - _dont_send_or_sync_me: PhantomData<*mut ()>, } +impl !Send for Env {} +impl !Sync for Env {} + impl Iterator for Env { type Item = (OsString, OsString); fn next(&mut self) -> Option<(OsString, OsString)> { @@ -155,7 +156,7 @@ pub fn env() -> Env { environ = environ.add(1); } } - return Env { iter: result.into_iter(), _dont_send_or_sync_me: PhantomData }; + return Env { iter: result.into_iter() }; } // See src/libstd/sys/unix/os.rs, same as that diff --git a/library/std/src/sys/wasm/args.rs b/library/std/src/sys/wasm/args.rs index 3b6557ae3257f..8c25a1d262a63 100644 --- a/library/std/src/sys/wasm/args.rs +++ b/library/std/src/sys/wasm/args.rs @@ -1,5 +1,4 @@ use crate::ffi::OsString; -use crate::marker::PhantomData; use crate::vec; pub unsafe fn init(_argc: isize, _argv: *const *const u8) { @@ -9,14 +8,16 @@ pub unsafe fn init(_argc: isize, _argv: *const *const u8) { pub unsafe fn cleanup() {} pub fn args() -> Args { - Args { iter: Vec::new().into_iter(), _dont_send_or_sync_me: PhantomData } + Args { iter: Vec::new().into_iter() } } pub struct Args { iter: vec::IntoIter, - _dont_send_or_sync_me: PhantomData<*mut ()>, } +impl !Send for Args {} +impl !Sync for Args {} + impl Args { pub fn inner_debug(&self) -> &[OsString] { self.iter.as_slice() diff --git a/library/test/src/bench.rs b/library/test/src/bench.rs index 169154187f250..7869ba2c04178 100644 --- a/library/test/src/bench.rs +++ b/library/test/src/bench.rs @@ -1,6 +1,4 @@ //! Benchmarking module. -pub use std::hint::black_box; - use super::{ event::CompletedTest, options::BenchMode, @@ -16,6 +14,15 @@ use std::panic::{catch_unwind, AssertUnwindSafe}; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; +/// An identity function that *__hints__* to the compiler to be maximally pessimistic about what +/// `black_box` could do. +/// +/// See [`std::hint::black_box`] for details. +#[inline(always)] +pub fn black_box(dummy: T) -> T { + std::hint::black_box(dummy) +} + /// Manager of the benchmarking runs. /// /// This is fed into functions marked with `#[bench]` to allow for diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index 2e0864f303cc9..9adc099aaa566 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -24,6 +24,7 @@ #![feature(rustc_private)] #![feature(nll)] #![feature(available_concurrency)] +#![feature(bench_black_box)] #![feature(internal_output_capture)] #![feature(panic_unwind)] #![feature(staged_api)] diff --git a/src/test/ui/associated-consts/associated-const-dead-code.stderr b/src/test/ui/associated-consts/associated-const-dead-code.stderr index 9b6bbb68a71f7..e9915ba9e96a5 100644 --- a/src/test/ui/associated-consts/associated-const-dead-code.stderr +++ b/src/test/ui/associated-consts/associated-const-dead-code.stderr @@ -2,8 +2,11 @@ error: associated constant is never used: `BAR` --> $DIR/associated-const-dead-code.rs:6:5 | LL | const BAR: u32 = 1; - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^---^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_BAR` | + = note: the leading underscore signals that this associated constant serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/associated-const-dead-code.rs:1:9 | diff --git a/src/test/ui/codemap_tests/two_files.stderr b/src/test/ui/codemap_tests/two_files.stderr index de2ffc2e5dc1d..aff51ee9e2f54 100644 --- a/src/test/ui/codemap_tests/two_files.stderr +++ b/src/test/ui/codemap_tests/two_files.stderr @@ -5,10 +5,9 @@ LL | impl Bar for Baz { } | ^^^ type aliases cannot be used as traits | help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` alias - --> $DIR/two_files_data.rs:5:1 | -LL | type Bar = dyn Foo; - | ^^^^^^^^^^^^^^^^^^^ +LL | trait Bar = dyn Foo; + | error: aborting due to previous error diff --git a/src/test/ui/const-generics/defaults/auxiliary/const_defaulty.rs b/src/test/ui/const-generics/defaults/auxiliary/const_defaulty.rs index 769b6e952dc9c..6514409698e3e 100644 --- a/src/test/ui/const-generics/defaults/auxiliary/const_defaulty.rs +++ b/src/test/ui/const-generics/defaults/auxiliary/const_defaulty.rs @@ -1,4 +1,4 @@ -#![feature(const_generics)] +#![cfg_attr(full, feature(const_generics))] #![feature(const_generics_defaults)] #![allow(incomplete_features)] diff --git a/src/test/ui/const-generics/defaults/complex-generic-default-expr.full.stderr b/src/test/ui/const-generics/defaults/complex-generic-default-expr.full.stderr new file mode 100644 index 0000000000000..e0e2b6c69f280 --- /dev/null +++ b/src/test/ui/const-generics/defaults/complex-generic-default-expr.full.stderr @@ -0,0 +1,18 @@ +error: constant expression depends on a generic parameter + --> $DIR/complex-generic-default-expr.rs:6:34 + | +LL | struct Foo; + | ^ + | + = note: this may fail depending on what value the parameter takes + +error: constant expression depends on a generic parameter + --> $DIR/complex-generic-default-expr.rs:10:21 + | +LL | struct Bar() }>(T); + | ^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/const-generics/defaults/complex-generic-default-expr.min.stderr b/src/test/ui/const-generics/defaults/complex-generic-default-expr.min.stderr new file mode 100644 index 0000000000000..58abd8db9f09f --- /dev/null +++ b/src/test/ui/const-generics/defaults/complex-generic-default-expr.min.stderr @@ -0,0 +1,20 @@ +error: generic parameters may not be used in const operations + --> $DIR/complex-generic-default-expr.rs:6:47 + | +LL | struct Foo; + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments, i.e. `N` + = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/complex-generic-default-expr.rs:10:62 + | +LL | struct Bar() }>(T); + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/const-generics/defaults/complex-generic-default-expr.rs b/src/test/ui/const-generics/defaults/complex-generic-default-expr.rs new file mode 100644 index 0000000000000..a7b712f7b4b86 --- /dev/null +++ b/src/test/ui/const-generics/defaults/complex-generic-default-expr.rs @@ -0,0 +1,14 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![feature(const_generics_defaults)] +#![allow(incomplete_features)] + +struct Foo; +//[full]~^ ERROR constant expression depends on a generic parameter +//[min]~^^ ERROR generic parameters may not be used in const operations + +struct Bar() }>(T); +//[full]~^ ERROR constant expression depends on a generic parameter +//[min]~^^ ERROR generic parameters may not be used in const operations + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/const-default.rs b/src/test/ui/const-generics/defaults/const-default.rs index 150c70770ae51..4fa21b8b1fb78 100644 --- a/src/test/ui/const-generics/defaults/const-default.rs +++ b/src/test/ui/const-generics/defaults/const-default.rs @@ -1,6 +1,6 @@ // run-pass - -#![feature(const_generics)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] #![feature(const_generics_defaults)] #![allow(incomplete_features)] diff --git a/src/test/ui/const-generics/defaults/const-param-as-default-value.rs b/src/test/ui/const-generics/defaults/const-param-as-default-value.rs new file mode 100644 index 0000000000000..59ac261f44fd5 --- /dev/null +++ b/src/test/ui/const-generics/defaults/const-param-as-default-value.rs @@ -0,0 +1,23 @@ +// run-pass +#![feature(const_generics_defaults)] +#![allow(incomplete_features)] +struct Foo([u8; N], [u8; M]); + +fn foo() -> Foo { + let x = [0; N]; + Foo(x, x) +} + +// To check that we actually apply the correct substs for const param defaults. +fn concrete_foo() -> Foo<13> { + Foo(Default::default(), Default::default()) +} + + +fn main() { + let val = foo::<13>(); + assert_eq!(val.0, val.1); + + let val = concrete_foo(); + assert_eq!(val.0, val.1); +} diff --git a/src/test/ui/const-generics/defaults/const-param-in-ty-defaults.rs b/src/test/ui/const-generics/defaults/const-param-in-ty-defaults.rs new file mode 100644 index 0000000000000..3f534ca0308ba --- /dev/null +++ b/src/test/ui/const-generics/defaults/const-param-in-ty-defaults.rs @@ -0,0 +1,14 @@ +// run-pass +#![feature(const_generics_defaults)] +#![allow(incomplete_features)] +struct Foo(T); + +impl Foo { + fn new() -> Self { + Foo([0; N]) + } +} + +fn main() { + assert_eq!(Foo::new().0, [0; 10]); +} diff --git a/src/test/ui/const-generics/defaults/default-on-impl.full.stderr b/src/test/ui/const-generics/defaults/default-on-impl.full.stderr new file mode 100644 index 0000000000000..c417a26842ed1 --- /dev/null +++ b/src/test/ui/const-generics/defaults/default-on-impl.full.stderr @@ -0,0 +1,8 @@ +error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions + --> $DIR/default-on-impl.rs:8:12 + | +LL | impl Foo {} + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/defaults/default-on-impl.min.stderr b/src/test/ui/const-generics/defaults/default-on-impl.min.stderr new file mode 100644 index 0000000000000..c417a26842ed1 --- /dev/null +++ b/src/test/ui/const-generics/defaults/default-on-impl.min.stderr @@ -0,0 +1,8 @@ +error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions + --> $DIR/default-on-impl.rs:8:12 + | +LL | impl Foo {} + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/defaults/default-on-impl.rs b/src/test/ui/const-generics/defaults/default-on-impl.rs new file mode 100644 index 0000000000000..735549defeaf0 --- /dev/null +++ b/src/test/ui/const-generics/defaults/default-on-impl.rs @@ -0,0 +1,11 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![feature(const_generics_defaults)] +#![allow(incomplete_features)] + +struct Foo; + +impl Foo {} +//~^ ERROR defaults for const parameters are only allowed + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/default-param-wf-concrete.rs b/src/test/ui/const-generics/defaults/default-param-wf-concrete.rs new file mode 100644 index 0000000000000..4bb56c6a1c08c --- /dev/null +++ b/src/test/ui/const-generics/defaults/default-param-wf-concrete.rs @@ -0,0 +1,5 @@ +#![feature(const_generics_defaults)] +#![allow(incomplete_features)] +struct Foo; +//~^ ERROR evaluation of constant value failed +fn main() {} diff --git a/src/test/ui/const-generics/defaults/default-param-wf-concrete.stderr b/src/test/ui/const-generics/defaults/default-param-wf-concrete.stderr new file mode 100644 index 0000000000000..8464ea98bf695 --- /dev/null +++ b/src/test/ui/const-generics/defaults/default-param-wf-concrete.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/default-param-wf-concrete.rs:3:28 + | +LL | struct Foo; + | ^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-generics/defaults/external.rs b/src/test/ui/const-generics/defaults/external.rs index b39e69ab10b66..32acf567cf2b9 100644 --- a/src/test/ui/const-generics/defaults/external.rs +++ b/src/test/ui/const-generics/defaults/external.rs @@ -1,5 +1,7 @@ // aux-build:const_defaulty.rs // check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] #![feature(const_generics_defaults)] #![allow(incomplete_features)] diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.full.stderr b/src/test/ui/const-generics/defaults/intermixed-lifetime.full.stderr index c4a666a829d8c..29d835e36c6eb 100644 --- a/src/test/ui/const-generics/defaults/intermixed-lifetime.full.stderr +++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.full.stderr @@ -1,5 +1,5 @@ error: lifetime parameters must be declared prior to const parameters - --> $DIR/intermixed-lifetime.rs:6:28 + --> $DIR/intermixed-lifetime.rs:7:28 | LL | struct Foo(&'a (), T); | -----------------^^---------- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T = u32>` diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr b/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr index 69a490978d1df..985e7b655ece9 100644 --- a/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr +++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr @@ -1,26 +1,14 @@ error: lifetime parameters must be declared prior to const parameters - --> $DIR/intermixed-lifetime.rs:6:28 + --> $DIR/intermixed-lifetime.rs:7:28 | LL | struct Foo(&'a (), T); - | -----------------^^---------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>` + | -----------------^^---------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const N: usize, T = u32>` -error: type parameters must be declared prior to const parameters - --> $DIR/intermixed-lifetime.rs:6:32 - | -LL | struct Foo(&'a (), T); - | ---------------------^------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>` - -error: lifetime parameters must be declared prior to const parameters +error: lifetime parameters must be declared prior to type parameters --> $DIR/intermixed-lifetime.rs:10:37 | LL | struct Bar(&'a (), T); - | --------------------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>` - -error: type parameters must be declared prior to const parameters - --> $DIR/intermixed-lifetime.rs:10:28 - | -LL | struct Bar(&'a (), T); - | -----------------^----------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>` + | --------------------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const N: usize, T = u32>` -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.rs b/src/test/ui/const-generics/defaults/intermixed-lifetime.rs index 9e83bf92a59b9..307e3aaf1fbf3 100644 --- a/src/test/ui/const-generics/defaults/intermixed-lifetime.rs +++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.rs @@ -1,15 +1,13 @@ -// revisions: full min // Checks that lifetimes cannot be interspersed between consts and types. +// revisions: full min #![cfg_attr(full, feature(const_generics))] -#![cfg_attr(full, allow(incomplete_features))] +#![feature(const_generics_defaults)] +#![allow(incomplete_features)] struct Foo(&'a (), T); //~^ Error lifetime parameters must be declared prior to const parameters -//[min]~^^ Error type parameters must be declared prior to const parameters struct Bar(&'a (), T); -//[full]~^ Error lifetime parameters must be declared prior to type parameters -//[min]~^^ Error type parameters must be declared prior to const parameters -//[min]~| Error lifetime parameters must be declared prior to const parameters +//~^ Error lifetime parameters must be declared prior to type parameters fn main() {} diff --git a/src/test/ui/const-generics/defaults/mismatch.stderr b/src/test/ui/const-generics/defaults/mismatch.full.stderr similarity index 90% rename from src/test/ui/const-generics/defaults/mismatch.stderr rename to src/test/ui/const-generics/defaults/mismatch.full.stderr index ff72c71c40f0f..be4f364d8ee62 100644 --- a/src/test/ui/const-generics/defaults/mismatch.stderr +++ b/src/test/ui/const-generics/defaults/mismatch.full.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/mismatch.rs:11:28 + --> $DIR/mismatch.rs:12:28 | LL | let e: Example::<13> = (); | ------------- ^^ expected struct `Example`, found `()` @@ -7,7 +7,7 @@ LL | let e: Example::<13> = (); | expected due to this error[E0308]: mismatched types - --> $DIR/mismatch.rs:13:34 + --> $DIR/mismatch.rs:14:34 | LL | let e: Example2:: = (); | ------------------- ^^ expected struct `Example2`, found `()` @@ -18,7 +18,7 @@ LL | let e: Example2:: = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:15:34 + --> $DIR/mismatch.rs:16:34 | LL | let e: Example3::<13, u32> = (); | ------------------- ^^ expected struct `Example3`, found `()` @@ -29,7 +29,7 @@ LL | let e: Example3::<13, u32> = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:17:28 + --> $DIR/mismatch.rs:18:28 | LL | let e: Example3::<7> = (); | ------------- ^^ expected struct `Example3`, found `()` @@ -40,7 +40,7 @@ LL | let e: Example3::<7> = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:21:28 + --> $DIR/mismatch.rs:22:28 | LL | let e: Example4::<7> = (); | ------------- ^^ expected struct `Example4`, found `()` diff --git a/src/test/ui/const-generics/defaults/mismatch.min.stderr b/src/test/ui/const-generics/defaults/mismatch.min.stderr new file mode 100644 index 0000000000000..be4f364d8ee62 --- /dev/null +++ b/src/test/ui/const-generics/defaults/mismatch.min.stderr @@ -0,0 +1,52 @@ +error[E0308]: mismatched types + --> $DIR/mismatch.rs:12:28 + | +LL | let e: Example::<13> = (); + | ------------- ^^ expected struct `Example`, found `()` + | | + | expected due to this + +error[E0308]: mismatched types + --> $DIR/mismatch.rs:14:34 + | +LL | let e: Example2:: = (); + | ------------------- ^^ expected struct `Example2`, found `()` + | | + | expected due to this + | + = note: expected struct `Example2` + found unit type `()` + +error[E0308]: mismatched types + --> $DIR/mismatch.rs:16:34 + | +LL | let e: Example3::<13, u32> = (); + | ------------------- ^^ expected struct `Example3`, found `()` + | | + | expected due to this + | + = note: expected struct `Example3` + found unit type `()` + +error[E0308]: mismatched types + --> $DIR/mismatch.rs:18:28 + | +LL | let e: Example3::<7> = (); + | ------------- ^^ expected struct `Example3`, found `()` + | | + | expected due to this + | + = note: expected struct `Example3<7_usize>` + found unit type `()` + +error[E0308]: mismatched types + --> $DIR/mismatch.rs:22:28 + | +LL | let e: Example4::<7> = (); + | ------------- ^^ expected struct `Example4`, found `()` + | | + | expected due to this + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/defaults/mismatch.rs b/src/test/ui/const-generics/defaults/mismatch.rs index d85b756f538dc..68a640c0a08b3 100644 --- a/src/test/ui/const-generics/defaults/mismatch.rs +++ b/src/test/ui/const-generics/defaults/mismatch.rs @@ -1,4 +1,5 @@ -#![feature(const_generics)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] #![feature(const_generics_defaults)] #![allow(incomplete_features)] diff --git a/src/test/ui/const-generics/defaults/pretty-printing-ast.rs b/src/test/ui/const-generics/defaults/pretty-printing-ast.rs index a25d4baca1a97..7a57950dfc924 100644 --- a/src/test/ui/const-generics/defaults/pretty-printing-ast.rs +++ b/src/test/ui/const-generics/defaults/pretty-printing-ast.rs @@ -10,4 +10,4 @@ trait Foo {} fn foo() {} -struct Range; +struct Range; diff --git a/src/test/ui/const-generics/defaults/pretty-printing-ast.stdout b/src/test/ui/const-generics/defaults/pretty-printing-ast.stdout index f7a1d2ca4b2ef..f549993c413d4 100644 --- a/src/test/ui/const-generics/defaults/pretty-printing-ast.stdout +++ b/src/test/ui/const-generics/defaults/pretty-printing-ast.stdout @@ -17,4 +17,4 @@ trait Foo { } fn foo() { } struct Range; + FROM>; diff --git a/src/test/ui/const-generics/defaults/repr-c-issue-82792.rs b/src/test/ui/const-generics/defaults/repr-c-issue-82792.rs index 18ecf46729977..c64c2974c8f8f 100644 --- a/src/test/ui/const-generics/defaults/repr-c-issue-82792.rs +++ b/src/test/ui/const-generics/defaults/repr-c-issue-82792.rs @@ -6,7 +6,7 @@ #![allow(incomplete_features)] #[repr(C)] -pub struct Loaf { +pub struct Loaf { head: [T; N], slice: [T], } diff --git a/src/test/ui/const-generics/defaults/simple-defaults.min.stderr b/src/test/ui/const-generics/defaults/simple-defaults.min.stderr deleted file mode 100644 index 0746c64ac8cf4..0000000000000 --- a/src/test/ui/const-generics/defaults/simple-defaults.min.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: type parameters must be declared prior to const parameters - --> $DIR/simple-defaults.rs:8:40 - | -LL | struct FixedOutput<'a, const N: usize, T=u32> { - | ---------------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>` - -error: aborting due to previous error - diff --git a/src/test/ui/const-generics/defaults/simple-defaults.rs b/src/test/ui/const-generics/defaults/simple-defaults.rs index cb66c7769bb23..c003cb2c5a6ee 100644 --- a/src/test/ui/const-generics/defaults/simple-defaults.rs +++ b/src/test/ui/const-generics/defaults/simple-defaults.rs @@ -1,12 +1,12 @@ -// [full] run-pass -// revisions: min full -// Checks some basic test cases for defaults. +// run-pass +// Checks that type param defaults are allowed after const params. +// revisions: full min #![cfg_attr(full, feature(const_generics))] -#![cfg_attr(full, allow(incomplete_features))] +#![feature(const_generics_defaults)] +#![allow(incomplete_features)] #![allow(dead_code)] struct FixedOutput<'a, const N: usize, T=u32> { - //[min]~^ ERROR type parameters must be declared prior to const parameters out: &'a [T; N], } diff --git a/src/test/ui/const-generics/defaults/type-default-const-param-name.rs b/src/test/ui/const-generics/defaults/type-default-const-param-name.rs new file mode 100644 index 0000000000000..e68075ee3c627 --- /dev/null +++ b/src/test/ui/const-generics/defaults/type-default-const-param-name.rs @@ -0,0 +1,19 @@ +// check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![feature(const_generics_defaults)] +#![allow(incomplete_features)] + +struct N; + +struct Foo(T); + +impl Foo { + fn new() -> Self { + Foo(N) + } +} + +fn main() { + let Foo::<1, N>(N) = Foo::new(); +} diff --git a/src/test/ui/const-generics/defaults/wrong-order.full.stderr b/src/test/ui/const-generics/defaults/wrong-order.full.stderr index accc73134d899..eb0bcb2821556 100644 --- a/src/test/ui/const-generics/defaults/wrong-order.full.stderr +++ b/src/test/ui/const-generics/defaults/wrong-order.full.stderr @@ -1,19 +1,8 @@ error: generic parameters with a default must be trailing - --> $DIR/wrong-order.rs:4:10 + --> $DIR/wrong-order.rs:6:10 | LL | struct A { | ^ - | - = note: using type defaults and const parameters in the same parameter list is currently not permitted - -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/wrong-order.rs:2:27 - | -LL | #![cfg_attr(full, feature(const_generics))] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 for more information -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/src/test/ui/const-generics/defaults/wrong-order.min.stderr b/src/test/ui/const-generics/defaults/wrong-order.min.stderr index c8f1d471b244b..eb0bcb2821556 100644 --- a/src/test/ui/const-generics/defaults/wrong-order.min.stderr +++ b/src/test/ui/const-generics/defaults/wrong-order.min.stderr @@ -1,10 +1,8 @@ error: generic parameters with a default must be trailing - --> $DIR/wrong-order.rs:4:10 + --> $DIR/wrong-order.rs:6:10 | LL | struct A { | ^ - | - = note: using type defaults and const parameters in the same parameter list is currently not permitted error: aborting due to previous error diff --git a/src/test/ui/const-generics/defaults/wrong-order.rs b/src/test/ui/const-generics/defaults/wrong-order.rs index 5c2d9b8ad4751..88e9e96ba43f9 100644 --- a/src/test/ui/const-generics/defaults/wrong-order.rs +++ b/src/test/ui/const-generics/defaults/wrong-order.rs @@ -1,5 +1,7 @@ // revisions: full min -#![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete +#![cfg_attr(full, feature(const_generics))] +#![feature(const_generics_defaults)] +#![allow(incomplete_features)] struct A { //~^ ERROR generic parameters with a default must be trailing diff --git a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr index c2b7b206653a6..e8fd9e7769b79 100644 --- a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr +++ b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr @@ -1,22 +1,17 @@ error: generic parameters with a default must be trailing - --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:11:12 + --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:8:12 | LL | struct Bar(T); | ^ | = note: using type defaults and const parameters in the same parameter list is currently not permitted -error: constant values inside of type parameter defaults must not depend on generic parameters - --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:6:44 - | -LL | struct Foo()]>(T, U); - | ^ the anonymous constant must not depend on the parameter `T` - -error: constant values inside of type parameter defaults must not depend on generic parameters - --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:11:21 +error[E0128]: generic parameters with a default cannot use forward declared identifiers + --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:8:21 | LL | struct Bar(T); - | ^ the anonymous constant must not depend on the parameter `N` + | ^ defaulted generic parameters cannot be forward declared -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0128`. diff --git a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr index 4a462c328bf64..5fa6423306c5a 100644 --- a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr +++ b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr @@ -1,5 +1,5 @@ error: generic parameters with a default must be trailing - --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:11:12 + --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:8:12 | LL | struct Bar(T); | ^ @@ -7,7 +7,7 @@ LL | struct Bar(T); = note: using type defaults and const parameters in the same parameter list is currently not permitted error: generic parameters may not be used in const operations - --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:6:44 + --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:5:44 | LL | struct Foo()]>(T, U); | ^ cannot perform const operation using `T` @@ -15,11 +15,12 @@ LL | struct Foo()]>(T, U); = note: type parameters may not be used in const expressions = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions -error: constant values inside of type parameter defaults must not depend on generic parameters - --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:11:21 +error[E0128]: generic parameters with a default cannot use forward declared identifiers + --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:8:21 | LL | struct Bar(T); - | ^ the anonymous constant must not depend on the parameter `N` + | ^ defaulted generic parameters cannot be forward declared error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0128`. diff --git a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs index c7be8bdaf9c3d..76c1b84aef557 100644 --- a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs +++ b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs @@ -1,15 +1,12 @@ // revisions: full min - #![cfg_attr(full, feature(const_generics))] #![cfg_attr(full, allow(incomplete_features))] struct Foo()]>(T, U); -//[full]~^ ERROR constant values inside of type parameter defaults -//[min]~^^ ERROR generic parameters may not be used in const operations +//[min]~^ ERROR generic parameters may not be used in const operations -// FIXME(const_generics_defaults): We still don't know how to deal with type defaults. struct Bar(T); -//~^ ERROR constant values inside of type parameter defaults +//~^ ERROR generic parameters with a default cannot use forward declared identifiers //~| ERROR generic parameters with a default fn main() {} diff --git a/src/test/ui/consts/cast-discriminant-zst-enum.rs b/src/test/ui/consts/cast-discriminant-zst-enum.rs index 9c02d232e134b..66b76627c02e6 100644 --- a/src/test/ui/consts/cast-discriminant-zst-enum.rs +++ b/src/test/ui/consts/cast-discriminant-zst-enum.rs @@ -1,6 +1,6 @@ // run-pass // Test a ZST enum whose dicriminant is ~0i128. This caused an ICE when casting to a i32. -#![feature(test)] +#![feature(bench_black_box)] use std::hint::black_box; #[derive(Copy, Clone)] diff --git a/src/test/ui/consts/const_discriminant.rs b/src/test/ui/consts/const_discriminant.rs index d016d236dbf81..a47f6af02965b 100644 --- a/src/test/ui/consts/const_discriminant.rs +++ b/src/test/ui/consts/const_discriminant.rs @@ -1,6 +1,6 @@ // run-pass #![feature(const_discriminant)] -#![feature(test)] +#![feature(bench_black_box)] #![allow(dead_code)] use std::mem::{discriminant, Discriminant}; diff --git a/src/test/ui/derive-uninhabited-enum-38885.stderr b/src/test/ui/derive-uninhabited-enum-38885.stderr index 72607629d3c10..ff8fb9953fb53 100644 --- a/src/test/ui/derive-uninhabited-enum-38885.stderr +++ b/src/test/ui/derive-uninhabited-enum-38885.stderr @@ -2,8 +2,11 @@ warning: variant is never constructed: `Void` --> $DIR/derive-uninhabited-enum-38885.rs:13:5 | LL | Void(Void), - | ^^^^^^^^^^ + | ----^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_Void` | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. = note: `-W dead-code` implied by `-W unused` warning: 1 warning emitted diff --git a/src/test/ui/generics/generic-non-trailing-defaults.rs b/src/test/ui/generics/generic-non-trailing-defaults.rs index cb2bb2832b70e..16ea71d48c825 100644 --- a/src/test/ui/generics/generic-non-trailing-defaults.rs +++ b/src/test/ui/generics/generic-non-trailing-defaults.rs @@ -5,5 +5,6 @@ struct Vec(A, T); struct Foo, C>(A, B, C); //~^ ERROR generic parameters with a default must be trailing +//~| ERROR generic parameters with a default cannot use fn main() {} diff --git a/src/test/ui/generics/generic-non-trailing-defaults.stderr b/src/test/ui/generics/generic-non-trailing-defaults.stderr index 6d76861750335..713ba091b861c 100644 --- a/src/test/ui/generics/generic-non-trailing-defaults.stderr +++ b/src/test/ui/generics/generic-non-trailing-defaults.stderr @@ -10,5 +10,12 @@ error: generic parameters with a default must be trailing LL | struct Foo, C>(A, B, C); | ^ -error: aborting due to 2 previous errors +error[E0128]: generic parameters with a default cannot use forward declared identifiers + --> $DIR/generic-non-trailing-defaults.rs:6:23 + | +LL | struct Foo, C>(A, B, C); + | ^ defaulted generic parameters cannot be forward declared + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0128`. diff --git a/src/test/ui/issues/issue-37515.stderr b/src/test/ui/issues/issue-37515.stderr index 204a39bc8e8e9..3223554a5b778 100644 --- a/src/test/ui/issues/issue-37515.stderr +++ b/src/test/ui/issues/issue-37515.stderr @@ -2,8 +2,11 @@ warning: type alias is never used: `Z` --> $DIR/issue-37515.rs:5:1 | LL | type Z = dyn for<'x> Send; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^-^^^^^^^^^^^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_Z` | + = note: the leading underscore signals that this type alias serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/issue-37515.rs:3:9 | diff --git a/src/test/ui/lint/dead-code/basic.stderr b/src/test/ui/lint/dead-code/basic.stderr index f7b9b9c613ae0..8264d0736e03e 100644 --- a/src/test/ui/lint/dead-code/basic.stderr +++ b/src/test/ui/lint/dead-code/basic.stderr @@ -2,8 +2,9 @@ error: function is never used: `foo` --> $DIR/basic.rs:4:4 | LL | fn foo() { - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_foo` | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/basic.rs:1:9 | diff --git a/src/test/ui/lint/dead-code/const-and-self.stderr b/src/test/ui/lint/dead-code/const-and-self.stderr index c0e406189e8ab..e7233f386cc68 100644 --- a/src/test/ui/lint/dead-code/const-and-self.stderr +++ b/src/test/ui/lint/dead-code/const-and-self.stderr @@ -2,8 +2,9 @@ warning: variant is never constructed: `B` --> $DIR/const-and-self.rs:33:5 | LL | B, - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_B` | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/const-and-self.rs:3:9 | @@ -14,7 +15,9 @@ warning: variant is never constructed: `C` --> $DIR/const-and-self.rs:34:5 | LL | C, - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_C` + | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. warning: 2 warnings emitted diff --git a/src/test/ui/lint/dead-code/drop-only-field-issue-81658.rs b/src/test/ui/lint/dead-code/drop-only-field-issue-81658.rs new file mode 100644 index 0000000000000..d28b6430bc587 --- /dev/null +++ b/src/test/ui/lint/dead-code/drop-only-field-issue-81658.rs @@ -0,0 +1,42 @@ +//! The field `guard` is never used directly, but it is still useful for its side effect when +//! dropped. Since rustc doesn't consider a `Drop` impl as a use, we want to make sure we at least +//! produce a helpful diagnostic that points the user to what they can do if they indeed intended to +//! have a field that is only used for its `Drop` side effect. +//! +//! Issue: https://github.com/rust-lang/rust/issues/81658 + +#![deny(dead_code)] + +use std::sync::{Mutex, MutexGuard}; + +/// Holds a locked value until it is dropped +pub struct Locked<'a, T> { + // Field is kept for its affect when dropped, but otherwise unused + guard: MutexGuard<'a, T>, //~ ERROR field is never read +} + +impl<'a, T> Locked<'a, T> { + pub fn new(value: &'a Mutex) -> Self { + Self { + guard: value.lock().unwrap(), + } + } +} + +fn main() { + let items = Mutex::new(vec![1, 2, 3]); + + // Hold a lock on items while doing something else + let result = { + // The lock will be released at the end of this scope + let _lock = Locked::new(&items); + + do_something_else() + }; + + println!("{}", result); +} + +fn do_something_else() -> i32 { + 1 + 1 +} diff --git a/src/test/ui/lint/dead-code/drop-only-field-issue-81658.stderr b/src/test/ui/lint/dead-code/drop-only-field-issue-81658.stderr new file mode 100644 index 0000000000000..f379a0941166f --- /dev/null +++ b/src/test/ui/lint/dead-code/drop-only-field-issue-81658.stderr @@ -0,0 +1,17 @@ +error: field is never read: `guard` + --> $DIR/drop-only-field-issue-81658.rs:15:5 + | +LL | guard: MutexGuard<'a, T>, + | -----^^^^^^^^^^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_guard` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) +note: the lint level is defined here + --> $DIR/drop-only-field-issue-81658.rs:8:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/dead-code/empty-unused-enum.stderr b/src/test/ui/lint/dead-code/empty-unused-enum.stderr index ed9a7ccd14b21..5c06cd5a6a0b2 100644 --- a/src/test/ui/lint/dead-code/empty-unused-enum.stderr +++ b/src/test/ui/lint/dead-code/empty-unused-enum.stderr @@ -2,8 +2,9 @@ error: enum is never used: `E` --> $DIR/empty-unused-enum.rs:3:6 | LL | enum E {} - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_E` | + = note: the leading underscore signals that this enum serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/empty-unused-enum.rs:1:9 | diff --git a/src/test/ui/lint/dead-code/field-used-in-ffi-issue-81658.rs b/src/test/ui/lint/dead-code/field-used-in-ffi-issue-81658.rs new file mode 100644 index 0000000000000..12eafe6ae4958 --- /dev/null +++ b/src/test/ui/lint/dead-code/field-used-in-ffi-issue-81658.rs @@ -0,0 +1,50 @@ +//! The field `items` is being "used" by FFI (implicitly through pointers). However, since rustc +//! doesn't know how to detect that, we produce a message that says the field is unused. This can +//! cause some confusion and we want to make sure our diagnostics help as much as they can. +//! +//! Issue: https://github.com/rust-lang/rust/issues/81658 + +#![deny(dead_code)] + +/// A struct for holding on to data while it is being used in our FFI code +pub struct FFIData { + /// These values cannot be dropped while the pointers to each item + /// are still in use + items: Option>, //~ ERROR field is never read +} + +impl FFIData { + pub fn new() -> Self { + Self {items: None} + } + + /// Load items into this type and return pointers to each item that can + /// be passed to FFI + pub fn load(&mut self, items: Vec) -> Vec<*const T> { + let ptrs = items.iter().map(|item| item as *const _).collect(); + + self.items = Some(items); + + ptrs + } +} + +extern { + /// The FFI code that uses items + fn process_item(item: *const i32); +} + +fn main() { + // Data cannot be dropped until the end of this scope or else the items + // will be dropped before they are processed + let mut data = FFIData::new(); + + let ptrs = data.load(vec![1, 2, 3, 4, 5]); + + for ptr in ptrs { + // Safety: This pointer is valid as long as the arena is in scope + unsafe { process_item(ptr); } + } + + // Items will be safely freed at the end of this scope +} diff --git a/src/test/ui/lint/dead-code/field-used-in-ffi-issue-81658.stderr b/src/test/ui/lint/dead-code/field-used-in-ffi-issue-81658.stderr new file mode 100644 index 0000000000000..d6a247d98e292 --- /dev/null +++ b/src/test/ui/lint/dead-code/field-used-in-ffi-issue-81658.stderr @@ -0,0 +1,17 @@ +error: field is never read: `items` + --> $DIR/field-used-in-ffi-issue-81658.rs:13:5 + | +LL | items: Option>, + | -----^^^^^^^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_items` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) +note: the lint level is defined here + --> $DIR/field-used-in-ffi-issue-81658.rs:7:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/dead-code/impl-trait.stderr b/src/test/ui/lint/dead-code/impl-trait.stderr index 09b6d08eb8fb8..fb18eb2819f76 100644 --- a/src/test/ui/lint/dead-code/impl-trait.stderr +++ b/src/test/ui/lint/dead-code/impl-trait.stderr @@ -2,8 +2,11 @@ error: type alias is never used: `Unused` --> $DIR/impl-trait.rs:12:1 | LL | type Unused = (); - | ^^^^^^^^^^^^^^^^^ + | ^^^^^------^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_Unused` | + = note: the leading underscore signals that this type alias serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/impl-trait.rs:1:9 | diff --git a/src/test/ui/lint/dead-code/lint-dead-code-1.stderr b/src/test/ui/lint/dead-code/lint-dead-code-1.stderr index af97ea98b2b6d..15448448e1169 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-1.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-1.stderr @@ -2,8 +2,9 @@ error: struct is never constructed: `Bar` --> $DIR/lint-dead-code-1.rs:12:16 | LL | pub struct Bar; - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_Bar` | + = note: the leading underscore signals that this struct serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/lint-dead-code-1.rs:5:9 | @@ -14,55 +15,77 @@ error: static is never used: `priv_static` --> $DIR/lint-dead-code-1.rs:20:1 | LL | static priv_static: isize = 0; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^-----------^^^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_priv_static` + | + = note: the leading underscore signals that this static serves some other purpose even if it isn't used in a way that we can detect. error: constant is never used: `priv_const` --> $DIR/lint-dead-code-1.rs:27:1 | LL | const priv_const: isize = 0; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^----------^^^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_priv_const` + | + = note: the leading underscore signals that this constant serves some other purpose even if it isn't used in a way that we can detect. error: struct is never constructed: `PrivStruct` --> $DIR/lint-dead-code-1.rs:35:8 | LL | struct PrivStruct; - | ^^^^^^^^^^ + | ^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_PrivStruct` + | + = note: the leading underscore signals that this struct serves some other purpose even if it isn't used in a way that we can detect. error: enum is never used: `priv_enum` --> $DIR/lint-dead-code-1.rs:64:6 | LL | enum priv_enum { foo2, bar2 } - | ^^^^^^^^^ + | ^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_priv_enum` + | + = note: the leading underscore signals that this enum serves some other purpose even if it isn't used in a way that we can detect. error: variant is never constructed: `bar3` --> $DIR/lint-dead-code-1.rs:67:5 | LL | bar3 - | ^^^^ + | ^^^^ help: if this is intentional, prefix it with an underscore: `_bar3` + | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. error: function is never used: `priv_fn` --> $DIR/lint-dead-code-1.rs:88:4 | LL | fn priv_fn() { - | ^^^^^^^ + | ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_priv_fn` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: function is never used: `foo` --> $DIR/lint-dead-code-1.rs:93:4 | LL | fn foo() { - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_foo` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: function is never used: `bar` --> $DIR/lint-dead-code-1.rs:98:4 | LL | fn bar() { - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_bar` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: function is never used: `baz` --> $DIR/lint-dead-code-1.rs:102:4 | LL | fn baz() -> impl Copy { - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_baz` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: aborting due to 10 previous errors diff --git a/src/test/ui/lint/dead-code/lint-dead-code-2.stderr b/src/test/ui/lint/dead-code/lint-dead-code-2.stderr index b01ba57f98580..5e19c7d02ffd3 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-2.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-2.stderr @@ -2,8 +2,9 @@ error: function is never used: `dead_fn` --> $DIR/lint-dead-code-2.rs:22:4 | LL | fn dead_fn() {} - | ^^^^^^^ + | ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_dead_fn` | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/lint-dead-code-2.rs:2:9 | @@ -14,13 +15,17 @@ error: function is never used: `dead_fn2` --> $DIR/lint-dead-code-2.rs:25:4 | LL | fn dead_fn2() {} - | ^^^^^^^^ + | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_dead_fn2` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: function is never used: `main` --> $DIR/lint-dead-code-2.rs:38:4 | LL | fn main() { - | ^^^^ + | ^^^^ help: if this is intentional, prefix it with an underscore: `_main` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: aborting due to 3 previous errors diff --git a/src/test/ui/lint/dead-code/lint-dead-code-3.stderr b/src/test/ui/lint/dead-code/lint-dead-code-3.stderr index cf8f01ea19f0c..d32fde5872d99 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-3.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-3.stderr @@ -2,8 +2,9 @@ error: struct is never constructed: `Foo` --> $DIR/lint-dead-code-3.rs:14:8 | LL | struct Foo; - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_Foo` | + = note: the leading underscore signals that this struct serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/lint-dead-code-3.rs:4:9 | @@ -14,25 +15,35 @@ error: associated function is never used: `foo` --> $DIR/lint-dead-code-3.rs:16:8 | LL | fn foo(&self) { - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_foo` + | + = note: the leading underscore signals that this associated function serves some other purpose even if it isn't used in a way that we can detect. error: function is never used: `bar` --> $DIR/lint-dead-code-3.rs:21:4 | LL | fn bar() { - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_bar` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: enum is never used: `c_void` --> $DIR/lint-dead-code-3.rs:60:6 | LL | enum c_void {} - | ^^^^^^ + | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_c_void` + | + = note: the leading underscore signals that this enum serves some other purpose even if it isn't used in a way that we can detect. error: function is never used: `free` --> $DIR/lint-dead-code-3.rs:62:5 | LL | fn free(p: *const c_void); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^----^^^^^^^^^^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_free` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: aborting due to 5 previous errors diff --git a/src/test/ui/lint/dead-code/lint-dead-code-4.stderr b/src/test/ui/lint/dead-code/lint-dead-code-4.stderr index 3905d1a06bdfe..2785faa29f5d9 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-4.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-4.stderr @@ -2,8 +2,11 @@ error: field is never read: `b` --> $DIR/lint-dead-code-4.rs:7:5 | LL | b: bool, - | ^^^^^^^ + | -^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_b` | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) note: the lint level is defined here --> $DIR/lint-dead-code-4.rs:3:9 | @@ -14,59 +17,88 @@ error: variant is never constructed: `X` --> $DIR/lint-dead-code-4.rs:15:5 | LL | X, - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_X` + | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. error: variant is never constructed: `Y` --> $DIR/lint-dead-code-4.rs:16:5 | -LL | / Y { +LL | Y { + | ^ help: if this is intentional, prefix it with an underscore: `_Y` + | _____| + | | LL | | a: String, LL | | b: i32, LL | | c: i32, LL | | }, | |_____^ + | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. error: enum is never used: `ABC` --> $DIR/lint-dead-code-4.rs:24:6 | LL | enum ABC { - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_ABC` + | + = note: the leading underscore signals that this enum serves some other purpose even if it isn't used in a way that we can detect. error: variant is never constructed: `I` --> $DIR/lint-dead-code-4.rs:36:5 | LL | I, - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_I` + | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. error: field is never read: `b` --> $DIR/lint-dead-code-4.rs:39:9 | LL | b: i32, - | ^^^^^^ + | -^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_b` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: field is never read: `c` --> $DIR/lint-dead-code-4.rs:40:9 | LL | c: i32, - | ^^^^^^ + | -^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_c` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: variant is never constructed: `K` --> $DIR/lint-dead-code-4.rs:42:5 | LL | K - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_K` + | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. error: field is never read: `x` --> $DIR/lint-dead-code-4.rs:61:5 | LL | x: usize, - | ^^^^^^^^ + | -^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_x` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: field is never read: `c` --> $DIR/lint-dead-code-4.rs:63:5 | LL | c: bool, - | ^^^^^^^ + | -^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_c` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: aborting due to 10 previous errors diff --git a/src/test/ui/lint/dead-code/lint-dead-code-5.stderr b/src/test/ui/lint/dead-code/lint-dead-code-5.stderr index 519add826273f..6375d98d35cb2 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-5.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-5.stderr @@ -2,8 +2,9 @@ error: variant is never constructed: `Variant2` --> $DIR/lint-dead-code-5.rs:6:5 | LL | Variant2 - | ^^^^^^^^ + | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_Variant2` | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/lint-dead-code-5.rs:2:9 | @@ -14,19 +15,29 @@ error: variant is never constructed: `Variant5` --> $DIR/lint-dead-code-5.rs:13:5 | LL | Variant5 { _x: isize }, - | ^^^^^^^^^^^^^^^^^^^^^^ + | --------^^^^^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_Variant5` + | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. error: variant is never constructed: `Variant6` --> $DIR/lint-dead-code-5.rs:14:5 | LL | Variant6(isize), - | ^^^^^^^^^^^^^^^ + | --------^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_Variant6` + | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. error: enum is never used: `Enum3` --> $DIR/lint-dead-code-5.rs:35:6 | LL | enum Enum3 { - | ^^^^^ + | ^^^^^ help: if this is intentional, prefix it with an underscore: `_Enum3` + | + = note: the leading underscore signals that this enum serves some other purpose even if it isn't used in a way that we can detect. error: aborting due to 4 previous errors diff --git a/src/test/ui/lint/dead-code/lint-dead-code-6.stderr b/src/test/ui/lint/dead-code/lint-dead-code-6.stderr index 7dc60730d6aad..ef26fe54ab589 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-6.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-6.stderr @@ -2,8 +2,9 @@ error: struct is never constructed: `UnusedStruct` --> $DIR/lint-dead-code-6.rs:3:8 | LL | struct UnusedStruct; - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_UnusedStruct` | + = note: the leading underscore signals that this struct serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/lint-dead-code-6.rs:1:9 | @@ -14,19 +15,25 @@ error: associated function is never used: `unused_impl_fn_1` --> $DIR/lint-dead-code-6.rs:5:8 | LL | fn unused_impl_fn_1() { - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_impl_fn_1` + | + = note: the leading underscore signals that this associated function serves some other purpose even if it isn't used in a way that we can detect. error: associated function is never used: `unused_impl_fn_2` --> $DIR/lint-dead-code-6.rs:9:8 | LL | fn unused_impl_fn_2(var: i32) { - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_impl_fn_2` + | + = note: the leading underscore signals that this associated function serves some other purpose even if it isn't used in a way that we can detect. error: associated function is never used: `unused_impl_fn_3` --> $DIR/lint-dead-code-6.rs:13:8 | LL | fn unused_impl_fn_3( - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_impl_fn_3` + | + = note: the leading underscore signals that this associated function serves some other purpose even if it isn't used in a way that we can detect. error: aborting due to 4 previous errors diff --git a/src/test/ui/lint/dead-code/newline-span.stderr b/src/test/ui/lint/dead-code/newline-span.stderr index fd74405f2b648..5bd566be35e01 100644 --- a/src/test/ui/lint/dead-code/newline-span.stderr +++ b/src/test/ui/lint/dead-code/newline-span.stderr @@ -2,8 +2,9 @@ error: function is never used: `unused` --> $DIR/newline-span.rs:3:4 | LL | fn unused() { - | ^^^^^^ + | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused` | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/newline-span.rs:1:9 | @@ -14,13 +15,17 @@ error: function is never used: `unused2` --> $DIR/newline-span.rs:7:4 | LL | fn unused2(var: i32) { - | ^^^^^^^ + | ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused2` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: function is never used: `unused3` --> $DIR/newline-span.rs:11:4 | LL | fn unused3( - | ^^^^^^^ + | ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused3` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. error: aborting due to 3 previous errors diff --git a/src/test/ui/lint/dead-code/type-alias.stderr b/src/test/ui/lint/dead-code/type-alias.stderr index b2acd5d4213b3..1e7a030de3aa7 100644 --- a/src/test/ui/lint/dead-code/type-alias.stderr +++ b/src/test/ui/lint/dead-code/type-alias.stderr @@ -2,8 +2,11 @@ error: type alias is never used: `Unused` --> $DIR/type-alias.rs:4:1 | LL | type Unused = u8; - | ^^^^^^^^^^^^^^^^^ + | ^^^^^------^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_Unused` | + = note: the leading underscore signals that this type alias serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/type-alias.rs:1:9 | diff --git a/src/test/ui/lint/dead-code/unused-enum.stderr b/src/test/ui/lint/dead-code/unused-enum.stderr index 9f368fdd2f816..d536479c800ae 100644 --- a/src/test/ui/lint/dead-code/unused-enum.stderr +++ b/src/test/ui/lint/dead-code/unused-enum.stderr @@ -2,8 +2,9 @@ error: struct is never constructed: `F` --> $DIR/unused-enum.rs:3:8 | LL | struct F; - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_F` | + = note: the leading underscore signals that this struct serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/unused-enum.rs:1:9 | @@ -15,13 +16,17 @@ error: struct is never constructed: `B` --> $DIR/unused-enum.rs:4:8 | LL | struct B; - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_B` + | + = note: the leading underscore signals that this struct serves some other purpose even if it isn't used in a way that we can detect. error: enum is never used: `E` --> $DIR/unused-enum.rs:6:6 | LL | enum E { - | ^ + | ^ help: if this is intentional, prefix it with an underscore: `_E` + | + = note: the leading underscore signals that this enum serves some other purpose even if it isn't used in a way that we can detect. error: aborting due to 3 previous errors diff --git a/src/test/ui/lint/dead-code/unused-struct-variant.stderr b/src/test/ui/lint/dead-code/unused-struct-variant.stderr index b93d6d4ac1866..394ced3e81001 100644 --- a/src/test/ui/lint/dead-code/unused-struct-variant.stderr +++ b/src/test/ui/lint/dead-code/unused-struct-variant.stderr @@ -2,8 +2,11 @@ error: variant is never constructed: `Bar` --> $DIR/unused-struct-variant.rs:8:5 | LL | Bar(B), - | ^^^^^^ + | ---^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_Bar` | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/unused-struct-variant.rs:1:9 | diff --git a/src/test/ui/lint/dead-code/unused-variant.stderr b/src/test/ui/lint/dead-code/unused-variant.stderr index a547f5af4b082..7dcb79d0490c1 100644 --- a/src/test/ui/lint/dead-code/unused-variant.stderr +++ b/src/test/ui/lint/dead-code/unused-variant.stderr @@ -2,8 +2,9 @@ error: variant is never constructed: `Variant1` --> $DIR/unused-variant.rs:5:5 | LL | Variant1, - | ^^^^^^^^ + | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_Variant1` | + = note: the leading underscore signals that this variant serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/unused-variant.rs:1:9 | diff --git a/src/test/ui/lint/dead-code/with-core-crate.stderr b/src/test/ui/lint/dead-code/with-core-crate.stderr index 2c63e60d67609..1bde434069ee7 100644 --- a/src/test/ui/lint/dead-code/with-core-crate.stderr +++ b/src/test/ui/lint/dead-code/with-core-crate.stderr @@ -2,8 +2,9 @@ error: function is never used: `foo` --> $DIR/with-core-crate.rs:7:4 | LL | fn foo() { - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_foo` | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/with-core-crate.rs:1:9 | diff --git a/src/test/ui/lint/dead-code/write-only-field.stderr b/src/test/ui/lint/dead-code/write-only-field.stderr index a191d22c8b94c..13a21bb1193de 100644 --- a/src/test/ui/lint/dead-code/write-only-field.stderr +++ b/src/test/ui/lint/dead-code/write-only-field.stderr @@ -2,8 +2,11 @@ error: field is never read: `f` --> $DIR/write-only-field.rs:4:5 | LL | f: i32, - | ^^^^^^ + | -^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_f` | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) note: the lint level is defined here --> $DIR/write-only-field.rs:1:9 | @@ -14,31 +17,51 @@ error: field is never read: `sub` --> $DIR/write-only-field.rs:5:5 | LL | sub: Sub, - | ^^^^^^^^ + | ---^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_sub` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: field is never read: `f` --> $DIR/write-only-field.rs:9:5 | LL | f: i32, - | ^^^^^^ + | -^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_f` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: field is never read: `y` --> $DIR/write-only-field.rs:28:9 | LL | y: bool, - | ^^^^^^^ + | -^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_y` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: field is never read: `u` --> $DIR/write-only-field.rs:58:9 | LL | u: u32, - | ^^^^^^ + | -^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_u` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: field is never read: `v` --> $DIR/write-only-field.rs:59:9 | LL | v: u32, - | ^^^^^^ + | -^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_v` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: aborting due to 6 previous errors diff --git a/src/test/ui/lint/issue-17718-const-naming.stderr b/src/test/ui/lint/issue-17718-const-naming.stderr index ce4ebcb5e3ef6..e880006e114c1 100644 --- a/src/test/ui/lint/issue-17718-const-naming.stderr +++ b/src/test/ui/lint/issue-17718-const-naming.stderr @@ -2,8 +2,11 @@ error: constant is never used: `foo` --> $DIR/issue-17718-const-naming.rs:4:1 | LL | const foo: isize = 3; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^---^^^^^^^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_foo` | + = note: the leading underscore signals that this constant serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/issue-17718-const-naming.rs:2:9 | diff --git a/src/test/ui/resolve/issue-3907.stderr b/src/test/ui/resolve/issue-3907.stderr index 4d0b0af58a320..6fc61cae84339 100644 --- a/src/test/ui/resolve/issue-3907.stderr +++ b/src/test/ui/resolve/issue-3907.stderr @@ -5,10 +5,9 @@ LL | impl Foo for S { | ^^^ type aliases cannot be used as traits | help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` alias - --> $DIR/issue-3907.rs:5:1 | -LL | type Foo = dyn issue_3907::Foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | trait Foo = dyn issue_3907::Foo; + | help: consider importing this trait instead | LL | use issue_3907::Foo; diff --git a/src/test/ui/resolve/issue-5035.stderr b/src/test/ui/resolve/issue-5035.stderr index 41dff2fe54205..a8aa50b7c3ab2 100644 --- a/src/test/ui/resolve/issue-5035.stderr +++ b/src/test/ui/resolve/issue-5035.stderr @@ -11,16 +11,16 @@ LL | trait I {} | ------- similarly named trait `I` defined here LL | type K = dyn I; LL | impl K for isize {} - | ^ - | | - | type aliases cannot be used as traits - | help: a trait with a similar name exists: `I` + | ^ type aliases cannot be used as traits | help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` alias - --> $DIR/issue-5035.rs:2:1 | -LL | type K = dyn I; - | ^^^^^^^^^^^^^^^ +LL | trait K = dyn I; + | +help: a trait with a similar name exists + | +LL | impl I for isize {} + | ^ error: aborting due to 2 previous errors diff --git a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr index 2974d08eb23b1..8addc0303fb91 100644 --- a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr +++ b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr @@ -11,10 +11,9 @@ LL | fn g isize>(x: F) {} | ^^^^^^^^^^^^^^^^^^^^^^^ type aliases cannot be used as traits | help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` alias - --> $DIR/unboxed-closure-sugar-nonexistent-trait.rs:4:1 | -LL | type Typedef = isize; - | ^^^^^^^^^^^^^^^^^^^^^ +LL | trait Typedef = isize; + | error: aborting due to 2 previous errors diff --git a/src/test/ui/span/macro-span-replacement.stderr b/src/test/ui/span/macro-span-replacement.stderr index 45cf5f8688cd1..f94a9e30a3dfa 100644 --- a/src/test/ui/span/macro-span-replacement.stderr +++ b/src/test/ui/span/macro-span-replacement.stderr @@ -2,11 +2,14 @@ warning: struct is never constructed: `S` --> $DIR/macro-span-replacement.rs:7:14 | LL | $b $a; - | ^ + | --^ + | | + | help: if this is intentional, prefix it with an underscore: `_S` ... LL | m!(S struct); | ------------- in this macro invocation | + = note: the leading underscore signals that this struct serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/macro-span-replacement.rs:3:9 | diff --git a/src/test/ui/span/unused-warning-point-at-identifier.stderr b/src/test/ui/span/unused-warning-point-at-identifier.stderr index 6ef877da122f5..3bf342f197252 100644 --- a/src/test/ui/span/unused-warning-point-at-identifier.stderr +++ b/src/test/ui/span/unused-warning-point-at-identifier.stderr @@ -2,8 +2,9 @@ warning: enum is never used: `Enum` --> $DIR/unused-warning-point-at-identifier.rs:5:6 | LL | enum Enum { - | ^^^^ + | ^^^^ help: if this is intentional, prefix it with an underscore: `_Enum` | + = note: the leading underscore signals that this enum serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/unused-warning-point-at-identifier.rs:3:9 | @@ -15,19 +16,25 @@ warning: struct is never constructed: `Struct` --> $DIR/unused-warning-point-at-identifier.rs:12:8 | LL | struct Struct { - | ^^^^^^ + | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_Struct` + | + = note: the leading underscore signals that this struct serves some other purpose even if it isn't used in a way that we can detect. warning: function is never used: `func` --> $DIR/unused-warning-point-at-identifier.rs:19:4 | LL | fn func() -> usize { - | ^^^^ + | ^^^^ help: if this is intentional, prefix it with an underscore: `_func` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. warning: function is never used: `func_complete_span` --> $DIR/unused-warning-point-at-identifier.rs:24:1 | LL | func_complete_span() - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_func_complete_span` + | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. warning: 4 warnings emitted diff --git a/src/test/ui/test-attrs/test-warns-dead-code.stderr b/src/test/ui/test-attrs/test-warns-dead-code.stderr index d3bcea2951364..e5a8dee6ccb68 100644 --- a/src/test/ui/test-attrs/test-warns-dead-code.stderr +++ b/src/test/ui/test-attrs/test-warns-dead-code.stderr @@ -2,8 +2,9 @@ error: function is never used: `dead` --> $DIR/test-warns-dead-code.rs:5:4 | LL | fn dead() {} - | ^^^^ + | ^^^^ help: if this is intentional, prefix it with an underscore: `_dead` | + = note: the leading underscore signals that this function serves some other purpose even if it isn't used in a way that we can detect. note: the lint level is defined here --> $DIR/test-warns-dead-code.rs:3:9 | diff --git a/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.fixed b/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.fixed new file mode 100644 index 0000000000000..8a94abaeb0744 --- /dev/null +++ b/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.fixed @@ -0,0 +1,13 @@ +// Regression test of #43913. + +// run-rustfix + +#![feature(trait_alias)] +#![allow(bare_trait_objects, dead_code)] + +trait Strings = Iterator; + +struct Struct(S); +//~^ ERROR: expected trait, found type alias `Strings` + +fn main() {} diff --git a/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.rs b/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.rs new file mode 100644 index 0000000000000..40c678c281f4c --- /dev/null +++ b/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.rs @@ -0,0 +1,13 @@ +// Regression test of #43913. + +// run-rustfix + +#![feature(trait_alias)] +#![allow(bare_trait_objects, dead_code)] + +type Strings = Iterator; + +struct Struct(S); +//~^ ERROR: expected trait, found type alias `Strings` + +fn main() {} diff --git a/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.stderr b/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.stderr new file mode 100644 index 0000000000000..6e03eeada499c --- /dev/null +++ b/src/test/ui/traits/alias/suggest-trait-alias-instead-of-type.stderr @@ -0,0 +1,14 @@ +error[E0404]: expected trait, found type alias `Strings` + --> $DIR/suggest-trait-alias-instead-of-type.rs:10:18 + | +LL | struct Struct(S); + | ^^^^^^^ type aliases cannot be used as traits + | +help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` alias + | +LL | trait Strings = Iterator; + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0404`. diff --git a/src/test/ui/union/union-fields-1.stderr b/src/test/ui/union/union-fields-1.stderr index 87621cc01b1b9..3595bf6dce688 100644 --- a/src/test/ui/union/union-fields-1.stderr +++ b/src/test/ui/union/union-fields-1.stderr @@ -2,8 +2,11 @@ error: field is never read: `c` --> $DIR/union-fields-1.rs:6:5 | LL | c: u8, - | ^^^^^ + | -^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_c` | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) note: the lint level is defined here --> $DIR/union-fields-1.rs:1:9 | @@ -14,19 +17,31 @@ error: field is never read: `a` --> $DIR/union-fields-1.rs:9:5 | LL | a: u8, - | ^^^^^ + | -^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_a` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: field is never read: `a` --> $DIR/union-fields-1.rs:13:20 | LL | union NoDropLike { a: u8 } - | ^^^^^ + | -^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_a` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: field is never read: `c` --> $DIR/union-fields-1.rs:18:5 | LL | c: u8, - | ^^^^^ + | -^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_c` + | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) error: aborting due to 4 previous errors diff --git a/src/test/ui/union/union-lint-dead-code.stderr b/src/test/ui/union/union-lint-dead-code.stderr index 7de70ec33801f..8ead9cde9b333 100644 --- a/src/test/ui/union/union-lint-dead-code.stderr +++ b/src/test/ui/union/union-lint-dead-code.stderr @@ -2,8 +2,11 @@ error: field is never read: `b` --> $DIR/union-lint-dead-code.rs:5:5 | LL | b: bool, - | ^^^^^^^ + | -^^^^^^ + | | + | help: if this is intentional, prefix it with an underscore: `_b` | + = note: the leading underscore signals that this field serves some other purpose even if it isn't used in a way that we can detect. (e.g. for its effect when dropped or in foreign code) note: the lint level is defined here --> $DIR/union-lint-dead-code.rs:1:9 |