diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 23667d1b331a3..6187e091319e0 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -539,7 +539,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, .emit(); } else if has_guard && !cx.tcx.allow_bind_by_move_patterns_with_guards() { let mut err = struct_span_err!(cx.tcx.sess, p.span, E0008, - "cannot bind by-move into a pattern guard"); + "cannot bind by-move into a pattern guard"); err.span_label(p.span, "moves value into pattern guard"); if cx.tcx.sess.opts.unstable_features.is_nightly_build() && cx.tcx.use_mir_borrowck() { err.help("add #![feature(bind_by_move_pattern_guards)] to the \ diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 91b0e9c1dca62..5e3f747009911 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -42,8 +42,9 @@ use rustc::lint; use rustc::hir::def::*; use rustc::hir::def::Namespace::*; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId}; -use rustc::ty; use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap}; +use rustc::session::config::nightly_options; +use rustc::ty; use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap}; use rustc_metadata::creader::CrateLoader; @@ -1381,6 +1382,9 @@ pub struct Resolver<'a, 'b: 'a> { /// The current self type if inside an impl (used for better errors). current_self_type: Option, + /// The current self item if inside an ADT (used for better errors). + current_self_item: Option, + /// The idents for the primitive types. primitive_type_table: PrimitiveTypeTable, @@ -1710,6 +1714,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { current_trait_ref: None, current_self_type: None, + current_self_item: None, primitive_type_table: PrimitiveTypeTable::new(), @@ -2186,15 +2191,17 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } fn resolve_adt(&mut self, item: &Item, generics: &Generics) { - self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| { - let item_def_id = this.definitions.local_def_id(item.id); - if this.session.features_untracked().self_in_typedefs { - this.with_self_rib(Def::SelfTy(None, Some(item_def_id)), |this| { + self.with_current_self_item(item, |this| { + this.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| { + let item_def_id = this.definitions.local_def_id(item.id); + if this.session.features_untracked().self_in_typedefs { + this.with_self_rib(Def::SelfTy(None, Some(item_def_id)), |this| { + visit::walk_item(this, item); + }); + } else { visit::walk_item(this, item); - }); - } else { - visit::walk_item(this, item); - } + } + }); }); } @@ -2435,6 +2442,15 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { result } + fn with_current_self_item(&mut self, self_item: &Item, f: F) -> T + where F: FnOnce(&mut Resolver) -> T + { + let previous_value = replace(&mut self.current_self_item, Some(self_item.id)); + let result = f(self); + self.current_self_item = previous_value; + result + } + /// This is called to resolve a trait reference from an `impl` (i.e. `impl Trait for Foo`) fn with_optional_trait_ref(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T where F: FnOnce(&mut Resolver, Option) -> T @@ -3004,6 +3020,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { "traits and impls" }; err.span_label(span, format!("`Self` is only available in {}", available_in)); + if this.current_self_item.is_some() && nightly_options::is_nightly_build() { + err.help("add #![feature(self_in_typedefs)] to the crate attributes \ + to enable"); + } return (err, Vec::new()); } if is_self_value(path, ns) { diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 499daccf5e80f..ae97cdc85ad38 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -17,6 +17,9 @@ use check::FnCtxt; use hir::def_id::DefId; use hir::def::Def; use namespace::Namespace; +use rustc::hir; +use rustc::lint; +use rustc::session::config::nightly_options; use rustc::ty::subst::{Subst, Substs}; use rustc::traits::{self, ObligationCause}; use rustc::ty::{self, Ty, ToPolyTraitRef, ToPredicate, TraitRef, TypeFoldable}; @@ -28,8 +31,6 @@ use rustc::middle::stability; use syntax::ast; use syntax::util::lev_distance::{lev_distance, find_best_match_for_name}; use syntax_pos::{Span, symbol::Symbol}; -use rustc::hir; -use rustc::lint; use std::mem; use std::ops::Deref; use std::rc::Rc; @@ -1073,9 +1074,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { self.tcx.item_path_str(stable_pick.item.def_id), )); - if ::rustc::session::config::nightly_options::is_nightly_build() { + if nightly_options::is_nightly_build() { for (candidate, feature) in unstable_candidates { - diag.note(&format!( + diag.help(&format!( "add #![feature({})] to the crate attributes to enable `{}`", feature, self.tcx.item_path_str(candidate.item.def_id), diff --git a/src/test/ui/feature-gates/feature-gate-self_in_typedefs.stderr b/src/test/ui/feature-gates/feature-gate-self_in_typedefs.stderr index 22ca92bbe1391..ab04953f3e50c 100644 --- a/src/test/ui/feature-gates/feature-gate-self_in_typedefs.stderr +++ b/src/test/ui/feature-gates/feature-gate-self_in_typedefs.stderr @@ -3,6 +3,8 @@ error[E0411]: cannot find type `Self` in this scope | LL | Cons(T, &'a Self) | ^^^^ `Self` is only available in traits and impls + | + = help: add #![feature(self_in_typedefs)] to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/inference/inference_unstable.stderr b/src/test/ui/inference/inference_unstable.stderr index 3a5cb6f2b2e0f..2851af4891e5a 100644 --- a/src/test/ui/inference/inference_unstable.stderr +++ b/src/test/ui/inference/inference_unstable.stderr @@ -8,5 +8,5 @@ LL | assert_eq!('x'.ipu_flatten(), 1); = warning: once this method is added to the standard library, the ambiguity may cause an error or change in behavior! = note: for more information, see issue #48919 = help: call with fully qualified syntax `inference_unstable_itertools::IpuItertools::ipu_flatten(...)` to keep using the current method - = note: add #![feature(ipu_flatten)] to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_flatten` + = help: add #![feature(ipu_flatten)] to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_flatten`