From 132bff9933e90e07a2f993882dca9fc674116f5b Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Mon, 25 Jul 2016 23:04:42 +0000 Subject: [PATCH 01/10] If a single import resolves to an inaccessible name in some but not all namespaces, avoid importing the name in the inaccessible namespaces. Currently, the inaccessible namespaces are imported but cause a privacy error when used. --- src/librustc_resolve/lib.rs | 11 +--- src/librustc_resolve/resolve_imports.rs | 74 +++++++++++-------------- 2 files changed, 35 insertions(+), 50 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index aa8c706ea1e27..7a0a417d0274a 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -825,8 +825,6 @@ enum NameBindingKind<'a> { Import { binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>, - // Some(error) if using this imported name causes the import to be a privacy error - privacy_error: Option>>, }, } @@ -1206,16 +1204,11 @@ impl<'a> Resolver<'a> { self.used_crates.insert(krate); } - let (directive, privacy_error) = match binding.kind { - NameBindingKind::Import { directive, ref privacy_error, .. } => - (directive, privacy_error), + let directive = match binding.kind { + NameBindingKind::Import { directive, .. } => directive, _ => return, }; - if let Some(error) = privacy_error.as_ref() { - self.privacy_errors.push((**error).clone()); - } - if !self.make_glob_map { return; } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 681d9ec735b4f..fc5e2a48e876c 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -73,13 +73,11 @@ pub struct ImportDirective<'a> { impl<'a> ImportDirective<'a> { // Given the binding to which this directive resolves in a particular namespace, // this returns the binding for the name this directive defines in that namespace. - fn import(&'a self, binding: &'a NameBinding<'a>, privacy_error: Option>>) - -> NameBinding<'a> { + fn import(&'a self, binding: &'a NameBinding<'a>) -> NameBinding<'a> { NameBinding { kind: NameBindingKind::Import { binding: binding, directive: self, - privacy_error: privacy_error, }, span: self.span, vis: self.vis, @@ -328,7 +326,7 @@ impl<'a> ::ModuleS<'a> { fn define_in_glob_importers(&self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>) { if !binding.is_importable() || !binding.is_pseudo_public() { return } for &(importer, directive) in self.glob_importers.borrow_mut().iter() { - let _ = importer.try_define_child(name, ns, directive.import(binding, None)); + let _ = importer.try_define_child(name, ns, directive.import(binding)); } } } @@ -409,7 +407,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { span: DUMMY_SP, vis: ty::Visibility::Public, }); - let dummy_binding = directive.import(dummy_binding, None); + let dummy_binding = directive.import(dummy_binding); let _ = source_module.try_define_child(target, ValueNS, dummy_binding.clone()); let _ = source_module.try_define_child(target, TypeNS, dummy_binding); @@ -494,14 +492,17 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { self.resolver.resolve_name_in_module(target_module, source, TypeNS, false, true); let module_ = self.resolver.current_module; + let mut privacy_error = true; for &(ns, result, determined) in &[(ValueNS, &value_result, value_determined), (TypeNS, &type_result, type_determined)] { - if determined.get() { continue } - if let Indeterminate = *result { continue } - - determined.set(true); - if let Success(binding) = *result { - if !binding.is_importable() { + match *result { + Failed(..) if !determined.get() => { + determined.set(true); + module_.update_resolution(target, ns, |resolution| { + resolution.single_imports.directive_failed() + }); + } + Success(binding) if !binding.is_importable() => { let msg = format!("`{}` is not directly importable", target); span_err!(self.resolver.session, directive.span, E0253, "{}", &msg); // Do not import this illegal binding. Import a dummy binding and pretend @@ -509,23 +510,19 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { self.import_dummy_binding(module_, directive); return Success(()); } - - let privacy_error = if !self.resolver.is_accessible(binding.vis) { - Some(Box::new(PrivacyError(directive.span, source, binding))) - } else { - None - }; - - let imported_binding = directive.import(binding, privacy_error); - let conflict = module_.try_define_child(target, ns, imported_binding); - if let Err(old_binding) = conflict { - let binding = &directive.import(binding, None); - self.resolver.report_conflict(module_, target, ns, binding, old_binding); + Success(binding) if !self.resolver.is_accessible(binding.vis) => {} + Success(binding) if !determined.get() => { + determined.set(true); + let imported_binding = directive.import(binding); + let conflict = module_.try_define_child(target, ns, imported_binding); + if let Err(old_binding) = conflict { + let binding = &directive.import(binding); + self.resolver.report_conflict(module_, target, ns, binding, old_binding); + } + privacy_error = false; } - } else { - module_.update_resolution(target, ns, |resolution| { - resolution.single_imports.directive_failed(); - }); + Success(_) => privacy_error = false, + _ => {} } } @@ -556,6 +553,14 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { _ => (), } + if privacy_error { + for &(ns, result) in &[(ValueNS, &value_result), (TypeNS, &type_result)] { + let binding = match *result { Success(binding) => binding, _ => continue }; + self.resolver.privacy_errors.push(PrivacyError(directive.span, source, binding)); + let _ = module_.try_define_child(target, ns, directive.import(binding)); + } + } + match (&value_result, &type_result) { (&Success(binding), _) if !binding.pseudo_vis() .is_at_least(directive.vis, self.resolver) && @@ -592,19 +597,6 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { _ => {} } - // Report a privacy error here if all successful namespaces are privacy errors. - let mut privacy_error = None; - for &ns in &[ValueNS, TypeNS] { - privacy_error = match module_.resolve_name(target, ns, true) { - Success(&NameBinding { - kind: NameBindingKind::Import { ref privacy_error, .. }, .. - }) => privacy_error.as_ref().map(|error| (**error).clone()), - _ => continue, - }; - if privacy_error.is_none() { break } - } - privacy_error.map(|error| self.resolver.privacy_errors.push(error)); - // Record what this import resolves to for later uses in documentation, // this may resolve to either a value or a type, but for documentation // purposes it's good enough to just favor one over the other. @@ -652,7 +644,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { }).collect::>(); for ((name, ns), binding) in bindings { if binding.is_importable() && binding.is_pseudo_public() { - let _ = module_.try_define_child(name, ns, directive.import(binding, None)); + let _ = module_.try_define_child(name, ns, directive.import(binding)); } } From 8205691929bc545430f1fa73e61a4f5f77fbbdc7 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Tue, 26 Jul 2016 04:16:48 +0000 Subject: [PATCH 02/10] Fix fallout in tests. --- src/test/compile-fail/privacy-ns2.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/compile-fail/privacy-ns2.rs b/src/test/compile-fail/privacy-ns2.rs index bf296220d2a2b..7accf0ca8201c 100644 --- a/src/test/compile-fail/privacy-ns2.rs +++ b/src/test/compile-fail/privacy-ns2.rs @@ -25,15 +25,15 @@ pub mod foo1 { } fn test_single1() { - use foo1::Bar; //~ ERROR function `Bar` is private + use foo1::Bar; - Bar(); + Bar(); //~ ERROR unresolved name `Bar` } fn test_list1() { - use foo1::{Bar,Baz}; //~ ERROR `Bar` is private + use foo1::{Bar,Baz}; - Bar(); + Bar(); //~ ERROR unresolved name `Bar` } // private type, public value @@ -46,15 +46,15 @@ pub mod foo2 { } fn test_single2() { - use foo2::Bar; //~ ERROR trait `Bar` is private + use foo2::Bar; - let _x : Box; + let _x : Box; //~ ERROR type name `Bar` is undefined } fn test_list2() { - use foo2::{Bar,Baz}; //~ ERROR `Bar` is private + use foo2::{Bar,Baz}; - let _x: Box; + let _x: Box; //~ ERROR type name `Bar` is undefined } // neither public From 6ac83de691c5eb180e2007fcbe3236fd359d2ab7 Mon Sep 17 00:00:00 2001 From: Knight Date: Wed, 27 Jul 2016 02:30:50 +0800 Subject: [PATCH 03/10] Add test for string AddAssign --- src/libcollectionstest/string.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/libcollectionstest/string.rs b/src/libcollectionstest/string.rs index 7f0fd282ae5e9..1652fb5a88d80 100644 --- a/src/libcollectionstest/string.rs +++ b/src/libcollectionstest/string.rs @@ -192,6 +192,17 @@ fn test_push_str() { assert_eq!(&s[0..], "abcประเทศไทย中华Việt Nam"); } +#[test] +fn test_add_assign() { + let mut s = String::new(); + s += ""; + assert_eq!(s.as_str(), ""); + s += "abc"; + assert_eq!(s.as_str(), "abc"); + s += "ประเทศไทย中华Việt Nam"; + assert_eq!(s.as_str(), "abcประเทศไทย中华Việt Nam"); +} + #[test] fn test_push() { let mut data = String::from("ประเทศไทย中"); From cfdaca049a2451b62d3d403ef13b78d7a2f60816 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Wed, 27 Jul 2016 16:59:33 -0700 Subject: [PATCH 04/10] Rename _ to {numerics} for unknown numeric types --- src/librustc/util/ppaux.rs | 3 ++- src/test/compile-fail/array-not-vector.rs | 2 +- src/test/compile-fail/bad-const-type.rs | 2 +- src/test/compile-fail/coerce-mut.rs | 2 +- src/test/compile-fail/coercion-slice.rs | 2 +- src/test/compile-fail/fully-qualified-type-name1.rs | 2 +- src/test/compile-fail/if-let-arm-types.rs | 2 +- src/test/compile-fail/indexing-requires-a-uint.rs | 2 +- src/test/compile-fail/integral-variable-unification-error.rs | 4 ++-- src/test/compile-fail/issue-13466.rs | 4 ++-- src/test/compile-fail/issue-17651.rs | 2 +- src/test/compile-fail/issue-19991.rs | 2 +- src/test/compile-fail/issue-26237.rs | 2 +- src/test/compile-fail/issue-4201.rs | 2 +- src/test/compile-fail/issue-4968.rs | 2 +- src/test/compile-fail/issue-7867.rs | 4 ++-- src/test/compile-fail/kindck-impl-type-params-2.rs | 2 +- src/test/compile-fail/match-range-fail.rs | 2 +- src/test/compile-fail/match-vec-mismatch.rs | 2 +- src/test/compile-fail/method-self-arg-1.rs | 2 +- src/test/compile-fail/mut-pattern-mismatched.rs | 4 ++-- src/test/compile-fail/no_send-rc.rs | 2 +- src/test/compile-fail/range-1.rs | 2 +- src/test/compile-fail/repeat_count.rs | 2 +- .../compile-fail/slightly-nice-generic-literal-messages.rs | 4 ++-- src/test/compile-fail/str-idx.rs | 2 +- src/test/compile-fail/struct-base-wrong-type-2.rs | 2 +- src/test/compile-fail/struct-base-wrong-type.rs | 2 +- .../compile-fail/traits-inductive-overflow-simultaneous.rs | 2 +- src/test/compile-fail/tuple-arity-mismatch.rs | 2 +- src/test/compile-fail/tuple-index-out-of-bounds.rs | 2 +- src/test/compile-fail/type-mismatch-multiple.rs | 2 +- src/test/compile-fail/typeck-unsafe-always-share.rs | 2 +- src/test/compile-fail/vtable-res-trait-param.rs | 2 +- src/test/ui/mismatched_types/issue-26480.stderr | 2 +- 35 files changed, 41 insertions(+), 40 deletions(-) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 0bfb7c1ed5532..a33d914e7cf7a 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -974,7 +974,8 @@ impl fmt::Display for ty::InferTy { ty::TyVar(ref vid) if print_var_ids => write!(f, "{:?}", vid), ty::IntVar(ref vid) if print_var_ids => write!(f, "{:?}", vid), ty::FloatVar(ref vid) if print_var_ids => write!(f, "{:?}", vid), - ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => write!(f, "_"), + ty::TyVar(_) => write!(f, "_"), + ty::IntVar(_) | ty::FloatVar(_) => write!(f, "{}", "{numeric}"), ty::FreshTy(v) => write!(f, "FreshTy({})", v), ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v), ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v) diff --git a/src/test/compile-fail/array-not-vector.rs b/src/test/compile-fail/array-not-vector.rs index 1bbccae53a44d..b8883e4661eaa 100644 --- a/src/test/compile-fail/array-not-vector.rs +++ b/src/test/compile-fail/array-not-vector.rs @@ -12,7 +12,7 @@ fn main() { let _x: i32 = [1, 2, 3]; //~^ ERROR mismatched types //~| expected type `i32` - //~| found type `[_; 3]` + //~| found type `[{numeric}; 3]` //~| expected i32, found array of 3 elements let x: &[i32] = &[1, 2, 3]; diff --git a/src/test/compile-fail/bad-const-type.rs b/src/test/compile-fail/bad-const-type.rs index ee6ac33072792..3b6221f0df5b8 100644 --- a/src/test/compile-fail/bad-const-type.rs +++ b/src/test/compile-fail/bad-const-type.rs @@ -11,6 +11,6 @@ static i: String = 10; //~^ ERROR mismatched types //~| expected type `std::string::String` -//~| found type `_` +//~| found type `{numeric}` //~| expected struct `std::string::String`, found integral variable fn main() { println!("{}", i); } diff --git a/src/test/compile-fail/coerce-mut.rs b/src/test/compile-fail/coerce-mut.rs index 634d12441a120..91222e58b78cc 100644 --- a/src/test/compile-fail/coerce-mut.rs +++ b/src/test/compile-fail/coerce-mut.rs @@ -15,6 +15,6 @@ fn main() { f(&x); //~^ ERROR mismatched types //~| expected type `&mut i32` - //~| found type `&_` + //~| found type `&{numeric}` //~| values differ in mutability } diff --git a/src/test/compile-fail/coercion-slice.rs b/src/test/compile-fail/coercion-slice.rs index bd7e6c2a2131d..bfec84993961e 100644 --- a/src/test/compile-fail/coercion-slice.rs +++ b/src/test/compile-fail/coercion-slice.rs @@ -14,6 +14,6 @@ fn main() { let _: &[i32] = [0]; //~^ ERROR mismatched types //~| expected type `&[i32]` - //~| found type `[_; 1]` + //~| found type `[{numeric}; 1]` //~| expected &-ptr, found array of 1 elements } diff --git a/src/test/compile-fail/fully-qualified-type-name1.rs b/src/test/compile-fail/fully-qualified-type-name1.rs index 5ea8ce2264438..3ae95a72abdd9 100644 --- a/src/test/compile-fail/fully-qualified-type-name1.rs +++ b/src/test/compile-fail/fully-qualified-type-name1.rs @@ -15,6 +15,6 @@ fn main() { x = 5; //~^ ERROR mismatched types //~| expected type `std::option::Option` - //~| found type `_` + //~| found type `{numeric}` //~| expected enum `std::option::Option`, found integral variable } diff --git a/src/test/compile-fail/if-let-arm-types.rs b/src/test/compile-fail/if-let-arm-types.rs index c7b1e1a62c209..394a6fb30d7e9 100644 --- a/src/test/compile-fail/if-let-arm-types.rs +++ b/src/test/compile-fail/if-let-arm-types.rs @@ -12,7 +12,7 @@ fn main() { if let Some(b) = None { //~ ERROR: `if let` arms have incompatible types //~^ expected (), found integral variable //~| expected type `()` - //~| found type `_` + //~| found type `{numeric}` () } else { //~ NOTE: `if let` arm with an incompatible type 1 diff --git a/src/test/compile-fail/indexing-requires-a-uint.rs b/src/test/compile-fail/indexing-requires-a-uint.rs index 354d7b936485b..fe29a840f28c7 100644 --- a/src/test/compile-fail/indexing-requires-a-uint.rs +++ b/src/test/compile-fail/indexing-requires-a-uint.rs @@ -13,7 +13,7 @@ fn main() { fn bar(_: T) {} - [0][0u8]; //~ ERROR: `[_]: std::ops::Index` is not satisfied + [0][0u8]; //~ ERROR: `[{numeric}]: std::ops::Index` is not satisfied [0][0]; // should infer to be a usize diff --git a/src/test/compile-fail/integral-variable-unification-error.rs b/src/test/compile-fail/integral-variable-unification-error.rs index 99f2d25166891..9dd3772c10cd9 100644 --- a/src/test/compile-fail/integral-variable-unification-error.rs +++ b/src/test/compile-fail/integral-variable-unification-error.rs @@ -12,7 +12,7 @@ fn main() { let mut x = 2; x = 5.0; //~^ ERROR mismatched types - //~| expected type `_` - //~| found type `_` + //~| expected type `{numeric}` + //~| found type `{numeric}` //~| expected integral variable, found floating-point variable } diff --git a/src/test/compile-fail/issue-13466.rs b/src/test/compile-fail/issue-13466.rs index 17b96411603ef..b1a5adb313fac 100644 --- a/src/test/compile-fail/issue-13466.rs +++ b/src/test/compile-fail/issue-13466.rs @@ -17,13 +17,13 @@ pub fn main() { let _x: usize = match Some(1) { Ok(u) => u, //~^ ERROR mismatched types - //~| expected type `std::option::Option<_>` + //~| expected type `std::option::Option<{numeric}>` //~| found type `std::result::Result<_, _>` //~| expected enum `std::option::Option`, found enum `std::result::Result` Err(e) => panic!(e) //~^ ERROR mismatched types - //~| expected type `std::option::Option<_>` + //~| expected type `std::option::Option<{numeric}>` //~| found type `std::result::Result<_, _>` //~| expected enum `std::option::Option`, found enum `std::result::Result` }; diff --git a/src/test/compile-fail/issue-17651.rs b/src/test/compile-fail/issue-17651.rs index 0fe01ece558ee..2438c86a57c7f 100644 --- a/src/test/compile-fail/issue-17651.rs +++ b/src/test/compile-fail/issue-17651.rs @@ -14,5 +14,5 @@ fn main() { // FIXME (#22405): Replace `Box::new` with `box` here when/if possible. (|| Box::new(*(&[0][..])))(); - //~^ ERROR `[_]: std::marker::Sized` is not satisfied + //~^ ERROR `[{numeric}]: std::marker::Sized` is not satisfied } diff --git a/src/test/compile-fail/issue-19991.rs b/src/test/compile-fail/issue-19991.rs index b368daaaf587c..77a83a608213d 100644 --- a/src/test/compile-fail/issue-19991.rs +++ b/src/test/compile-fail/issue-19991.rs @@ -14,7 +14,7 @@ fn main() { if let Some(homura) = Some("madoka") { //~ ERROR missing an else clause //~| expected type `()` - //~| found type `_` + //~| found type `{numeric}` //~| expected (), found integral variable 765 }; diff --git a/src/test/compile-fail/issue-26237.rs b/src/test/compile-fail/issue-26237.rs index 11e236d22126b..f2d24f3998cc2 100644 --- a/src/test/compile-fail/issue-26237.rs +++ b/src/test/compile-fail/issue-26237.rs @@ -11,7 +11,7 @@ macro_rules! macro_panic { ($not_a_function:expr, $some_argument:ident) => { $not_a_function($some_argument) - //~^ ERROR expected function, found `_` + //~^ ERROR expected function, found `{numeric}` } } diff --git a/src/test/compile-fail/issue-4201.rs b/src/test/compile-fail/issue-4201.rs index 58423341cc6f0..65bfeed20eaa0 100644 --- a/src/test/compile-fail/issue-4201.rs +++ b/src/test/compile-fail/issue-4201.rs @@ -14,7 +14,7 @@ fn main() { } else if false { //~^ ERROR if may be missing an else clause //~| expected type `()` -//~| found type `_` +//~| found type `{numeric}` //~| expected (), found integral variable 1 }; diff --git a/src/test/compile-fail/issue-4968.rs b/src/test/compile-fail/issue-4968.rs index 7c0905873df89..e929f0cb3113d 100644 --- a/src/test/compile-fail/issue-4968.rs +++ b/src/test/compile-fail/issue-4968.rs @@ -14,7 +14,7 @@ const A: (isize,isize) = (4,2); fn main() { match 42 { A => () } //~^ ERROR mismatched types - //~| expected type `_` + //~| expected type `{numeric}` //~| found type `(isize, isize)` //~| expected integral variable, found tuple } diff --git a/src/test/compile-fail/issue-7867.rs b/src/test/compile-fail/issue-7867.rs index e0de860b0eac3..95ba2308bfb90 100644 --- a/src/test/compile-fail/issue-7867.rs +++ b/src/test/compile-fail/issue-7867.rs @@ -25,12 +25,12 @@ fn main() { match &Some(42) { Some(x) => (), //~^ ERROR mismatched types - //~| expected type `&std::option::Option<_>` + //~| expected type `&std::option::Option<{numeric}>` //~| found type `std::option::Option<_>` //~| expected &-ptr, found enum `std::option::Option` None => () //~^ ERROR mismatched types - //~| expected type `&std::option::Option<_>` + //~| expected type `&std::option::Option<{numeric}>` //~| found type `std::option::Option<_>` //~| expected &-ptr, found enum `std::option::Option` } diff --git a/src/test/compile-fail/kindck-impl-type-params-2.rs b/src/test/compile-fail/kindck-impl-type-params-2.rs index 1cf970e150d70..93723ae9f237c 100644 --- a/src/test/compile-fail/kindck-impl-type-params-2.rs +++ b/src/test/compile-fail/kindck-impl-type-params-2.rs @@ -21,5 +21,5 @@ fn take_param(foo: &T) { } fn main() { let x: Box<_> = box 3; take_param(&x); - //~^ ERROR `Box<_>: std::marker::Copy` is not satisfied + //~^ ERROR `Box<{numeric}>: std::marker::Copy` is not satisfied } diff --git a/src/test/compile-fail/match-range-fail.rs b/src/test/compile-fail/match-range-fail.rs index 2c4c256302186..30386a589837a 100644 --- a/src/test/compile-fail/match-range-fail.rs +++ b/src/test/compile-fail/match-range-fail.rs @@ -20,7 +20,7 @@ fn main() { 10 ... "what" => () }; //~^^ ERROR only char and numeric types are allowed in range - //~| start type: _ + //~| start type: {numeric} //~| end type: &'static str match 5 { diff --git a/src/test/compile-fail/match-vec-mismatch.rs b/src/test/compile-fail/match-vec-mismatch.rs index 3ac4958e7db0f..94ac49e8f60d3 100644 --- a/src/test/compile-fail/match-vec-mismatch.rs +++ b/src/test/compile-fail/match-vec-mismatch.rs @@ -18,7 +18,7 @@ fn main() { }; match &[0, 1, 2] { - [..] => {} //~ ERROR expected an array or slice, found `&[_; 3]` + [..] => {} //~ ERROR expected an array or slice, found `&[{numeric}; 3]` }; match &[0, 1, 2] { diff --git a/src/test/compile-fail/method-self-arg-1.rs b/src/test/compile-fail/method-self-arg-1.rs index ffa5287d4b2c3..5596fb7c80799 100644 --- a/src/test/compile-fail/method-self-arg-1.rs +++ b/src/test/compile-fail/method-self-arg-1.rs @@ -24,6 +24,6 @@ fn main() { //~| expected &-ptr, found struct `Foo` Foo::bar(&42); //~ ERROR mismatched types //~| expected type `&Foo` - //~| found type `&_` + //~| found type `&{numeric}` //~| expected struct `Foo`, found integral variable } diff --git a/src/test/compile-fail/mut-pattern-mismatched.rs b/src/test/compile-fail/mut-pattern-mismatched.rs index 63e7dbd30def2..d1fd0057d2947 100644 --- a/src/test/compile-fail/mut-pattern-mismatched.rs +++ b/src/test/compile-fail/mut-pattern-mismatched.rs @@ -14,7 +14,7 @@ fn main() { // (separate lines to ensure the spans are accurate) let &_ //~ ERROR mismatched types - //~| expected type `&mut _` + //~| expected type `&mut {numeric}` //~| found type `&_` //~| values differ in mutability = foo; @@ -23,7 +23,7 @@ fn main() { let bar = &1; let &_ = bar; let &mut _ //~ ERROR mismatched types - //~| expected type `&_` + //~| expected type `&{numeric}` //~| found type `&mut _` //~| values differ in mutability = bar; diff --git a/src/test/compile-fail/no_send-rc.rs b/src/test/compile-fail/no_send-rc.rs index 69f6fcdc4afa6..7c364e8d6fb56 100644 --- a/src/test/compile-fail/no_send-rc.rs +++ b/src/test/compile-fail/no_send-rc.rs @@ -15,5 +15,5 @@ fn bar(_: T) {} fn main() { let x = Rc::new(5); bar(x); - //~^ ERROR `std::rc::Rc<_>: std::marker::Send` is not satisfied + //~^ ERROR `std::rc::Rc<{numeric}>: std::marker::Send` is not satisfied } diff --git a/src/test/compile-fail/range-1.rs b/src/test/compile-fail/range-1.rs index c00be91a2d74d..7d69eca5ad58f 100644 --- a/src/test/compile-fail/range-1.rs +++ b/src/test/compile-fail/range-1.rs @@ -23,5 +23,5 @@ pub fn main() { // Unsized type. let arr: &[_] = &[1, 2, 3]; let range = *arr..; - //~^ ERROR `[_]: std::marker::Sized` is not satisfied + //~^ ERROR `[{numeric}]: std::marker::Sized` is not satisfied } diff --git a/src/test/compile-fail/repeat_count.rs b/src/test/compile-fail/repeat_count.rs index 3a7e9cc4191ec..1bdd24abe8183 100644 --- a/src/test/compile-fail/repeat_count.rs +++ b/src/test/compile-fail/repeat_count.rs @@ -28,7 +28,7 @@ fn main() { let d = [0; 0.5]; //~^ ERROR mismatched types //~| expected type `usize` - //~| found type `_` + //~| found type `{numeric}` //~| expected usize, found floating-point variable //~| ERROR expected usize for repeat count, found float [E0306] let e = [0; "foo"]; diff --git a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs index 3140bb6e5731d..589876a7f5ff1 100644 --- a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs +++ b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs @@ -16,8 +16,8 @@ fn main() { match Foo(1.1, marker::PhantomData) { 1 => {} //~^ ERROR mismatched types - //~| expected type `Foo<_, _>` - //~| found type `_` + //~| expected type `Foo<{numeric}, _>` + //~| found type `{numeric}` //~| expected struct `Foo`, found integral variable } diff --git a/src/test/compile-fail/str-idx.rs b/src/test/compile-fail/str-idx.rs index b972a09b5c490..1fb93bd790912 100644 --- a/src/test/compile-fail/str-idx.rs +++ b/src/test/compile-fail/str-idx.rs @@ -10,5 +10,5 @@ pub fn main() { let s: &str = "hello"; - let c: u8 = s[4]; //~ ERROR `str: std::ops::Index<_>` is not satisfied + let c: u8 = s[4]; //~ ERROR `str: std::ops::Index<{numeric}>` is not satisfied } diff --git a/src/test/compile-fail/struct-base-wrong-type-2.rs b/src/test/compile-fail/struct-base-wrong-type-2.rs index 1250d0dabcd9a..9624af488dd89 100644 --- a/src/test/compile-fail/struct-base-wrong-type-2.rs +++ b/src/test/compile-fail/struct-base-wrong-type-2.rs @@ -24,6 +24,6 @@ fn main() { //~| expected struct `Foo`, found struct `Bar` let f__isize = Foo { a: 2, ..4 }; //~ ERROR mismatched types //~| expected type `Foo` - //~| found type `_` + //~| found type `{numeric}` //~| expected struct `Foo`, found integral variable } diff --git a/src/test/compile-fail/struct-base-wrong-type.rs b/src/test/compile-fail/struct-base-wrong-type.rs index 4503e465840fe..89b57f3dcd325 100644 --- a/src/test/compile-fail/struct-base-wrong-type.rs +++ b/src/test/compile-fail/struct-base-wrong-type.rs @@ -23,7 +23,7 @@ static foo: Foo = Foo { a: 2, ..bar }; //~ ERROR mismatched types //~| expected struct `Foo`, found struct `Bar` static foo_i: Foo = Foo { a: 2, ..4 }; //~ ERROR mismatched types //~| expected type `Foo` - //~| found type `_` + //~| found type `{numeric}` //~| expected struct `Foo`, found integral variable fn main() { diff --git a/src/test/compile-fail/traits-inductive-overflow-simultaneous.rs b/src/test/compile-fail/traits-inductive-overflow-simultaneous.rs index 2968e8a7ca996..97a99cb3ce7cc 100644 --- a/src/test/compile-fail/traits-inductive-overflow-simultaneous.rs +++ b/src/test/compile-fail/traits-inductive-overflow-simultaneous.rs @@ -26,5 +26,5 @@ fn is_ee(t: T) { fn main() { is_ee(4); - //~^ ERROR overflow evaluating the requirement `_: Tweedle + //~^ ERROR overflow evaluating the requirement `{numeric}: Tweedle } diff --git a/src/test/compile-fail/tuple-arity-mismatch.rs b/src/test/compile-fail/tuple-arity-mismatch.rs index e62255a4e77d4..09dc9aaf000e8 100644 --- a/src/test/compile-fail/tuple-arity-mismatch.rs +++ b/src/test/compile-fail/tuple-arity-mismatch.rs @@ -16,7 +16,7 @@ fn main() { let y = first ((1,2.0,3)); //~^ ERROR mismatched types //~| expected type `(isize, f64)` - //~| found type `(isize, f64, _)` + //~| found type `(isize, f64, {numeric})` //~| expected a tuple with 2 elements, found one with 3 elements let y = first ((1,)); diff --git a/src/test/compile-fail/tuple-index-out-of-bounds.rs b/src/test/compile-fail/tuple-index-out-of-bounds.rs index c2c41fbbb2aaf..4a9d59ea0ed7f 100644 --- a/src/test/compile-fail/tuple-index-out-of-bounds.rs +++ b/src/test/compile-fail/tuple-index-out-of-bounds.rs @@ -20,5 +20,5 @@ fn main() { tuple.0; tuple.1; tuple.2; - //~^ ERROR attempted out-of-bounds tuple index `2` on type `(_, _)` + //~^ ERROR attempted out-of-bounds tuple index `2` on type `({numeric}, {numeric})` } diff --git a/src/test/compile-fail/type-mismatch-multiple.rs b/src/test/compile-fail/type-mismatch-multiple.rs index 0f174d99fefcb..681b3a559c2b8 100644 --- a/src/test/compile-fail/type-mismatch-multiple.rs +++ b/src/test/compile-fail/type-mismatch-multiple.rs @@ -13,7 +13,7 @@ fn main() { let a: bool = 1; let b: i32 = true; } //~^ ERROR mismatched types //~| expected type `bool` -//~| found type `_` +//~| found type `{numeric}` //~| expected bool, found integral variable //~| ERROR mismatched types //~| expected i32, found bool diff --git a/src/test/compile-fail/typeck-unsafe-always-share.rs b/src/test/compile-fail/typeck-unsafe-always-share.rs index 6047f6770a7bd..50b8ae7e48cdc 100644 --- a/src/test/compile-fail/typeck-unsafe-always-share.rs +++ b/src/test/compile-fail/typeck-unsafe-always-share.rs @@ -27,7 +27,7 @@ fn test(s: T) {} fn main() { let us = UnsafeCell::new(MySync{u: UnsafeCell::new(0)}); test(us); - //~^ ERROR `std::cell::UnsafeCell>: std::marker::Sync` is not satisfied + //~^ ERROR `std::cell::UnsafeCell>: std::marker::Sync` is not satisfied let uns = UnsafeCell::new(NoSync); test(uns); diff --git a/src/test/compile-fail/vtable-res-trait-param.rs b/src/test/compile-fail/vtable-res-trait-param.rs index eb0baff0005dd..936b23075eb98 100644 --- a/src/test/compile-fail/vtable-res-trait-param.rs +++ b/src/test/compile-fail/vtable-res-trait-param.rs @@ -24,7 +24,7 @@ impl TraitB for isize { fn call_it(b: B) -> isize { let y = 4; - b.gimme_an_a(y) //~ ERROR `_: TraitA` is not satisfied + b.gimme_an_a(y) //~ ERROR `{numeric}: TraitA` is not satisfied } fn main() { diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr index ff6920d28ccf9..3a8d9a16398d1 100644 --- a/src/test/ui/mismatched_types/issue-26480.stderr +++ b/src/test/ui/mismatched_types/issue-26480.stderr @@ -5,7 +5,7 @@ error[E0308]: mismatched types | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u64, found usize $DIR/issue-26480.rs:38:5: 38:19 note: in this expansion of write! (defined in $DIR/issue-26480.rs) -error: non-scalar cast: `_` as `()` +error: non-scalar cast: `{numeric}` as `()` --> $DIR/issue-26480.rs:33:19 | 33 | ($x:expr) => ($x as ()) From cdc6afed389ecdcea0955eadae59ea6b008a58fe Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Tue, 26 Jul 2016 16:31:39 -0700 Subject: [PATCH 05/10] Add non-panicking abs() functions to all signed integer types. Currently, calling abs() on one of the signed integer types might panic (in debug mode at least) because the absolute value of the largest negative value can not be represented in that signed type. Unlike all other integer operations, there is currently not a non-panicking version on this function. This seems to just be an oversight in the design, therefore just adding it now. --- src/libcore/num/mod.rs | 84 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 97648cc34699a..4636811aa46da 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -611,6 +611,31 @@ macro_rules! int_impl { if b {None} else {Some(a)} } + /// Checked absolute value. Computes `self.abs()`, returning `None` if + /// `self == MIN`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// # #![feature(no_panic_abs)] + /// + /// use std::i32; + /// + /// assert_eq!((-5i32).checked_abs(), Some(5)); + /// assert_eq!(i32::MIN.checked_abs(), None); + /// ``` + #[unstable(feature = "no_panic_abs", issue = "35057")] + #[inline] + pub fn checked_abs(self) -> Option { + if self.is_negative() { + self.checked_neg() + } else { + Some(self) + } + } + /// Saturating integer addition. Computes `self + other`, saturating at /// the numeric bounds instead of overflowing. /// @@ -863,6 +888,36 @@ macro_rules! int_impl { self.overflowing_shr(rhs).0 } + /// Wrapping (modular) absolute value. Computes `self.abs()`, + /// wrapping around at the boundary of the type. + /// + /// The only case where such wrapping can occur is when one takes + /// the absolute value of the negative minimal value for the type + /// this is a positive value that is too large to represent in the + /// type. In such a case, this function returns `MIN` itself. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// # #![feature(no_panic_abs)] + /// + /// assert_eq!(100i8.wrapping_abs(), 100); + /// assert_eq!((-100i8).wrapping_abs(), 100); + /// assert_eq!((-128i8).wrapping_abs(), -128); + /// assert_eq!((-128i8).wrapping_abs() as u8, 128); + /// ``` + #[unstable(feature = "no_panic_abs", issue = "35057")] + #[inline(always)] + pub fn wrapping_abs(self) -> Self { + if self.is_negative() { + self.wrapping_neg() + } else { + self + } + } + /// Calculates `self` + `rhs` /// /// Returns a tuple of the addition along with a boolean indicating @@ -1071,6 +1126,35 @@ macro_rules! int_impl { (self >> (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) } + /// Computes the absolute value of `self`. + /// + /// Returns a tuple of the absolute version of self along with a + /// boolean indicating whether an overflow happened. If self is the + /// minimum value (e.g. i32::MIN for values of type i32), then the + /// minimum value will be returned again and true will be returned for + /// an overflow happening. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// # #![feature(no_panic_abs)] + /// + /// assert_eq!(10i8.overflowing_abs(), (10,false)); + /// assert_eq!((-10i8).overflowing_abs(), (10,false)); + /// assert_eq!((-128i8).overflowing_abs(), (-128,true)); + /// ``` + #[unstable(feature = "no_panic_abs", issue = "35057")] + #[inline] + pub fn overflowing_abs(self) -> (Self, bool) { + if self.is_negative() { + self.overflowing_neg() + } else { + (self, false) + } + } + /// Raises self to the power of `exp`, using exponentiation by squaring. /// /// # Examples From ea77049cfa72358d6a2d6370a3f7a6a70d93b8e8 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Thu, 28 Jul 2016 09:49:31 -0700 Subject: [PATCH 06/10] Move to {integer} and {float} --- src/librustc/util/ppaux.rs | 3 ++- src/test/compile-fail/array-not-vector.rs | 2 +- src/test/compile-fail/bad-const-type.rs | 2 +- src/test/compile-fail/coerce-mut.rs | 2 +- src/test/compile-fail/coercion-slice.rs | 2 +- src/test/compile-fail/fully-qualified-type-name1.rs | 2 +- src/test/compile-fail/if-let-arm-types.rs | 2 +- src/test/compile-fail/indexing-requires-a-uint.rs | 2 +- src/test/compile-fail/integral-variable-unification-error.rs | 4 ++-- src/test/compile-fail/issue-13466.rs | 4 ++-- src/test/compile-fail/issue-17651.rs | 2 +- src/test/compile-fail/issue-19991.rs | 2 +- src/test/compile-fail/issue-26237.rs | 2 +- src/test/compile-fail/issue-4201.rs | 2 +- src/test/compile-fail/issue-4968.rs | 2 +- src/test/compile-fail/issue-7867.rs | 4 ++-- src/test/compile-fail/kindck-impl-type-params-2.rs | 2 +- src/test/compile-fail/match-range-fail.rs | 4 ++-- src/test/compile-fail/match-vec-mismatch.rs | 2 +- src/test/compile-fail/method-self-arg-1.rs | 2 +- src/test/compile-fail/mut-pattern-mismatched.rs | 4 ++-- src/test/compile-fail/no_send-rc.rs | 2 +- src/test/compile-fail/range-1.rs | 2 +- src/test/compile-fail/repeat_count.rs | 2 +- .../compile-fail/slightly-nice-generic-literal-messages.rs | 4 ++-- src/test/compile-fail/str-idx.rs | 2 +- src/test/compile-fail/struct-base-wrong-type-2.rs | 2 +- src/test/compile-fail/struct-base-wrong-type.rs | 2 +- .../compile-fail/traits-inductive-overflow-simultaneous.rs | 2 +- src/test/compile-fail/tuple-arity-mismatch.rs | 2 +- src/test/compile-fail/tuple-index-out-of-bounds.rs | 2 +- src/test/compile-fail/type-mismatch-multiple.rs | 2 +- src/test/compile-fail/typeck-unsafe-always-share.rs | 2 +- src/test/compile-fail/vtable-res-trait-param.rs | 2 +- src/test/ui/mismatched_types/issue-26480.stderr | 2 +- 35 files changed, 42 insertions(+), 41 deletions(-) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index a33d914e7cf7a..60977a80946ff 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -975,7 +975,8 @@ impl fmt::Display for ty::InferTy { ty::IntVar(ref vid) if print_var_ids => write!(f, "{:?}", vid), ty::FloatVar(ref vid) if print_var_ids => write!(f, "{:?}", vid), ty::TyVar(_) => write!(f, "_"), - ty::IntVar(_) | ty::FloatVar(_) => write!(f, "{}", "{numeric}"), + ty::IntVar(_) => write!(f, "{}", "{integer}"), + ty::FloatVar(_) => write!(f, "{}", "{float}"), ty::FreshTy(v) => write!(f, "FreshTy({})", v), ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v), ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v) diff --git a/src/test/compile-fail/array-not-vector.rs b/src/test/compile-fail/array-not-vector.rs index b8883e4661eaa..47e1c09f380b8 100644 --- a/src/test/compile-fail/array-not-vector.rs +++ b/src/test/compile-fail/array-not-vector.rs @@ -12,7 +12,7 @@ fn main() { let _x: i32 = [1, 2, 3]; //~^ ERROR mismatched types //~| expected type `i32` - //~| found type `[{numeric}; 3]` + //~| found type `[{integer}; 3]` //~| expected i32, found array of 3 elements let x: &[i32] = &[1, 2, 3]; diff --git a/src/test/compile-fail/bad-const-type.rs b/src/test/compile-fail/bad-const-type.rs index 3b6221f0df5b8..5547d19868d34 100644 --- a/src/test/compile-fail/bad-const-type.rs +++ b/src/test/compile-fail/bad-const-type.rs @@ -11,6 +11,6 @@ static i: String = 10; //~^ ERROR mismatched types //~| expected type `std::string::String` -//~| found type `{numeric}` +//~| found type `{integer}` //~| expected struct `std::string::String`, found integral variable fn main() { println!("{}", i); } diff --git a/src/test/compile-fail/coerce-mut.rs b/src/test/compile-fail/coerce-mut.rs index 91222e58b78cc..86702a7463fd0 100644 --- a/src/test/compile-fail/coerce-mut.rs +++ b/src/test/compile-fail/coerce-mut.rs @@ -15,6 +15,6 @@ fn main() { f(&x); //~^ ERROR mismatched types //~| expected type `&mut i32` - //~| found type `&{numeric}` + //~| found type `&{integer}` //~| values differ in mutability } diff --git a/src/test/compile-fail/coercion-slice.rs b/src/test/compile-fail/coercion-slice.rs index bfec84993961e..a619f33468f4a 100644 --- a/src/test/compile-fail/coercion-slice.rs +++ b/src/test/compile-fail/coercion-slice.rs @@ -14,6 +14,6 @@ fn main() { let _: &[i32] = [0]; //~^ ERROR mismatched types //~| expected type `&[i32]` - //~| found type `[{numeric}; 1]` + //~| found type `[{integer}; 1]` //~| expected &-ptr, found array of 1 elements } diff --git a/src/test/compile-fail/fully-qualified-type-name1.rs b/src/test/compile-fail/fully-qualified-type-name1.rs index 3ae95a72abdd9..1a7ceb2e7639e 100644 --- a/src/test/compile-fail/fully-qualified-type-name1.rs +++ b/src/test/compile-fail/fully-qualified-type-name1.rs @@ -15,6 +15,6 @@ fn main() { x = 5; //~^ ERROR mismatched types //~| expected type `std::option::Option` - //~| found type `{numeric}` + //~| found type `{integer}` //~| expected enum `std::option::Option`, found integral variable } diff --git a/src/test/compile-fail/if-let-arm-types.rs b/src/test/compile-fail/if-let-arm-types.rs index 394a6fb30d7e9..40013a7ee43bb 100644 --- a/src/test/compile-fail/if-let-arm-types.rs +++ b/src/test/compile-fail/if-let-arm-types.rs @@ -12,7 +12,7 @@ fn main() { if let Some(b) = None { //~ ERROR: `if let` arms have incompatible types //~^ expected (), found integral variable //~| expected type `()` - //~| found type `{numeric}` + //~| found type `{integer}` () } else { //~ NOTE: `if let` arm with an incompatible type 1 diff --git a/src/test/compile-fail/indexing-requires-a-uint.rs b/src/test/compile-fail/indexing-requires-a-uint.rs index fe29a840f28c7..61d54b3f8e4fd 100644 --- a/src/test/compile-fail/indexing-requires-a-uint.rs +++ b/src/test/compile-fail/indexing-requires-a-uint.rs @@ -13,7 +13,7 @@ fn main() { fn bar(_: T) {} - [0][0u8]; //~ ERROR: `[{numeric}]: std::ops::Index` is not satisfied + [0][0u8]; //~ ERROR: `[{integer}]: std::ops::Index` is not satisfied [0][0]; // should infer to be a usize diff --git a/src/test/compile-fail/integral-variable-unification-error.rs b/src/test/compile-fail/integral-variable-unification-error.rs index 9dd3772c10cd9..f2686ae4d196b 100644 --- a/src/test/compile-fail/integral-variable-unification-error.rs +++ b/src/test/compile-fail/integral-variable-unification-error.rs @@ -12,7 +12,7 @@ fn main() { let mut x = 2; x = 5.0; //~^ ERROR mismatched types - //~| expected type `{numeric}` - //~| found type `{numeric}` + //~| expected type `{integer}` + //~| found type `{float}` //~| expected integral variable, found floating-point variable } diff --git a/src/test/compile-fail/issue-13466.rs b/src/test/compile-fail/issue-13466.rs index b1a5adb313fac..abddf6ba7a38d 100644 --- a/src/test/compile-fail/issue-13466.rs +++ b/src/test/compile-fail/issue-13466.rs @@ -17,13 +17,13 @@ pub fn main() { let _x: usize = match Some(1) { Ok(u) => u, //~^ ERROR mismatched types - //~| expected type `std::option::Option<{numeric}>` + //~| expected type `std::option::Option<{integer}>` //~| found type `std::result::Result<_, _>` //~| expected enum `std::option::Option`, found enum `std::result::Result` Err(e) => panic!(e) //~^ ERROR mismatched types - //~| expected type `std::option::Option<{numeric}>` + //~| expected type `std::option::Option<{integer}>` //~| found type `std::result::Result<_, _>` //~| expected enum `std::option::Option`, found enum `std::result::Result` }; diff --git a/src/test/compile-fail/issue-17651.rs b/src/test/compile-fail/issue-17651.rs index 2438c86a57c7f..3ea136aca4bec 100644 --- a/src/test/compile-fail/issue-17651.rs +++ b/src/test/compile-fail/issue-17651.rs @@ -14,5 +14,5 @@ fn main() { // FIXME (#22405): Replace `Box::new` with `box` here when/if possible. (|| Box::new(*(&[0][..])))(); - //~^ ERROR `[{numeric}]: std::marker::Sized` is not satisfied + //~^ ERROR `[{integer}]: std::marker::Sized` is not satisfied } diff --git a/src/test/compile-fail/issue-19991.rs b/src/test/compile-fail/issue-19991.rs index 77a83a608213d..e07dfaf9fe59e 100644 --- a/src/test/compile-fail/issue-19991.rs +++ b/src/test/compile-fail/issue-19991.rs @@ -14,7 +14,7 @@ fn main() { if let Some(homura) = Some("madoka") { //~ ERROR missing an else clause //~| expected type `()` - //~| found type `{numeric}` + //~| found type `{integer}` //~| expected (), found integral variable 765 }; diff --git a/src/test/compile-fail/issue-26237.rs b/src/test/compile-fail/issue-26237.rs index f2d24f3998cc2..22772e596b19e 100644 --- a/src/test/compile-fail/issue-26237.rs +++ b/src/test/compile-fail/issue-26237.rs @@ -11,7 +11,7 @@ macro_rules! macro_panic { ($not_a_function:expr, $some_argument:ident) => { $not_a_function($some_argument) - //~^ ERROR expected function, found `{numeric}` + //~^ ERROR expected function, found `{integer}` } } diff --git a/src/test/compile-fail/issue-4201.rs b/src/test/compile-fail/issue-4201.rs index 65bfeed20eaa0..b1f668d9c5e21 100644 --- a/src/test/compile-fail/issue-4201.rs +++ b/src/test/compile-fail/issue-4201.rs @@ -14,7 +14,7 @@ fn main() { } else if false { //~^ ERROR if may be missing an else clause //~| expected type `()` -//~| found type `{numeric}` +//~| found type `{integer}` //~| expected (), found integral variable 1 }; diff --git a/src/test/compile-fail/issue-4968.rs b/src/test/compile-fail/issue-4968.rs index e929f0cb3113d..77588e5c221fd 100644 --- a/src/test/compile-fail/issue-4968.rs +++ b/src/test/compile-fail/issue-4968.rs @@ -14,7 +14,7 @@ const A: (isize,isize) = (4,2); fn main() { match 42 { A => () } //~^ ERROR mismatched types - //~| expected type `{numeric}` + //~| expected type `{integer}` //~| found type `(isize, isize)` //~| expected integral variable, found tuple } diff --git a/src/test/compile-fail/issue-7867.rs b/src/test/compile-fail/issue-7867.rs index 95ba2308bfb90..ed465117344d4 100644 --- a/src/test/compile-fail/issue-7867.rs +++ b/src/test/compile-fail/issue-7867.rs @@ -25,12 +25,12 @@ fn main() { match &Some(42) { Some(x) => (), //~^ ERROR mismatched types - //~| expected type `&std::option::Option<{numeric}>` + //~| expected type `&std::option::Option<{integer}>` //~| found type `std::option::Option<_>` //~| expected &-ptr, found enum `std::option::Option` None => () //~^ ERROR mismatched types - //~| expected type `&std::option::Option<{numeric}>` + //~| expected type `&std::option::Option<{integer}>` //~| found type `std::option::Option<_>` //~| expected &-ptr, found enum `std::option::Option` } diff --git a/src/test/compile-fail/kindck-impl-type-params-2.rs b/src/test/compile-fail/kindck-impl-type-params-2.rs index 93723ae9f237c..a455a7b2d5d0f 100644 --- a/src/test/compile-fail/kindck-impl-type-params-2.rs +++ b/src/test/compile-fail/kindck-impl-type-params-2.rs @@ -21,5 +21,5 @@ fn take_param(foo: &T) { } fn main() { let x: Box<_> = box 3; take_param(&x); - //~^ ERROR `Box<{numeric}>: std::marker::Copy` is not satisfied + //~^ ERROR `Box<{integer}>: std::marker::Copy` is not satisfied } diff --git a/src/test/compile-fail/match-range-fail.rs b/src/test/compile-fail/match-range-fail.rs index 30386a589837a..f89b3e39390d3 100644 --- a/src/test/compile-fail/match-range-fail.rs +++ b/src/test/compile-fail/match-range-fail.rs @@ -20,7 +20,7 @@ fn main() { 10 ... "what" => () }; //~^^ ERROR only char and numeric types are allowed in range - //~| start type: {numeric} + //~| start type: {integer} //~| end type: &'static str match 5 { @@ -28,6 +28,6 @@ fn main() { _ => { } }; //~^^^ ERROR mismatched types - //~| expected type `_` + //~| expected type `{integer}` //~| found type `char` } diff --git a/src/test/compile-fail/match-vec-mismatch.rs b/src/test/compile-fail/match-vec-mismatch.rs index 94ac49e8f60d3..596cec167c218 100644 --- a/src/test/compile-fail/match-vec-mismatch.rs +++ b/src/test/compile-fail/match-vec-mismatch.rs @@ -18,7 +18,7 @@ fn main() { }; match &[0, 1, 2] { - [..] => {} //~ ERROR expected an array or slice, found `&[{numeric}; 3]` + [..] => {} //~ ERROR expected an array or slice, found `&[{integer}; 3]` }; match &[0, 1, 2] { diff --git a/src/test/compile-fail/method-self-arg-1.rs b/src/test/compile-fail/method-self-arg-1.rs index 5596fb7c80799..03816362d46c3 100644 --- a/src/test/compile-fail/method-self-arg-1.rs +++ b/src/test/compile-fail/method-self-arg-1.rs @@ -24,6 +24,6 @@ fn main() { //~| expected &-ptr, found struct `Foo` Foo::bar(&42); //~ ERROR mismatched types //~| expected type `&Foo` - //~| found type `&{numeric}` + //~| found type `&{integer}` //~| expected struct `Foo`, found integral variable } diff --git a/src/test/compile-fail/mut-pattern-mismatched.rs b/src/test/compile-fail/mut-pattern-mismatched.rs index d1fd0057d2947..318d121e4c2df 100644 --- a/src/test/compile-fail/mut-pattern-mismatched.rs +++ b/src/test/compile-fail/mut-pattern-mismatched.rs @@ -14,7 +14,7 @@ fn main() { // (separate lines to ensure the spans are accurate) let &_ //~ ERROR mismatched types - //~| expected type `&mut {numeric}` + //~| expected type `&mut {integer}` //~| found type `&_` //~| values differ in mutability = foo; @@ -23,7 +23,7 @@ fn main() { let bar = &1; let &_ = bar; let &mut _ //~ ERROR mismatched types - //~| expected type `&{numeric}` + //~| expected type `&{integer}` //~| found type `&mut _` //~| values differ in mutability = bar; diff --git a/src/test/compile-fail/no_send-rc.rs b/src/test/compile-fail/no_send-rc.rs index 7c364e8d6fb56..f31d378733491 100644 --- a/src/test/compile-fail/no_send-rc.rs +++ b/src/test/compile-fail/no_send-rc.rs @@ -15,5 +15,5 @@ fn bar(_: T) {} fn main() { let x = Rc::new(5); bar(x); - //~^ ERROR `std::rc::Rc<{numeric}>: std::marker::Send` is not satisfied + //~^ ERROR `std::rc::Rc<{integer}>: std::marker::Send` is not satisfied } diff --git a/src/test/compile-fail/range-1.rs b/src/test/compile-fail/range-1.rs index 7d69eca5ad58f..dc6833163a478 100644 --- a/src/test/compile-fail/range-1.rs +++ b/src/test/compile-fail/range-1.rs @@ -23,5 +23,5 @@ pub fn main() { // Unsized type. let arr: &[_] = &[1, 2, 3]; let range = *arr..; - //~^ ERROR `[{numeric}]: std::marker::Sized` is not satisfied + //~^ ERROR `[{integer}]: std::marker::Sized` is not satisfied } diff --git a/src/test/compile-fail/repeat_count.rs b/src/test/compile-fail/repeat_count.rs index 1bdd24abe8183..1758b28a32482 100644 --- a/src/test/compile-fail/repeat_count.rs +++ b/src/test/compile-fail/repeat_count.rs @@ -28,7 +28,7 @@ fn main() { let d = [0; 0.5]; //~^ ERROR mismatched types //~| expected type `usize` - //~| found type `{numeric}` + //~| found type `{float}` //~| expected usize, found floating-point variable //~| ERROR expected usize for repeat count, found float [E0306] let e = [0; "foo"]; diff --git a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs index 589876a7f5ff1..2eba7c2e534e1 100644 --- a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs +++ b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs @@ -16,8 +16,8 @@ fn main() { match Foo(1.1, marker::PhantomData) { 1 => {} //~^ ERROR mismatched types - //~| expected type `Foo<{numeric}, _>` - //~| found type `{numeric}` + //~| expected type `Foo<{float}, _>` + //~| found type `{integer}` //~| expected struct `Foo`, found integral variable } diff --git a/src/test/compile-fail/str-idx.rs b/src/test/compile-fail/str-idx.rs index 1fb93bd790912..2b2c23a3ce4e9 100644 --- a/src/test/compile-fail/str-idx.rs +++ b/src/test/compile-fail/str-idx.rs @@ -10,5 +10,5 @@ pub fn main() { let s: &str = "hello"; - let c: u8 = s[4]; //~ ERROR `str: std::ops::Index<{numeric}>` is not satisfied + let c: u8 = s[4]; //~ ERROR `str: std::ops::Index<{integer}>` is not satisfied } diff --git a/src/test/compile-fail/struct-base-wrong-type-2.rs b/src/test/compile-fail/struct-base-wrong-type-2.rs index 9624af488dd89..7e5510edb2c33 100644 --- a/src/test/compile-fail/struct-base-wrong-type-2.rs +++ b/src/test/compile-fail/struct-base-wrong-type-2.rs @@ -24,6 +24,6 @@ fn main() { //~| expected struct `Foo`, found struct `Bar` let f__isize = Foo { a: 2, ..4 }; //~ ERROR mismatched types //~| expected type `Foo` - //~| found type `{numeric}` + //~| found type `{integer}` //~| expected struct `Foo`, found integral variable } diff --git a/src/test/compile-fail/struct-base-wrong-type.rs b/src/test/compile-fail/struct-base-wrong-type.rs index 89b57f3dcd325..3703b15d4db83 100644 --- a/src/test/compile-fail/struct-base-wrong-type.rs +++ b/src/test/compile-fail/struct-base-wrong-type.rs @@ -23,7 +23,7 @@ static foo: Foo = Foo { a: 2, ..bar }; //~ ERROR mismatched types //~| expected struct `Foo`, found struct `Bar` static foo_i: Foo = Foo { a: 2, ..4 }; //~ ERROR mismatched types //~| expected type `Foo` - //~| found type `{numeric}` + //~| found type `{integer}` //~| expected struct `Foo`, found integral variable fn main() { diff --git a/src/test/compile-fail/traits-inductive-overflow-simultaneous.rs b/src/test/compile-fail/traits-inductive-overflow-simultaneous.rs index 97a99cb3ce7cc..777746a189c5f 100644 --- a/src/test/compile-fail/traits-inductive-overflow-simultaneous.rs +++ b/src/test/compile-fail/traits-inductive-overflow-simultaneous.rs @@ -26,5 +26,5 @@ fn is_ee(t: T) { fn main() { is_ee(4); - //~^ ERROR overflow evaluating the requirement `{numeric}: Tweedle + //~^ ERROR overflow evaluating the requirement `{integer}: Tweedle } diff --git a/src/test/compile-fail/tuple-arity-mismatch.rs b/src/test/compile-fail/tuple-arity-mismatch.rs index 09dc9aaf000e8..a71f441029472 100644 --- a/src/test/compile-fail/tuple-arity-mismatch.rs +++ b/src/test/compile-fail/tuple-arity-mismatch.rs @@ -16,7 +16,7 @@ fn main() { let y = first ((1,2.0,3)); //~^ ERROR mismatched types //~| expected type `(isize, f64)` - //~| found type `(isize, f64, {numeric})` + //~| found type `(isize, f64, {integer})` //~| expected a tuple with 2 elements, found one with 3 elements let y = first ((1,)); diff --git a/src/test/compile-fail/tuple-index-out-of-bounds.rs b/src/test/compile-fail/tuple-index-out-of-bounds.rs index 4a9d59ea0ed7f..4597cf3d350c4 100644 --- a/src/test/compile-fail/tuple-index-out-of-bounds.rs +++ b/src/test/compile-fail/tuple-index-out-of-bounds.rs @@ -20,5 +20,5 @@ fn main() { tuple.0; tuple.1; tuple.2; - //~^ ERROR attempted out-of-bounds tuple index `2` on type `({numeric}, {numeric})` + //~^ ERROR attempted out-of-bounds tuple index `2` on type `({integer}, {integer})` } diff --git a/src/test/compile-fail/type-mismatch-multiple.rs b/src/test/compile-fail/type-mismatch-multiple.rs index 681b3a559c2b8..9359c03595669 100644 --- a/src/test/compile-fail/type-mismatch-multiple.rs +++ b/src/test/compile-fail/type-mismatch-multiple.rs @@ -13,7 +13,7 @@ fn main() { let a: bool = 1; let b: i32 = true; } //~^ ERROR mismatched types //~| expected type `bool` -//~| found type `{numeric}` +//~| found type `{integer}` //~| expected bool, found integral variable //~| ERROR mismatched types //~| expected i32, found bool diff --git a/src/test/compile-fail/typeck-unsafe-always-share.rs b/src/test/compile-fail/typeck-unsafe-always-share.rs index 50b8ae7e48cdc..f0172777cdabb 100644 --- a/src/test/compile-fail/typeck-unsafe-always-share.rs +++ b/src/test/compile-fail/typeck-unsafe-always-share.rs @@ -27,7 +27,7 @@ fn test(s: T) {} fn main() { let us = UnsafeCell::new(MySync{u: UnsafeCell::new(0)}); test(us); - //~^ ERROR `std::cell::UnsafeCell>: std::marker::Sync` is not satisfied + //~^ ERROR `std::cell::UnsafeCell>: std::marker::Sync` is not satisfied let uns = UnsafeCell::new(NoSync); test(uns); diff --git a/src/test/compile-fail/vtable-res-trait-param.rs b/src/test/compile-fail/vtable-res-trait-param.rs index 936b23075eb98..8b3e9369ece46 100644 --- a/src/test/compile-fail/vtable-res-trait-param.rs +++ b/src/test/compile-fail/vtable-res-trait-param.rs @@ -24,7 +24,7 @@ impl TraitB for isize { fn call_it(b: B) -> isize { let y = 4; - b.gimme_an_a(y) //~ ERROR `{numeric}: TraitA` is not satisfied + b.gimme_an_a(y) //~ ERROR `{integer}: TraitA` is not satisfied } fn main() { diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr index 3a8d9a16398d1..45638a65915c4 100644 --- a/src/test/ui/mismatched_types/issue-26480.stderr +++ b/src/test/ui/mismatched_types/issue-26480.stderr @@ -5,7 +5,7 @@ error[E0308]: mismatched types | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u64, found usize $DIR/issue-26480.rs:38:5: 38:19 note: in this expansion of write! (defined in $DIR/issue-26480.rs) -error: non-scalar cast: `{numeric}` as `()` +error: non-scalar cast: `{integer}` as `()` --> $DIR/issue-26480.rs:33:19 | 33 | ($x:expr) => ($x as ()) From 6dc98cf099d1fc3209e1354144f2190c052c8a0b Mon Sep 17 00:00:00 2001 From: mcarton Date: Thu, 28 Jul 2016 19:33:31 +0200 Subject: [PATCH 07/10] Revert "Remove unused methods from MultiSpan" This reverts commit f7019a4e2f80577d38ec35fcebd64d5970b15f78. This removed the only way to make a suggestion with more than one substitute. Bring it back until we come up with a better solution. --- src/libsyntax_pos/lib.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index c96be8fec2b02..7dfe19452a2a9 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -193,6 +193,20 @@ impl MultiSpan { } } + pub fn from_span(primary_span: Span) -> MultiSpan { + MultiSpan { + primary_spans: vec![primary_span], + span_labels: vec![] + } + } + + pub fn from_spans(vec: Vec) -> MultiSpan { + MultiSpan { + primary_spans: vec, + span_labels: vec![] + } + } + pub fn push_span_label(&mut self, span: Span, label: String) { self.span_labels.push((span, label)); } @@ -240,10 +254,7 @@ impl MultiSpan { impl From for MultiSpan { fn from(span: Span) -> MultiSpan { - MultiSpan { - primary_spans: vec![span], - span_labels: vec![] - } + MultiSpan::from_span(span) } } From f459e801fd6cfad61e81ed12e6c364f0776d6ed4 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Thu, 28 Jul 2016 22:09:31 -0400 Subject: [PATCH 08/10] Rewrite `collections::LinkedList::append` doc example. --- src/libcollections/linked_list.rs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index 3d5c3125fae24..6842f02e0e19b 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -203,19 +203,22 @@ impl LinkedList { /// ``` /// use std::collections::LinkedList; /// - /// let mut a = LinkedList::new(); - /// let mut b = LinkedList::new(); - /// a.push_back(1); - /// a.push_back(2); - /// b.push_back(3); - /// b.push_back(4); + /// let mut list1 = LinkedList::new(); + /// list1.push_back('a'); /// - /// a.append(&mut b); + /// let mut list2 = LinkedList::new(); + /// list2.push_back('b'); + /// list2.push_back('c'); /// - /// for e in &a { - /// println!("{}", e); // prints 1, then 2, then 3, then 4 - /// } - /// println!("{}", b.len()); // prints 0 + /// list1.append(&mut list2); + /// + /// let mut iter = list1.iter(); + /// assert_eq!(iter.next(), Some(&'a')); + /// assert_eq!(iter.next(), Some(&'b')); + /// assert_eq!(iter.next(), Some(&'c')); + /// assert!(iter.next().is_none()); + /// + /// assert!(list2.is_empty()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn append(&mut self, other: &mut Self) { From 2a41b31a88356d5a772cb644ab8d29af0bf44742 Mon Sep 17 00:00:00 2001 From: Wang Xuerui Date: Fri, 29 Jul 2016 16:40:10 +0800 Subject: [PATCH 09/10] syntax_ext: format: fix ICE with bad named arguments --- src/libsyntax_ext/format.rs | 4 +++- src/test/compile-fail/ifmt-bad-arg.rs | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 94bb78edaacdb..1f6f57c70f72f 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -406,7 +406,9 @@ impl<'a, 'b> Context<'a, 'b> { let arg_idx = match arg_index_consumed.get_mut(i) { None => 0, // error already emitted elsewhere Some(offset) => { - let arg_idx = self.arg_index_map[i][*offset]; + let ref idx_map = self.arg_index_map[i]; + // unwrap_or branch: error already emitted elsewhere + let arg_idx = *idx_map.get(*offset).unwrap_or(&0); *offset += 1; arg_idx } diff --git a/src/test/compile-fail/ifmt-bad-arg.rs b/src/test/compile-fail/ifmt-bad-arg.rs index 272ad980feb46..59c61a42e077f 100644 --- a/src/test/compile-fail/ifmt-bad-arg.rs +++ b/src/test/compile-fail/ifmt-bad-arg.rs @@ -41,6 +41,12 @@ fn main() { //~^ ERROR invalid reference to argument `0` (no arguments given) //~^^ ERROR invalid reference to argument `1` (no arguments given) + // bad named arguments, #35082 + + format!("{valuea} {valueb}", valuea=5, valuec=7); + //~^ ERROR there is no argument named `valueb` + //~^^ ERROR named argument never used + // bad syntax of the format string format!("{"); //~ ERROR: expected `'}'` but string was terminated From 415fde498a561f22eb7e431b31a31906764a196b Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 28 Jul 2016 05:58:45 -0400 Subject: [PATCH 10/10] intravisit: Fold functionality of IdVisitor into the regular Visitor. --- src/librustc/hir/intravisit.rs | 255 ++++++---------------- src/librustc/hir/map/collector.rs | 2 +- src/librustc/hir/mod.rs | 6 +- src/librustc/lint/context.rs | 36 ++- src/librustc/middle/cstore.rs | 7 +- src/librustc/middle/effect.rs | 4 +- src/librustc/middle/liveness.rs | 2 +- src/librustc_borrowck/borrowck/mod.rs | 2 +- src/librustc_const_eval/check_match.rs | 10 +- src/librustc_incremental/calculate_svh.rs | 8 +- src/librustc_metadata/astencode.rs | 10 +- src/librustc_mir/mir_map.rs | 2 +- src/librustc_passes/consts.rs | 2 +- src/librustc_passes/rvalues.rs | 2 +- src/librustc_privacy/lib.rs | 2 +- src/librustc_typeck/check/upvar.rs | 2 +- 16 files changed, 119 insertions(+), 233 deletions(-) diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 442c85af22a26..a06fc21764de4 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -94,11 +94,14 @@ pub trait Visitor<'v> : Sized { /////////////////////////////////////////////////////////////////////////// + fn visit_id(&mut self, _node_id: NodeId) { + // Nothing to do. + } fn visit_name(&mut self, _span: Span, _name: Name) { // Nothing to do. } - fn visit_mod(&mut self, m: &'v Mod, _s: Span, _n: NodeId) { - walk_mod(self, m) + fn visit_mod(&mut self, m: &'v Mod, _s: Span, n: NodeId) { + walk_mod(self, m, n) } fn visit_foreign_item(&mut self, i: &'v ForeignItem) { walk_foreign_item(self, i) @@ -135,8 +138,8 @@ pub trait Visitor<'v> : Sized { fn visit_where_predicate(&mut self, predicate: &'v WherePredicate) { walk_where_predicate(self, predicate) } - fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, _: NodeId) { - walk_fn(self, fk, fd, b, s) + fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, id: NodeId) { + walk_fn(self, fk, fd, b, s, id) } fn visit_trait_item(&mut self, ti: &'v TraitItem) { walk_trait_item(self, ti) @@ -157,7 +160,7 @@ pub trait Visitor<'v> : Sized { s: &'v VariantData, _: Name, _: &'v Generics, - _: NodeId, + _parent_id: NodeId, _: Span) { walk_struct_def(self, s) } @@ -225,24 +228,28 @@ pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) { } pub fn walk_macro_def<'v, V: Visitor<'v>>(visitor: &mut V, macro_def: &'v MacroDef) { + visitor.visit_id(macro_def.id); visitor.visit_name(macro_def.span, macro_def.name); walk_opt_name(visitor, macro_def.span, macro_def.imported_from); walk_list!(visitor, visit_attribute, ¯o_def.attrs); } -pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod) { +pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod, mod_node_id: NodeId) { + visitor.visit_id(mod_node_id); for &item_id in &module.item_ids { visitor.visit_nested_item(item_id); } } pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) { + visitor.visit_id(local.id); visitor.visit_pat(&local.pat); walk_list!(visitor, visit_ty, &local.ty); walk_list!(visitor, visit_expr, &local.init); } pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) { + visitor.visit_id(lifetime.id); visitor.visit_name(lifetime.span, lifetime.name); } @@ -263,6 +270,7 @@ pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V, pub fn walk_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v TraitRef) where V: Visitor<'v> { + visitor.visit_id(trait_ref.ref_id); visitor.visit_path(&trait_ref.path, trait_ref.ref_id) } @@ -271,9 +279,11 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { visitor.visit_name(item.span, item.name); match item.node { ItemExternCrate(opt_name) => { + visitor.visit_id(item.id); walk_opt_name(visitor, item.span, opt_name) } ItemUse(ref vp) => { + visitor.visit_id(item.id); match vp.node { ViewPathSimple(name, ref path) => { visitor.visit_name(vp.span, name); @@ -292,6 +302,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { } ItemStatic(ref typ, _, ref expr) | ItemConst(ref typ, ref expr) => { + visitor.visit_id(item.id); visitor.visit_ty(typ); visitor.visit_expr(expr); } @@ -309,23 +320,29 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { item.id) } ItemMod(ref module) => { + // visit_mod() takes care of visiting the Item's NodeId visitor.visit_mod(module, item.span, item.id) } ItemForeignMod(ref foreign_module) => { + visitor.visit_id(item.id); walk_list!(visitor, visit_foreign_item, &foreign_module.items); } ItemTy(ref typ, ref type_parameters) => { + visitor.visit_id(item.id); visitor.visit_ty(typ); visitor.visit_generics(type_parameters) } ItemEnum(ref enum_definition, ref type_parameters) => { visitor.visit_generics(type_parameters); + // visit_enum_def() takes care of visiting the Item's NodeId visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span) } ItemDefaultImpl(_, ref trait_ref) => { + visitor.visit_id(item.id); visitor.visit_trait_ref(trait_ref) } ItemImpl(_, _, ref type_parameters, ref opt_trait_reference, ref typ, ref impl_items) => { + visitor.visit_id(item.id); visitor.visit_generics(type_parameters); walk_list!(visitor, visit_trait_ref, opt_trait_reference); visitor.visit_ty(typ); @@ -333,9 +350,11 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { } ItemStruct(ref struct_definition, ref generics) => { visitor.visit_generics(generics); + visitor.visit_id(item.id); visitor.visit_variant_data(struct_definition, item.name, generics, item.id, item.span); } ItemTrait(_, ref generics, ref bounds, ref methods) => { + visitor.visit_id(item.id); visitor.visit_generics(generics); walk_list!(visitor, visit_ty_param_bound, bounds); walk_list!(visitor, visit_trait_item, methods); @@ -348,6 +367,7 @@ pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V, enum_definition: &'v EnumDef, generics: &'v Generics, item_id: NodeId) { + visitor.visit_id(item_id); walk_list!(visitor, visit_variant, &enum_definition.variants, @@ -358,18 +378,20 @@ pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V, pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V, variant: &'v Variant, generics: &'v Generics, - item_id: NodeId) { + parent_item_id: NodeId) { visitor.visit_name(variant.span, variant.node.name); visitor.visit_variant_data(&variant.node.data, variant.node.name, generics, - item_id, + parent_item_id, variant.span); walk_list!(visitor, visit_expr, &variant.node.disr_expr); walk_list!(visitor, visit_attribute, &variant.node.attrs); } pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { + visitor.visit_id(typ.id); + match typ.node { TyVec(ref ty) => { visitor.visit_ty(ty) @@ -421,6 +443,7 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) { pub fn walk_path_list_item<'v, V: Visitor<'v>>(visitor: &mut V, _prefix: &'v Path, item: &'v PathListItem) { + visitor.visit_id(item.node.id()); walk_opt_name(visitor, item.span, item.node.name()); walk_opt_name(visitor, item.span, item.node.rename()); } @@ -450,11 +473,13 @@ pub fn walk_path_parameters<'v, V: Visitor<'v>>(visitor: &mut V, pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V, type_binding: &'v TypeBinding) { + visitor.visit_id(type_binding.id); visitor.visit_name(type_binding.span, type_binding.name); visitor.visit_ty(&type_binding.ty); } pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { + visitor.visit_id(pattern.id); match pattern.node { PatKind::TupleStruct(ref path, ref children, _) => { visitor.visit_path(path, pattern.id); @@ -499,6 +524,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { } pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem) { + visitor.visit_id(foreign_item.id); visitor.visit_vis(&foreign_item.vis); visitor.visit_name(foreign_item.span, foreign_item.name); @@ -526,11 +552,13 @@ pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v TyPar pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) { for param in &generics.ty_params { + visitor.visit_id(param.id); visitor.visit_name(param.span, param.name); walk_list!(visitor, visit_ty_param_bound, ¶m.bounds); walk_list!(visitor, visit_ty, ¶m.default); } walk_list!(visitor, visit_lifetime_def, &generics.lifetimes); + visitor.visit_id(generics.where_clause.id); walk_list!(visitor, visit_where_predicate, &generics.where_clause.predicates); } @@ -557,6 +585,7 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>( ref path, ref ty, ..}) => { + visitor.visit_id(id); visitor.visit_path(path, id); visitor.visit_ty(ty); } @@ -571,6 +600,7 @@ pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FunctionR pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) { for argument in &function_declaration.inputs { + visitor.visit_id(argument.id); visitor.visit_pat(&argument.pat); visitor.visit_ty(&argument.ty) } @@ -579,6 +609,7 @@ pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: & pub fn walk_fn_decl_nopat<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) { for argument in &function_declaration.inputs { + visitor.visit_id(argument.id); visitor.visit_ty(&argument.ty) } walk_fn_ret_ty(visitor, &function_declaration.output) @@ -600,7 +631,9 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'v>, function_declaration: &'v FnDecl, function_body: &'v Block, - _span: Span) { + _span: Span, + id: NodeId) { + visitor.visit_id(id); walk_fn_decl(visitor, function_declaration); walk_fn_kind(visitor, function_kind); visitor.visit_block(function_body) @@ -611,10 +644,12 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai walk_list!(visitor, visit_attribute, &trait_item.attrs); match trait_item.node { ConstTraitItem(ref ty, ref default) => { + visitor.visit_id(trait_item.id); visitor.visit_ty(ty); walk_list!(visitor, visit_expr, default); } MethodTraitItem(ref sig, None) => { + visitor.visit_id(trait_item.id); visitor.visit_generics(&sig.generics); walk_fn_decl(visitor, &sig.decl); } @@ -629,6 +664,7 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai trait_item.id); } TypeTraitItem(ref bounds, ref default) => { + visitor.visit_id(trait_item.id); walk_list!(visitor, visit_ty_param_bound, bounds); walk_list!(visitor, visit_ty, default); } @@ -641,6 +677,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt walk_list!(visitor, visit_attribute, &impl_item.attrs); match impl_item.node { ImplItemKind::Const(ref ty, ref expr) => { + visitor.visit_id(impl_item.id); visitor.visit_ty(ty); visitor.visit_expr(expr); } @@ -655,16 +692,19 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt impl_item.id); } ImplItemKind::Type(ref ty) => { + visitor.visit_id(impl_item.id); visitor.visit_ty(ty); } } } pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &'v VariantData) { + visitor.visit_id(struct_definition.id()); walk_list!(visitor, visit_struct_field, struct_definition.fields()); } pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v StructField) { + visitor.visit_id(struct_field.id); visitor.visit_vis(&struct_field.vis); visitor.visit_name(struct_field.span, struct_field.name); visitor.visit_ty(&struct_field.ty); @@ -672,14 +712,20 @@ pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v } pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) { + visitor.visit_id(block.id); walk_list!(visitor, visit_stmt, &block.stmts); walk_list!(visitor, visit_expr, &block.expr); } pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) { match statement.node { - StmtDecl(ref declaration, _) => visitor.visit_decl(declaration), - StmtExpr(ref expression, _) | StmtSemi(ref expression, _) => { + StmtDecl(ref declaration, id) => { + visitor.visit_id(id); + visitor.visit_decl(declaration) + } + StmtExpr(ref expression, id) | + StmtSemi(ref expression, id) => { + visitor.visit_id(id); visitor.visit_expr(expression) } } @@ -693,6 +739,7 @@ pub fn walk_decl<'v, V: Visitor<'v>>(visitor: &mut V, declaration: &'v Decl) { } pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { + visitor.visit_id(expression.id); match expression.node { ExprBox(ref subexpression) => { visitor.visit_expr(subexpression) @@ -815,6 +862,7 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) { pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility) { if let Visibility::Restricted { ref path, id } = *vis { + visitor.visit_id(id); visitor.visit_path(path, id) } } @@ -837,15 +885,16 @@ impl IdRange { self.min >= self.max } + pub fn contains(&self, id: NodeId) -> bool { + id >= self.min && id < self.max + } + pub fn add(&mut self, id: NodeId) { self.min = cmp::min(self.min, id); self.max = cmp::max(self.max, id + 1); } } -pub trait IdVisitingOperation { - fn visit_id(&mut self, node_id: NodeId); -} pub struct IdRangeComputingVisitor { pub result: IdRange, @@ -861,181 +910,12 @@ impl IdRangeComputingVisitor { } } -impl IdVisitingOperation for IdRangeComputingVisitor { +impl<'v> Visitor<'v> for IdRangeComputingVisitor { fn visit_id(&mut self, id: NodeId) { self.result.add(id); } } -pub struct IdVisitor<'a, O: 'a> { - operation: &'a mut O, - - // In general, the id visitor visits the contents of an item, but - // not including nested trait/impl items, nor other nested items. - // The base visitor itself always skips nested items, but not - // trait/impl items. This means in particular that if you start by - // visiting a trait or an impl, you should not visit the - // trait/impl items respectively. This is handled by setting - // `skip_members` to true when `visit_item` is on the stack. This - // way, if the user begins by calling `visit_trait_item`, we will - // visit the trait item, but if they begin with `visit_item`, we - // won't visit the (nested) trait items. - skip_members: bool, -} - -impl<'a, O: IdVisitingOperation> IdVisitor<'a, O> { - pub fn new(operation: &'a mut O) -> IdVisitor<'a, O> { - IdVisitor { operation: operation, skip_members: false } - } - - fn visit_generics_helper(&mut self, generics: &Generics) { - for type_parameter in generics.ty_params.iter() { - self.operation.visit_id(type_parameter.id) - } - for lifetime in &generics.lifetimes { - self.operation.visit_id(lifetime.lifetime.id) - } - } -} - -impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { - fn visit_mod(&mut self, module: &Mod, _: Span, node_id: NodeId) { - self.operation.visit_id(node_id); - walk_mod(self, module) - } - - fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) { - self.operation.visit_id(foreign_item.id); - walk_foreign_item(self, foreign_item) - } - - fn visit_item(&mut self, item: &Item) { - assert!(!self.skip_members); - self.skip_members = true; - - self.operation.visit_id(item.id); - match item.node { - ItemUse(ref view_path) => { - match view_path.node { - ViewPathSimple(_, _) | - ViewPathGlob(_) => {} - ViewPathList(_, ref paths) => { - for path in paths { - self.operation.visit_id(path.node.id()) - } - } - } - } - _ => {} - } - walk_item(self, item); - - self.skip_members = false; - } - - fn visit_local(&mut self, local: &Local) { - self.operation.visit_id(local.id); - walk_local(self, local) - } - - fn visit_block(&mut self, block: &Block) { - self.operation.visit_id(block.id); - walk_block(self, block) - } - - fn visit_stmt(&mut self, statement: &Stmt) { - self.operation.visit_id(statement.node.id()); - walk_stmt(self, statement) - } - - fn visit_pat(&mut self, pattern: &Pat) { - self.operation.visit_id(pattern.id); - walk_pat(self, pattern) - } - - fn visit_expr(&mut self, expression: &Expr) { - self.operation.visit_id(expression.id); - walk_expr(self, expression) - } - - fn visit_ty(&mut self, typ: &Ty) { - self.operation.visit_id(typ.id); - walk_ty(self, typ) - } - - fn visit_generics(&mut self, generics: &Generics) { - self.visit_generics_helper(generics); - walk_generics(self, generics) - } - - fn visit_fn(&mut self, - function_kind: FnKind<'v>, - function_declaration: &'v FnDecl, - block: &'v Block, - span: Span, - node_id: NodeId) { - self.operation.visit_id(node_id); - - match function_kind { - FnKind::ItemFn(_, generics, _, _, _, _, _) => { - self.visit_generics_helper(generics) - } - FnKind::Method(_, sig, _, _) => { - self.visit_generics_helper(&sig.generics) - } - FnKind::Closure(_) => {} - } - - for argument in &function_declaration.inputs { - self.operation.visit_id(argument.id) - } - - walk_fn(self, function_kind, function_declaration, block, span); - } - - fn visit_struct_field(&mut self, struct_field: &StructField) { - self.operation.visit_id(struct_field.id); - walk_struct_field(self, struct_field) - } - - fn visit_variant_data(&mut self, - struct_def: &VariantData, - _: Name, - _: &Generics, - _: NodeId, - _: Span) { - self.operation.visit_id(struct_def.id()); - walk_struct_def(self, struct_def); - } - - fn visit_trait_item(&mut self, ti: &TraitItem) { - if !self.skip_members { - self.operation.visit_id(ti.id); - walk_trait_item(self, ti); - } - } - - fn visit_impl_item(&mut self, ii: &ImplItem) { - if !self.skip_members { - self.operation.visit_id(ii.id); - walk_impl_item(self, ii); - } - } - - fn visit_lifetime(&mut self, lifetime: &Lifetime) { - self.operation.visit_id(lifetime.id); - } - - fn visit_lifetime_def(&mut self, def: &LifetimeDef) { - self.visit_lifetime(&def.lifetime); - } - - fn visit_trait_ref(&mut self, trait_ref: &TraitRef) { - self.operation.visit_id(trait_ref.ref_id); - walk_trait_ref(self, trait_ref); - } -} - /// Computes the id range for a single fn body, ignoring nested items. pub fn compute_id_range_for_fn_body(fk: FnKind, decl: &FnDecl, @@ -1043,8 +923,7 @@ pub fn compute_id_range_for_fn_body(fk: FnKind, sp: Span, id: NodeId) -> IdRange { - let mut visitor = IdRangeComputingVisitor { result: IdRange::max() }; - let mut id_visitor = IdVisitor::new(&mut visitor); - id_visitor.visit_fn(fk, decl, body, sp, id); - id_visitor.operation.result + let mut visitor = IdRangeComputingVisitor::new(); + visitor.visit_fn(fk, decl, body, sp, id); + visitor.result() } diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 693d7a2edfca5..b3f222b22e891 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -197,7 +197,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { fn visit_fn(&mut self, fk: intravisit::FnKind<'ast>, fd: &'ast FnDecl, b: &'ast Block, s: Span, id: NodeId) { assert_eq!(self.parent_node, id); - intravisit::walk_fn(self, fk, fd, b, s); + intravisit::walk_fn(self, fk, fd, b, s, id); } fn visit_block(&mut self, block: &'ast Block) { diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 655f80ec07238..20bf4f7d3edbb 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1362,9 +1362,9 @@ pub enum ViewPath_ { /// TraitRef's appear in impls. /// /// resolve maps each TraitRef's ref_id to its defining trait; that's all -/// that the ref_id is for. The impl_id maps to the "self type" of this impl. -/// If this impl is an ItemImpl, the impl_id is redundant (it could be the -/// same as the impl's node id). +/// that the ref_id is for. Note that ref_id's value is not the NodeId of the +/// trait being referred to but just a unique NodeId that serves as a key +/// within the DefMap. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct TraitRef { pub path: Path, diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index ce3d72de9ae99..a55957c4d193e 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -45,7 +45,6 @@ use syntax_pos::Span; use errors::DiagnosticBuilder; use hir; use hir::intravisit as hir_visit; -use hir::intravisit::{IdVisitor, IdVisitingOperation}; use syntax::visit as ast_visit; /// Information about the registered lints. @@ -663,9 +662,11 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> { } fn visit_ids(&mut self, f: F) - where F: FnOnce(&mut IdVisitor) + where F: FnOnce(&mut IdVisitor) { - let mut v = IdVisitor::new(self); + let mut v = IdVisitor { + cx: self + }; f(&mut v); } } @@ -779,7 +780,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> { fn visit_fn(&mut self, fk: hir_visit::FnKind<'v>, decl: &'v hir::FnDecl, body: &'v hir::Block, span: Span, id: ast::NodeId) { run_lints!(self, check_fn, late_passes, fk, decl, body, span, id); - hir_visit::walk_fn(self, fk, decl, body, span); + hir_visit::walk_fn(self, fk, decl, body, span, id); run_lints!(self, check_fn_post, late_passes, fk, decl, body, span, id); } @@ -820,7 +821,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> { fn visit_mod(&mut self, m: &hir::Mod, s: Span, n: ast::NodeId) { run_lints!(self, check_mod, late_passes, m, s, n); - hir_visit::walk_mod(self, m); + hir_visit::walk_mod(self, m, n); run_lints!(self, check_mod_post, late_passes, m, s, n); } @@ -859,7 +860,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> { fn visit_trait_item(&mut self, trait_item: &hir::TraitItem) { self.with_lint_attrs(&trait_item.attrs, |cx| { run_lints!(cx, check_trait_item, late_passes, trait_item); - cx.visit_ids(|v| v.visit_trait_item(trait_item)); + cx.visit_ids(|v| hir_visit::walk_trait_item(v, trait_item)); hir_visit::walk_trait_item(cx, trait_item); run_lints!(cx, check_trait_item_post, late_passes, trait_item); }); @@ -868,7 +869,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> { fn visit_impl_item(&mut self, impl_item: &hir::ImplItem) { self.with_lint_attrs(&impl_item.attrs, |cx| { run_lints!(cx, check_impl_item, late_passes, impl_item); - cx.visit_ids(|v| v.visit_impl_item(impl_item)); + cx.visit_ids(|v| hir_visit::walk_impl_item(v, impl_item)); hir_visit::walk_impl_item(cx, impl_item); run_lints!(cx, check_impl_item_post, late_passes, impl_item); }); @@ -1046,16 +1047,30 @@ impl<'a> ast_visit::Visitor for EarlyContext<'a> { } } +struct IdVisitor<'a, 'b: 'a, 'tcx: 'a+'b> { + cx: &'a mut LateContext<'b, 'tcx> +} + // Output any lints that were previously added to the session. -impl<'a, 'tcx> IdVisitingOperation for LateContext<'a, 'tcx> { +impl<'a, 'b, 'tcx, 'v> hir_visit::Visitor<'v> for IdVisitor<'a, 'b, 'tcx> { + fn visit_id(&mut self, id: ast::NodeId) { - if let Some(lints) = self.sess().lints.borrow_mut().remove(&id) { + if let Some(lints) = self.cx.sess().lints.borrow_mut().remove(&id) { debug!("LateContext::visit_id: id={:?} lints={:?}", id, lints); for (lint_id, span, msg) in lints { - self.span_lint(lint_id.lint, span, &msg[..]) + self.cx.span_lint(lint_id.lint, span, &msg[..]) } } } + + fn visit_trait_item(&mut self, _ti: &hir::TraitItem) { + // Do not recurse into trait or impl items automatically. These are + // processed separately by calling hir_visit::walk_trait_item() + } + + fn visit_impl_item(&mut self, _ii: &hir::ImplItem) { + // See visit_trait_item() + } } enum CheckLintNameResult { @@ -1172,7 +1187,6 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Visit the whole crate. cx.with_lint_attrs(&krate.attrs, |cx| { - cx.visit_id(ast::CRATE_NODE_ID); cx.visit_ids(|v| { hir_visit::walk_crate(v, krate); }); diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index fd9463b13c055..484aacfd9ecc0 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -44,7 +44,7 @@ use syntax::parse::token::InternedString; use syntax_pos::Span; use rustc_back::target::Target; use hir; -use hir::intravisit::{IdVisitor, IdVisitingOperation, Visitor}; +use hir::intravisit::Visitor; pub use self::DefLike::{DlDef, DlField, DlImpl}; pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown}; @@ -292,11 +292,6 @@ impl InlinedItem { InlinedItem::ImplItem(_, ref ii) => visitor.visit_impl_item(ii), } } - - pub fn visit_ids(&self, operation: &mut O) { - let mut id_visitor = IdVisitor::new(operation); - self.visit(&mut id_visitor); - } } // FIXME: find a better place for this? diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 6fe98119c7060..446767ecbcaba 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -79,7 +79,7 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> { impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { fn visit_fn(&mut self, fn_kind: FnKind<'v>, fn_decl: &'v hir::FnDecl, - block: &'v hir::Block, span: Span, _: ast::NodeId) { + block: &'v hir::Block, span: Span, id: ast::NodeId) { let (is_item_fn, is_unsafe_fn) = match fn_kind { FnKind::ItemFn(_, _, unsafety, _, _, _, _) => @@ -96,7 +96,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { self.unsafe_context = UnsafeContext::new(SafeContext) } - intravisit::walk_fn(self, fn_kind, fn_decl, block, span); + intravisit::walk_fn(self, fn_kind, fn_decl, block, span, id); self.unsafe_context = old_unsafe_context } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index ea3765c76f89b..1222b5f42a19f 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -390,7 +390,7 @@ fn visit_fn(ir: &mut IrMaps, // gather up the various local variables, significant expressions, // and so forth: - intravisit::walk_fn(&mut fn_maps, fk, decl, body, sp); + intravisit::walk_fn(&mut fn_maps, fk, decl, body, sp, id); // Special nodes and variables: // - exit_ln represents the end of the fn, either by return or panic diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index e86120b73bf97..1fe47cd485387 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -197,7 +197,7 @@ fn borrowck_fn(this: &mut BorrowckCtxt, decl, body); - intravisit::walk_fn(this, fk, decl, body, sp); + intravisit::walk_fn(this, fk, decl, body, sp, id); } fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 915a0cf0bdc73..d3952de2fbe30 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -34,7 +34,7 @@ use std::iter::{FromIterator, IntoIterator, repeat}; use rustc::hir; use rustc::hir::{Pat, PatKind}; -use rustc::hir::intravisit::{self, IdVisitor, IdVisitingOperation, Visitor, FnKind}; +use rustc::hir::intravisit::{self, Visitor, FnKind}; use rustc_back::slice; use syntax::ast::{self, DUMMY_NODE_ID, NodeId}; @@ -474,7 +474,7 @@ struct RenamingRecorder<'map> { renaming_map: &'map mut FnvHashMap<(NodeId, Span), NodeId> } -impl<'map> IdVisitingOperation for RenamingRecorder<'map> { +impl<'v, 'map> Visitor<'v> for RenamingRecorder<'map> { fn visit_id(&mut self, node_id: NodeId) { let key = (node_id, self.origin_span); self.renaming_map.insert(key, self.substituted_node_id); @@ -529,9 +529,7 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> { renaming_map: renaming_map, }; - let mut id_visitor = IdVisitor::new(&mut renaming_recorder); - - id_visitor.visit_expr(const_expr); + renaming_recorder.visit_expr(const_expr); } } } @@ -1049,7 +1047,7 @@ fn check_fn(cx: &mut MatchCheckCtxt, _ => cx.param_env = ParameterEnvironment::for_item(cx.tcx, fn_id), } - intravisit::walk_fn(cx, kind, decl, body, sp); + intravisit::walk_fn(cx, kind, decl, body, sp, fn_id); for input in &decl.inputs { check_irrefutable(cx, &input.pat, true); diff --git a/src/librustc_incremental/calculate_svh.rs b/src/librustc_incremental/calculate_svh.rs index 7b1e0d2d0c8b6..f9fa5154e20f3 100644 --- a/src/librustc_incremental/calculate_svh.rs +++ b/src/librustc_incremental/calculate_svh.rs @@ -384,9 +384,9 @@ mod svh_visitor { SawItem.hash(self.st); visit::walk_item(self, i) } - fn visit_mod(&mut self, m: &'a Mod, _s: Span, _n: NodeId) { + fn visit_mod(&mut self, m: &'a Mod, _s: Span, n: NodeId) { debug!("visit_mod: st={:?}", self.st); - SawMod.hash(self.st); visit::walk_mod(self, m) + SawMod.hash(self.st); visit::walk_mod(self, m, n) } fn visit_decl(&mut self, d: &'a Decl) { @@ -405,9 +405,9 @@ mod svh_visitor { } fn visit_fn(&mut self, fk: FnKind<'a>, fd: &'a FnDecl, - b: &'a Block, s: Span, _: NodeId) { + b: &'a Block, s: Span, n: NodeId) { debug!("visit_fn: st={:?}", self.st); - SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s) + SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s, n) } fn visit_trait_item(&mut self, ti: &'a TraitItem) { diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 2e8c5a7c23418..454c805ab577e 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -18,7 +18,7 @@ use rustc::session::Session; use rustc::hir; use rustc::hir::fold; use rustc::hir::fold::Folder; -use rustc::hir::intravisit::{IdRange, IdRangeComputingVisitor, IdVisitingOperation}; +use rustc::hir::intravisit::{Visitor, IdRangeComputingVisitor, IdRange}; use common as c; use cstore; @@ -693,7 +693,7 @@ struct SideTableEncodingIdVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> { rbml_w: &'a mut Encoder<'b>, } -impl<'a, 'b, 'c, 'tcx> IdVisitingOperation for +impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for SideTableEncodingIdVisitor<'a, 'b, 'c, 'tcx> { fn visit_id(&mut self, id: ast::NodeId) { encode_side_tables_for_id(self.ecx, self.rbml_w, id) @@ -704,7 +704,7 @@ fn encode_side_tables_for_ii(ecx: &e::EncodeContext, rbml_w: &mut Encoder, ii: &InlinedItem) { rbml_w.start_tag(c::tag_table as usize); - ii.visit_ids(&mut SideTableEncodingIdVisitor { + ii.visit(&mut SideTableEncodingIdVisitor { ecx: ecx, rbml_w: rbml_w }); @@ -1242,9 +1242,9 @@ fn copy_item_types(dcx: &DecodeContext, ii: &InlinedItem, orig_did: DefId) { } } -fn inlined_item_id_range(v: &InlinedItem) -> IdRange { +fn inlined_item_id_range(ii: &InlinedItem) -> IdRange { let mut visitor = IdRangeComputingVisitor::new(); - v.visit_ids(&mut visitor); + ii.visit(&mut visitor); visitor.result() } diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs index b7c5f35892b0b..11d6b0779275e 100644 --- a/src/librustc_mir/mir_map.rs +++ b/src/librustc_mir/mir_map.rs @@ -250,7 +250,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> { build::construct_fn(cx, id, arguments, fn_sig.output, body) }); - intravisit::walk_fn(self, fk, decl, body, span); + intravisit::walk_fn(self, fk, decl, body, span, id); } } diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index b0ba38f1db673..1030a4b0116de 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -158,7 +158,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { let qualif = self.with_mode(mode, |this| { this.with_euv(Some(fn_id), |euv| euv.walk_fn(fd, b)); - intravisit::walk_fn(this, fk, fd, b, s); + intravisit::walk_fn(this, fk, fd, b, s, fn_id); this.qualif }); diff --git a/src/librustc_passes/rvalues.rs b/src/librustc_passes/rvalues.rs index 4684683f02501..2a5dc50cae92f 100644 --- a/src/librustc_passes/rvalues.rs +++ b/src/librustc_passes/rvalues.rs @@ -49,7 +49,7 @@ impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for RvalueContext<'a, 'tcx> { let mut euv = euv::ExprUseVisitor::new(&mut delegate, &infcx); euv.walk_fn(fd, b); }); - intravisit::walk_fn(self, fk, fd, b, s) + intravisit::walk_fn(self, fk, fd, b, s, fn_id) } } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index acaf9b9b2faee..793e52d379203 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -291,7 +291,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { } } - intravisit::walk_mod(self, m); + intravisit::walk_mod(self, m, id); } fn visit_macro_def(&mut self, md: &'v hir::MacroDef) { diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 702dd5f8de58a..6fdbc3282bccd 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -503,7 +503,7 @@ impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for AdjustBorrowKind<'a, 'gcx, 'tcx> { span: Span, id: ast::NodeId) { - intravisit::walk_fn(self, fn_kind, decl, body, span); + intravisit::walk_fn(self, fn_kind, decl, body, span, id); self.analyze_closure(id, span, decl, body); } }