diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 0db4fb3890100..3d5ae7f7faba8 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -103,7 +103,6 @@ //! More documentation can be found in each respective module below, and you can //! also check out the `src/bootstrap/README.md` file for more information. -#![feature(core_intrinsics)] #![feature(drain_filter)] use std::cell::{Cell, RefCell}; diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index e41a7afd3e223..604be7d5f68d0 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -361,6 +361,7 @@ impl Ordering { /// assert!(data == b); /// ``` #[inline] + #[must_use] #[stable(feature = "rust1", since = "1.0.0")] pub fn reverse(self) -> Ordering { match self { @@ -398,6 +399,7 @@ impl Ordering { /// assert_eq!(result, Ordering::Less); /// ``` #[inline] + #[must_use] #[stable(feature = "ordering_chaining", since = "1.17.0")] pub fn then(self, other: Ordering) -> Ordering { match self { @@ -435,6 +437,7 @@ impl Ordering { /// assert_eq!(result, Ordering::Less); /// ``` #[inline] + #[must_use] #[stable(feature = "ordering_chaining", since = "1.17.0")] pub fn then_with Ordering>(self, f: F) -> Ordering { match self { @@ -576,6 +579,7 @@ pub trait Ord: Eq + PartialOrd { /// assert_eq!(10.cmp(&5), Ordering::Greater); /// assert_eq!(5.cmp(&5), Ordering::Equal); /// ``` + #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn cmp(&self, other: &Self) -> Ordering; @@ -591,6 +595,7 @@ pub trait Ord: Eq + PartialOrd { /// ``` #[stable(feature = "ord_max_min", since = "1.21.0")] #[inline] + #[must_use] fn max(self, other: Self) -> Self where Self: Sized, @@ -610,6 +615,7 @@ pub trait Ord: Eq + PartialOrd { /// ``` #[stable(feature = "ord_max_min", since = "1.21.0")] #[inline] + #[must_use] fn min(self, other: Self) -> Self where Self: Sized, @@ -635,6 +641,7 @@ pub trait Ord: Eq + PartialOrd { /// assert!(0.clamp(-2, 1) == 0); /// assert!(2.clamp(-2, 1) == 1); /// ``` + #[must_use] #[unstable(feature = "clamp", issue = "44095")] fn clamp(self, min: Self, max: Self) -> Self where @@ -915,6 +922,7 @@ pub macro PartialOrd($item:item) { /// assert_eq!(2, cmp::min(2, 2)); /// ``` #[inline] +#[must_use] #[stable(feature = "rust1", since = "1.0.0")] pub fn min(v1: T, v2: T) -> T { v1.min(v2) @@ -935,6 +943,7 @@ pub fn min(v1: T, v2: T) -> T { /// assert_eq!(cmp::min_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2); /// ``` #[inline] +#[must_use] #[unstable(feature = "cmp_min_max_by", issue = "64460")] pub fn min_by Ordering>(v1: T, v2: T, compare: F) -> T { match compare(&v1, &v2) { @@ -958,6 +967,7 @@ pub fn min_by Ordering>(v1: T, v2: T, compare: F) -> T { /// assert_eq!(cmp::min_by_key(-2, 2, |x: &i32| x.abs()), -2); /// ``` #[inline] +#[must_use] #[unstable(feature = "cmp_min_max_by", issue = "64460")] pub fn min_by_key K, K: Ord>(v1: T, v2: T, mut f: F) -> T { min_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2))) @@ -978,6 +988,7 @@ pub fn min_by_key K, K: Ord>(v1: T, v2: T, mut f: F) -> T { /// assert_eq!(2, cmp::max(2, 2)); /// ``` #[inline] +#[must_use] #[stable(feature = "rust1", since = "1.0.0")] pub fn max(v1: T, v2: T) -> T { v1.max(v2) @@ -998,6 +1009,7 @@ pub fn max(v1: T, v2: T) -> T { /// assert_eq!(cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 2); /// ``` #[inline] +#[must_use] #[unstable(feature = "cmp_min_max_by", issue = "64460")] pub fn max_by Ordering>(v1: T, v2: T, compare: F) -> T { match compare(&v1, &v2) { @@ -1021,6 +1033,7 @@ pub fn max_by Ordering>(v1: T, v2: T, compare: F) -> T { /// assert_eq!(cmp::max_by_key(-2, 2, |x: &i32| x.abs()), 2); /// ``` #[inline] +#[must_use] #[unstable(feature = "cmp_min_max_by", issue = "64460")] pub fn max_by_key K, K: Ord>(v1: T, v2: T, mut f: F) -> T { max_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2))) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index e35c91206b8d4..9b32442371c37 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -317,7 +317,7 @@ impl Option { // Getting to contained values ///////////////////////////////////////////////////////////////////////// - /// Unwraps an option, yielding the content of a [`Some`]. + /// Returns the contained [`Some`] value, consuming the `self` value. /// /// # Panics /// @@ -348,17 +348,22 @@ impl Option { } } - /// Moves the value `v` out of the `Option` if it is [`Some(v)`]. + /// Returns the contained [`Some`] value, consuming the `self` value. /// - /// In general, because this function may panic, its use is discouraged. + /// Because this function may panic, its use is generally discouraged. /// Instead, prefer to use pattern matching and handle the [`None`] - /// case explicitly. + /// case explicitly, or call [`unwrap_or`], [`unwrap_or_else`], or + /// [`unwrap_or_default`]. + /// + /// [`unwrap_or`]: #method.unwrap_or + /// [`unwrap_or_else`]: #method.unwrap_or_else + /// [`unwrap_or_default`]: #method.unwrap_or_default /// /// # Panics /// /// Panics if the self value equals [`None`]. /// - /// [`Some(v)`]: #variant.Some + /// [`Some`]: #variant.Some /// [`None`]: #variant.None /// /// # Examples @@ -382,12 +387,13 @@ impl Option { } } - /// Returns the contained value or a default. + /// Returns the contained [`Some`] value or a provided default. /// /// Arguments passed to `unwrap_or` are eagerly evaluated; if you are passing /// the result of a function call, it is recommended to use [`unwrap_or_else`], /// which is lazily evaluated. /// + /// [`Some`]: #variant.Some /// [`unwrap_or_else`]: #method.unwrap_or_else /// /// # Examples @@ -405,7 +411,7 @@ impl Option { } } - /// Returns the contained value or computes it from a closure. + /// Returns the contained [`Some`] value or computes it from a closure. /// /// # Examples /// @@ -986,7 +992,7 @@ impl Option<&mut T> { } impl Option { - /// Unwraps an option, expecting [`None`] and returning nothing. + /// Consumes `self` while expecting [`None`] and returning nothing. /// /// # Panics /// @@ -1029,7 +1035,7 @@ impl Option { } } - /// Unwraps an option, expecting [`None`] and returning nothing. + /// Consumes `self` while expecting [`None`] and returning nothing. /// /// # Panics /// @@ -1074,7 +1080,7 @@ impl Option { } impl Option { - /// Returns the contained value or a default + /// Returns the contained [`Some`] value or a default /// /// Consumes the `self` argument then, if [`Some`], returns the contained /// value, otherwise if [`None`], returns the [default value] for that diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 809d4bace8e84..0bc29e1bc662c 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -798,8 +798,7 @@ impl Result { } } - /// Unwraps a result, yielding the content of an [`Ok`]. - /// Else, it returns `optb`. + /// Returns the contained [`Ok`] value or a provided default. /// /// Arguments passed to `unwrap_or` are eagerly evaluated; if you are passing /// the result of a function call, it is recommended to use [`unwrap_or_else`], @@ -814,27 +813,25 @@ impl Result { /// Basic usage: /// /// ``` - /// let optb = 2; + /// let default = 2; /// let x: Result = Ok(9); - /// assert_eq!(x.unwrap_or(optb), 9); + /// assert_eq!(x.unwrap_or(default), 9); /// /// let x: Result = Err("error"); - /// assert_eq!(x.unwrap_or(optb), optb); + /// assert_eq!(x.unwrap_or(default), default); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn unwrap_or(self, optb: T) -> T { + pub fn unwrap_or(self, default: T) -> T { match self { Ok(t) => t, - Err(_) => optb, + Err(_) => default, } } - /// Unwraps a result, yielding the content of an [`Ok`]. - /// If the value is an [`Err`] then it calls `op` with its value. + /// Returns the contained [`Ok`] value or computes it from a closure. /// /// [`Ok`]: enum.Result.html#variant.Ok - /// [`Err`]: enum.Result.html#variant.Err /// /// # Examples /// @@ -937,7 +934,44 @@ impl Result<&mut T, E> { } impl Result { - /// Unwraps a result, yielding the content of an [`Ok`]. + /// Returns the contained [`Ok`] value, consuming the `self` value. + /// + /// # Panics + /// + /// Panics if the value is an [`Err`], with a panic message including the + /// passed message, and the content of the [`Err`]. + /// + /// [`Ok`]: enum.Result.html#variant.Ok + /// [`Err`]: enum.Result.html#variant.Err + /// + /// # Examples + /// + /// Basic usage: + /// + /// ```{.should_panic} + /// let x: Result = Err("emergency failure"); + /// x.expect("Testing expect"); // panics with `Testing expect: emergency failure` + /// ``` + #[inline] + #[track_caller] + #[stable(feature = "result_expect", since = "1.4.0")] + pub fn expect(self, msg: &str) -> T { + match self { + Ok(t) => t, + Err(e) => unwrap_failed(msg, &e), + } + } + + /// Returns the contained [`Ok`] value, consuming the `self` value. + /// + /// Because this function may panic, its use is generally discouraged. + /// Instead, prefer to use pattern matching and handle the [`Err`] + /// case explicitly, or call [`unwrap_or`], [`unwrap_or_else`], or + /// [`unwrap_or_default`]. + /// + /// [`unwrap_or`]: #method.unwrap_or + /// [`unwrap_or_else`]: #method.unwrap_or_else + /// [`unwrap_or_default`]: #method.unwrap_or_default /// /// # Panics /// @@ -969,13 +1003,15 @@ impl Result { Err(e) => unwrap_failed("called `Result::unwrap()` on an `Err` value", &e), } } +} - /// Unwraps a result, yielding the content of an [`Ok`]. +impl Result { + /// Returns the contained [`Err`] value, consuming the `self` value. /// /// # Panics /// - /// Panics if the value is an [`Err`], with a panic message including the - /// passed message, and the content of the [`Err`]. + /// Panics if the value is an [`Ok`], with a panic message including the + /// passed message, and the content of the [`Ok`]. /// /// [`Ok`]: enum.Result.html#variant.Ok /// [`Err`]: enum.Result.html#variant.Err @@ -985,22 +1021,20 @@ impl Result { /// Basic usage: /// /// ```{.should_panic} - /// let x: Result = Err("emergency failure"); - /// x.expect("Testing expect"); // panics with `Testing expect: emergency failure` + /// let x: Result = Ok(10); + /// x.expect_err("Testing expect_err"); // panics with `Testing expect_err: 10` /// ``` #[inline] #[track_caller] - #[stable(feature = "result_expect", since = "1.4.0")] - pub fn expect(self, msg: &str) -> T { + #[stable(feature = "result_expect_err", since = "1.17.0")] + pub fn expect_err(self, msg: &str) -> E { match self { - Ok(t) => t, - Err(e) => unwrap_failed(msg, &e), + Ok(t) => unwrap_failed(msg, &t), + Err(e) => e, } } -} -impl Result { - /// Unwraps a result, yielding the content of an [`Err`]. + /// Returns the contained [`Err`] value, consuming the `self` value. /// /// # Panics /// @@ -1031,38 +1065,10 @@ impl Result { Err(e) => e, } } - - /// Unwraps a result, yielding the content of an [`Err`]. - /// - /// # Panics - /// - /// Panics if the value is an [`Ok`], with a panic message including the - /// passed message, and the content of the [`Ok`]. - /// - /// [`Ok`]: enum.Result.html#variant.Ok - /// [`Err`]: enum.Result.html#variant.Err - /// - /// # Examples - /// - /// Basic usage: - /// - /// ```{.should_panic} - /// let x: Result = Ok(10); - /// x.expect_err("Testing expect_err"); // panics with `Testing expect_err: 10` - /// ``` - #[inline] - #[track_caller] - #[stable(feature = "result_expect_err", since = "1.17.0")] - pub fn expect_err(self, msg: &str) -> E { - match self { - Ok(t) => unwrap_failed(msg, &t), - Err(e) => e, - } - } } impl Result { - /// Returns the contained value or a default + /// Returns the contained [`Ok`] value or a default /// /// Consumes the `self` argument then, if [`Ok`], returns the contained /// value, otherwise if [`Err`], returns the default value for that @@ -1101,7 +1107,7 @@ impl Result { #[unstable(feature = "unwrap_infallible", reason = "newly added", issue = "61695")] impl> Result { - /// Unwraps a result that can never be an [`Err`], yielding the content of the [`Ok`]. + /// Returns the contained [`Ok`] value, but never panics. /// /// Unlike [`unwrap`], this method is known to never panic on the /// result types it is implemented for. Therefore, it can be used diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index aade4c3f74c54..76e4b5f01b775 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -249,6 +249,12 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { self.hash_spans } + #[inline] + fn hash_def_id(&mut self, def_id: DefId, hasher: &mut StableHasher) { + let hcx = self; + hcx.def_path_hash(def_id).hash_stable(hcx, hasher); + } + fn byte_pos_to_line_and_col( &mut self, byte: BytePos, diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 0155861549773..625d8a4670f22 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -11,12 +11,6 @@ use smallvec::SmallVec; use std::mem; impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> { - #[inline] - fn hash_def_id(&mut self, def_id: DefId, hasher: &mut StableHasher) { - let hcx = self; - hcx.def_path_hash(def_id).hash_stable(hcx, hasher); - } - #[inline] fn hash_hir_id(&mut self, hir_id: hir::HirId, hasher: &mut StableHasher) { let hcx = self; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 2f77792f7a198..ceac68704d2b0 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -27,7 +27,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![feature(arbitrary_self_types)] #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(box_syntax)] @@ -39,21 +38,15 @@ #![feature(marker_trait_attr)] #![feature(extern_types)] #![feature(nll)] -#![feature(optin_builtin_traits)] #![feature(option_expect_none)] #![feature(range_is_empty)] #![feature(specialization)] -#![feature(unboxed_closures)] -#![feature(thread_local)] -#![feature(trace_macros)] #![feature(trusted_len)] #![feature(vec_remove_item)] #![feature(stmt_expr_attributes)] -#![feature(integer_atomics)] #![feature(test)] #![feature(in_band_lifetimes)] #![feature(crate_visibility_modifier)] -#![feature(log_syntax)] #![feature(associated_type_bounds)] #![feature(rustc_attrs)] #![feature(hash_raw_entry)] diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index d1bccb961c48b..7cb1f3aa0e851 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -323,7 +323,7 @@ rustc_queries! { query associated_item(_: DefId) -> ty::AssocItem {} /// Collects the associated items defined on a trait or impl. - query associated_items(key: DefId) -> ty::AssocItemsIterator<'tcx> { + query associated_items(key: DefId) -> &'tcx [ty::AssocItem] { desc { |tcx| "collecting associated items of {}", tcx.def_path_str(key) } } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 50068b89687ba..9e6e6047b35d2 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -539,6 +539,7 @@ fn vtable_methods<'tcx>( tcx.arena.alloc_from_iter(supertraits(tcx, trait_ref).flat_map(move |trait_ref| { let trait_methods = tcx .associated_items(trait_ref.def_id()) + .iter() .filter(|item| item.kind == ty::AssocKind::Method); // Now list each method's DefId and InternalSubsts (for within its trait). diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index d0dbfe73c91d5..3c886ce7f3eb7 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -212,6 +212,7 @@ fn object_safety_violations_for_trait( // Check methods for violations. let mut violations: Vec<_> = tcx .associated_items(trait_def_id) + .iter() .filter(|item| item.kind == ty::AssocKind::Method) .filter_map(|item| { object_safety_violation_for_method(tcx, trait_def_id, &item) @@ -277,6 +278,7 @@ fn object_safety_violations_for_trait( violations.extend( tcx.associated_items(trait_def_id) + .iter() .filter(|item| item.kind == ty::AssocKind::Const) .map(|item| ObjectSafetyViolation::AssocConst(item.ident.name, item.ident.span)), ); @@ -632,7 +634,9 @@ fn object_ty_for_trait<'tcx>( let mut associated_types = traits::supertraits(tcx, ty::Binder::dummy(trait_ref)) .flat_map(|super_trait_ref| { - tcx.associated_items(super_trait_ref.def_id()).map(move |item| (super_trait_ref, item)) + tcx.associated_items(super_trait_ref.def_id()) + .iter() + .map(move |item| (super_trait_ref, item)) }) .filter(|(_, item)| item.kind == ty::AssocKind::Type) .collect::>(); diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index fffcf66075f93..8ea990d1e937e 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -1436,7 +1436,7 @@ fn assoc_ty_def( { return specialization_graph::NodeItem { node: specialization_graph::Node::Impl(impl_def_id), - item, + item: *item, }; } } diff --git a/src/librustc/traits/types/specialization_graph.rs b/src/librustc/traits/types/specialization_graph.rs index 3086850db6d9c..36a84369d4a3a 100644 --- a/src/librustc/traits/types/specialization_graph.rs +++ b/src/librustc/traits/types/specialization_graph.rs @@ -81,7 +81,7 @@ impl<'tcx> Node { } /// Iterate over the items defined directly by the given (impl or trait) node. - pub fn items(&self, tcx: TyCtxt<'tcx>) -> ty::AssocItemsIterator<'tcx> { + pub fn items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [ty::AssocItem] { tcx.associated_items(self.def_id()) } @@ -98,8 +98,10 @@ impl<'tcx> Node { ) -> Option { use crate::ty::AssocKind::*; - tcx.associated_items(self.def_id()).find(move |impl_item| { - match (trait_item_kind, impl_item.kind) { + tcx.associated_items(self.def_id()) + .iter() + .find(move |impl_item| { + match (trait_item_kind, impl_item.kind) { | (Const, Const) | (Method, Method) | (Type, Type) @@ -112,7 +114,8 @@ impl<'tcx> Node { | (OpaqueTy, _) => false, } - }) + }) + .copied() } pub fn def_id(&self) -> DefId { diff --git a/src/librustc/traits/wf.rs b/src/librustc/traits/wf.rs index 9fa3c87477951..c44d45e75807e 100644 --- a/src/librustc/traits/wf.rs +++ b/src/librustc/traits/wf.rs @@ -166,7 +166,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { let extend_cause_with_original_assoc_item_obligation = |cause: &mut traits::ObligationCause<'_>, pred: &ty::Predicate<'_>, - trait_assoc_items: ty::AssocItemsIterator<'_>| { + trait_assoc_items: &[ty::AssocItem]| { let trait_item = tcx .hir() .as_local_hir_id(trait_ref.def_id) @@ -283,6 +283,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { ) = (&proj.skip_binder().self_ty().kind, item.map(|i| &i.kind)) { if let Some((impl_item, trait_assoc_item)) = trait_assoc_items + .iter() .filter(|i| i.def_id == *item_def_id) .next() .and_then(|trait_assoc_item| { @@ -325,7 +326,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { extend_cause_with_original_assoc_item_obligation( &mut cause, &pred, - trait_assoc_items.clone(), + trait_assoc_items, ); traits::Obligation::new(cause, param_env, pred) }); diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs index db034d1618cea..f4006a1cd40c1 100644 --- a/src/librustc/ty/adjustment.rs +++ b/src/librustc/ty/adjustment.rs @@ -122,6 +122,7 @@ impl<'tcx> OverloadedDeref<'tcx> { }; let method_def_id = tcx .associated_items(trait_def_id.unwrap()) + .iter() .find(|m| m.kind == ty::AssocKind::Method) .unwrap() .def_id; diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 51a18f8eae274..c7f19513f666e 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -376,6 +376,7 @@ impl<'tcx> Instance<'tcx> { let fn_once = tcx.lang_items().fn_once_trait().unwrap(); let call_once = tcx .associated_items(fn_once) + .iter() .find(|it| it.kind == ty::AssocKind::Method) .unwrap() .def_id; diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 2538322431ec9..0118fc4c8ac84 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2705,14 +2705,14 @@ impl<'tcx> TyCtxt<'tcx> { .for_each(|&body_id| f(self.hir().body_owner_def_id(body_id))); } - pub fn provided_trait_methods(self, id: DefId) -> Vec { + pub fn provided_trait_methods(self, id: DefId) -> impl Iterator { self.associated_items(id) + .iter() .filter(|item| item.kind == AssocKind::Method && item.defaultness.has_value()) - .collect() } pub fn trait_relevant_for_never(self, did: DefId) -> bool { - self.associated_items(did).any(|item| item.relevant_for_never()) + self.associated_items(did).iter().any(|item| item.relevant_for_never()) } pub fn opt_item_name(self, def_id: DefId) -> Option { @@ -2974,25 +2974,6 @@ impl<'tcx> TyCtxt<'tcx> { } } -#[derive(Copy, Clone, HashStable)] -pub struct AssocItemsIterator<'tcx> { - pub items: &'tcx [AssocItem], -} - -impl<'tcx> Iterator for AssocItemsIterator<'tcx> { - type Item = AssocItem; - - #[inline] - fn next(&mut self) -> Option { - if let Some((first, rest)) = self.items.split_first() { - self.items = rest; - Some(*first) - } else { - None - } - } -} - #[derive(Clone, HashStable)] pub struct AdtSizedConstraint<'tcx>(pub &'tcx [Ty<'tcx>]); diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 4c5bc3debde54..0718853b1df59 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1066,6 +1066,7 @@ impl<'tcx> ProjectionTy<'tcx> { ) -> ProjectionTy<'tcx> { let item_def_id = tcx .associated_items(trait_ref.def_id) + .iter() .find(|item| { item.kind == ty::AssocKind::Type && tcx.hygienic_eq(item_name, item.ident, trait_ref.def_id) diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 4dfff85d53147..5d5fa4090c800 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -355,7 +355,7 @@ impl<'tcx> TyCtxt<'tcx> { let mut dtor_did = None; let ty = self.type_of(adt_did); self.for_each_relevant_impl(drop_trait, ty, |impl_did| { - if let Some(item) = self.associated_items(impl_did).next() { + if let Some(item) = self.associated_items(impl_did).first() { if validate(self, impl_did).is_ok() { dtor_did = Some(item.def_id); } diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index d9077d1606f3a..78bf149f0e01a 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -1074,12 +1074,15 @@ impl<'a> State<'a> { fn print_associated_type( &mut self, ident: ast::Ident, + generics: &ast::Generics, bounds: &ast::GenericBounds, ty: Option<&ast::Ty>, ) { self.word_space("type"); self.print_ident(ident); + self.print_generic_params(&generics.params); self.print_type_bounds(":", bounds); + self.print_where_clause(&generics.where_clause); if let Some(ty) = ty { self.s.space(); self.word_space("="); @@ -1474,7 +1477,7 @@ impl<'a> State<'a> { self.print_fn_full(sig, item.ident, &item.generics, &item.vis, body, &item.attrs); } ast::AssocItemKind::TyAlias(bounds, ty) => { - self.print_associated_type(item.ident, bounds, ty.as_deref()); + self.print_associated_type(item.ident, &item.generics, bounds, ty.as_deref()); } ast::AssocItemKind::Macro(mac) => { self.print_mac(mac); diff --git a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs index eba05ed5d7787..cdb9657e1ff3c 100644 --- a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs +++ b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs @@ -66,14 +66,8 @@ fn make_mir_scope( if !has_variables.contains(scope) { // Do not create a DIScope if there are no variables // defined in this MIR Scope, to avoid debuginfo bloat. - - // However, we don't skip creating a nested scope if - // our parent is the root, because we might want to - // put arguments in the root and not have shadowing. - if parent_scope.scope_metadata.unwrap() != fn_metadata { - debug_context.scopes[scope] = parent_scope; - return; - } + debug_context.scopes[scope] = parent_scope; + return; } let loc = span_start(cx, scope_data.span); diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index c4a52a73e25d9..c1a7bb5087824 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -5,7 +5,6 @@ use rustc_codegen_ssa::mir::debuginfo::VariableKind::*; use self::metadata::{file_metadata, type_metadata, TypeMap}; use self::namespace::mangled_name_of_instance; -use self::source_loc::InternalDebugLocation::{self, UnknownLocation}; use self::type_names::compute_debuginfo_type_name; use self::utils::{create_DIArray, is_node_local_to_unit, span_start, DIB}; @@ -38,7 +37,7 @@ use std::ffi::CString; use rustc::ty::layout::{self, HasTyCtxt, LayoutOf, Size}; use rustc_codegen_ssa::traits::*; use rustc_span::symbol::Symbol; -use rustc_span::{self, BytePos, Pos, Span}; +use rustc_span::{self, BytePos, Span}; use smallvec::SmallVec; use syntax::ast; @@ -52,7 +51,6 @@ mod utils; pub use self::create_scope_map::compute_mir_scopes; pub use self::metadata::create_global_var_metadata; pub use self::metadata::extend_scope_to_file; -pub use self::source_loc::set_source_location; #[allow(non_upper_case_globals)] const DW_TAG_auto_variable: c_uint = 0x100; @@ -148,7 +146,6 @@ impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> { // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). fn dbg_var_addr( &mut self, - dbg_context: &FunctionDebugContext<&'ll DIScope>, dbg_var: &'ll DIVariable, scope_metadata: &'ll DIScope, variable_alloca: Self::Value, @@ -156,12 +153,11 @@ impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> { indirect_offsets: &[Size], span: Span, ) { - assert!(!dbg_context.source_locations_enabled); let cx = self.cx(); - let loc = span_start(cx, span); - // Convert the direct and indirect offsets to address ops. + // FIXME(eddyb) use `const`s instead of getting the values via FFI, + // the values should match the ones in the DWARF standard anyway. let op_deref = || unsafe { llvm::LLVMRustDIBuilderCreateOpDeref() }; let op_plus_uconst = || unsafe { llvm::LLVMRustDIBuilderCreateOpPlusUconst() }; let mut addr_ops = SmallVec::<[_; 8]>::new(); @@ -178,37 +174,32 @@ impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> { } } - // FIXME(eddyb) maybe this information could be extracted from `var`, + // FIXME(eddyb) maybe this information could be extracted from `dbg_var`, // to avoid having to pass it down in both places? - source_loc::set_debug_location( - self, - InternalDebugLocation::new(scope_metadata, loc.line, loc.col.to_usize()), - ); + // NB: `var` doesn't seem to know about the column, so that's a limitation. + let dbg_loc = cx.create_debug_loc(scope_metadata, span); unsafe { - let debug_loc = llvm::LLVMGetCurrentDebugLocation(self.llbuilder); // FIXME(eddyb) replace `llvm.dbg.declare` with `llvm.dbg.addr`. - let instr = llvm::LLVMRustDIBuilderInsertDeclareAtEnd( + llvm::LLVMRustDIBuilderInsertDeclareAtEnd( DIB(cx), variable_alloca, dbg_var, addr_ops.as_ptr(), addr_ops.len() as c_uint, - debug_loc, + dbg_loc, self.llbb(), ); - - llvm::LLVMSetInstDebugLocation(self.llbuilder, instr); } - source_loc::set_debug_location(self, UnknownLocation); } - fn set_source_location( - &mut self, - debug_context: &mut FunctionDebugContext<&'ll DIScope>, - scope: &'ll DIScope, - span: Span, - ) { - set_source_location(debug_context, &self, scope, span) + fn set_source_location(&mut self, scope: &'ll DIScope, span: Span) { + debug!("set_source_location: {}", self.sess().source_map().span_to_string(span)); + + let dbg_loc = self.cx().create_debug_loc(scope, span); + + unsafe { + llvm::LLVMSetCurrentDebugLocation(self.llbuilder, dbg_loc); + } } fn insert_reference_to_gdb_debug_scripts_section_global(&mut self) { gdb::insert_reference_to_gdb_debug_scripts_section_global(self) @@ -342,7 +333,6 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { }; let mut fn_debug_context = FunctionDebugContext { scopes: IndexVec::from_elem(null_scope, &mir.source_scopes), - source_locations_enabled: false, defining_crate: def_id.krate, }; diff --git a/src/librustc_codegen_llvm/debuginfo/source_loc.rs b/src/librustc_codegen_llvm/debuginfo/source_loc.rs index 6afaca44e0e96..1f871c7d207a4 100644 --- a/src/librustc_codegen_llvm/debuginfo/source_loc.rs +++ b/src/librustc_codegen_llvm/debuginfo/source_loc.rs @@ -1,79 +1,35 @@ -use self::InternalDebugLocation::*; - use super::metadata::UNKNOWN_COLUMN_NUMBER; use super::utils::{debug_context, span_start}; -use rustc_codegen_ssa::mir::debuginfo::FunctionDebugContext; -use crate::builder::Builder; -use crate::llvm; +use crate::common::CodegenCx; use crate::llvm::debuginfo::DIScope; -use log::debug; +use crate::llvm::{self, Value}; use rustc_codegen_ssa::traits::*; use libc::c_uint; use rustc_span::{Pos, Span}; -/// Sets the current debug location at the beginning of the span. -/// -/// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). -pub fn set_source_location( - debug_context: &FunctionDebugContext, - bx: &Builder<'_, 'll, '_>, - scope: &'ll DIScope, - span: Span, -) { - let dbg_loc = if debug_context.source_locations_enabled { - debug!("set_source_location: {}", bx.sess().source_map().span_to_string(span)); - let loc = span_start(bx.cx(), span); - InternalDebugLocation::new(scope, loc.line, loc.col.to_usize()) - } else { - UnknownLocation - }; - set_debug_location(bx, dbg_loc); -} - -#[derive(Copy, Clone, PartialEq)] -pub enum InternalDebugLocation<'ll> { - KnownLocation { scope: &'ll DIScope, line: usize, col: usize }, - UnknownLocation, -} - -impl InternalDebugLocation<'ll> { - pub fn new(scope: &'ll DIScope, line: usize, col: usize) -> Self { - KnownLocation { scope, line, col } - } -} - -pub fn set_debug_location(bx: &Builder<'_, 'll, '_>, debug_location: InternalDebugLocation<'ll>) { - let metadata_node = match debug_location { - KnownLocation { scope, line, col } => { - // For MSVC, set the column number to zero. - // Otherwise, emit it. This mimics clang behaviour. - // See discussion in https://github.com/rust-lang/rust/issues/42921 - let col_used = if bx.sess().target.target.options.is_like_msvc { - UNKNOWN_COLUMN_NUMBER - } else { - col as c_uint - }; - debug!("setting debug location to {} {}", line, col); - - unsafe { - Some(llvm::LLVMRustDIBuilderCreateDebugLocation( - debug_context(bx.cx()).llcontext, - line as c_uint, - col_used, - scope, - None, - )) - } +impl CodegenCx<'ll, '_> { + pub fn create_debug_loc(&self, scope: &'ll DIScope, span: Span) -> &'ll Value { + let loc = span_start(self, span); + + // For MSVC, set the column number to zero. + // Otherwise, emit it. This mimics clang behaviour. + // See discussion in https://github.com/rust-lang/rust/issues/42921 + let col_used = if self.sess().target.target.options.is_like_msvc { + UNKNOWN_COLUMN_NUMBER + } else { + loc.col.to_usize() as c_uint + }; + + unsafe { + llvm::LLVMRustDIBuilderCreateDebugLocation( + debug_context(self).llcontext, + loc.line as c_uint, + col_used, + scope, + None, + ) } - UnknownLocation => { - debug!("clearing debug location "); - None - } - }; - - unsafe { - llvm::LLVMSetCurrentDebugLocation(bx.llbuilder, metadata_node); } } diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 8091a74854070..98a3e695fa079 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -6,18 +6,11 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(bool_to_option)] -#![feature(box_patterns)] -#![feature(box_syntax)] #![feature(const_cstr_unchecked)] #![feature(crate_visibility_modifier)] #![feature(extern_types)] #![feature(in_band_lifetimes)] -#![feature(libc)] #![feature(nll)] -#![feature(optin_builtin_traits)] -#![feature(concat_idents)] -#![feature(link_args)] -#![feature(static_nobundle)] #![feature(trusted_len)] #![recursion_limit = "256"] @@ -196,7 +189,7 @@ unsafe impl Sync for LlvmCodegenBackend {} impl LlvmCodegenBackend { pub fn new() -> Box { - box LlvmCodegenBackend(()) + Box::new(LlvmCodegenBackend(())) } } @@ -245,7 +238,7 @@ impl CodegenBackend for LlvmCodegenBackend { } fn metadata_loader(&self) -> Box { - box metadata::LlvmMetadataLoader + Box::new(metadata::LlvmMetadataLoader) } fn provide(&self, providers: &mut ty::query::Providers<'_>) { @@ -262,12 +255,12 @@ impl CodegenBackend for LlvmCodegenBackend { metadata: EncodedMetadata, need_metadata_module: bool, ) -> Box { - box rustc_codegen_ssa::base::codegen_crate( + Box::new(rustc_codegen_ssa::base::codegen_crate( LlvmCodegenBackend(()), tcx, metadata, need_metadata_module, - ) + )) } fn join_codegen( diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 3f37f86676c98..146b7d3d76c5e 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -909,9 +909,7 @@ extern "C" { pub fn LLVMDisposeBuilder(Builder: &'a mut Builder<'a>); // Metadata - pub fn LLVMSetCurrentDebugLocation(Builder: &Builder<'a>, L: Option<&'a Value>); - pub fn LLVMGetCurrentDebugLocation(Builder: &Builder<'a>) -> &'a Value; - pub fn LLVMSetInstDebugLocation(Builder: &Builder<'a>, Inst: &'a Value); + pub fn LLVMSetCurrentDebugLocation(Builder: &Builder<'a>, L: &'a Value); // Terminators pub fn LLVMBuildRetVoid(B: &Builder<'a>) -> &'a Value; diff --git a/src/librustc_codegen_llvm/metadata.rs b/src/librustc_codegen_llvm/metadata.rs index abe34bb148ce5..0f30c2c020de7 100644 --- a/src/librustc_codegen_llvm/metadata.rs +++ b/src/librustc_codegen_llvm/metadata.rs @@ -22,10 +22,11 @@ impl MetadataLoader for LlvmMetadataLoader { // Use ArchiveRO for speed here, it's backed by LLVM and uses mmap // internally to read the file. We also avoid even using a memcpy by // just keeping the archive along while the metadata is in use. - let archive = ArchiveRO::open(filename).map(|ar| OwningRef::new(box ar)).map_err(|e| { - debug!("llvm didn't like `{}`: {}", filename.display(), e); - format!("failed to read rlib metadata in '{}': {}", filename.display(), e) - })?; + let archive = + ArchiveRO::open(filename).map(|ar| OwningRef::new(Box::new(ar))).map_err(|e| { + debug!("llvm didn't like `{}`: {}", filename.display(), e); + format!("failed to read rlib metadata in '{}': {}", filename.display(), e) + })?; let buf: OwningRef<_, [u8]> = archive.try_map(|ar| { ar.iter() .filter_map(|s| s.ok()) @@ -44,9 +45,10 @@ impl MetadataLoader for LlvmMetadataLoader { let buf = path_to_c_string(filename); let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr()) .ok_or_else(|| format!("error reading library: '{}'", filename.display()))?; - let of = ObjectFile::new(mb).map(|of| OwningRef::new(box of)).ok_or_else(|| { - format!("provided path not an object file: '{}'", filename.display()) - })?; + let of = + ObjectFile::new(mb).map(|of| OwningRef::new(Box::new(of))).ok_or_else(|| { + format!("provided path not an object file: '{}'", filename.display()) + })?; let buf = of.try_map(|of| search_meta_section(of, target, filename))?; Ok(rustc_erase_owner!(buf)) } diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index f39587122c56d..a2bb39b9e4019 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -1,10 +1,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(bool_to_option)] #![feature(box_patterns)] -#![feature(box_syntax)] -#![feature(core_intrinsics)] -#![feature(libc)] -#![feature(stmt_expr_attributes)] #![feature(try_blocks)] #![feature(in_band_lifetimes)] #![feature(nll)] diff --git a/src/librustc_codegen_ssa/mir/debuginfo.rs b/src/librustc_codegen_ssa/mir/debuginfo.rs index f66496d10fb16..976a656a29b19 100644 --- a/src/librustc_codegen_ssa/mir/debuginfo.rs +++ b/src/librustc_codegen_ssa/mir/debuginfo.rs @@ -14,7 +14,6 @@ use super::{FunctionCx, LocalRef}; pub struct FunctionDebugContext { pub scopes: IndexVec>, - pub source_locations_enabled: bool, pub defining_crate: CrateNum, } @@ -53,11 +52,10 @@ impl DebugScope { } impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { - pub fn set_debug_loc(&mut self, bx: &mut Bx, source_info: mir::SourceInfo) { + pub fn set_debug_loc(&self, bx: &mut Bx, source_info: mir::SourceInfo) { let (scope, span) = self.debug_loc(source_info); - if let Some(debug_context) = &mut self.debug_context { - // FIXME(eddyb) get rid of this unwrap somehow. - bx.set_source_location(debug_context, scope.unwrap(), span); + if let Some(scope) = scope { + bx.set_source_location(scope, span); } } @@ -210,11 +208,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return; } - let debug_context = match &self.debug_context { - Some(debug_context) => debug_context, - None => return, - }; - // FIXME(eddyb) add debuginfo for unsized places too. let base = match local_ref { LocalRef::Place(place) => place, @@ -264,7 +257,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if let Some(scope) = scope { if let Some(dbg_var) = var.dbg_var { bx.dbg_var_addr( - debug_context, dbg_var, scope, base.llval, diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 8a6284479c722..64ead19b35869 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -230,13 +230,6 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx.br(fx.blocks[mir::START_BLOCK]); } - // Up until here, IR instructions for this function have explicitly not been annotated with - // source code location, so we don't step into call setup code. From here on, source location - // emitting should be enabled. - if let Some(debug_context) = &mut fx.debug_context { - debug_context.source_locations_enabled = true; - } - let rpo = traversal::reverse_postorder(&mir_body); let mut visited = BitSet::new_empty(mir_body.basic_blocks().len()); diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs index 22a4e96b9e4bf..3688ae51b3918 100644 --- a/src/librustc_codegen_ssa/traits/debuginfo.rs +++ b/src/librustc_codegen_ssa/traits/debuginfo.rs @@ -49,7 +49,6 @@ pub trait DebugInfoBuilderMethods: BackendTypes { // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). fn dbg_var_addr( &mut self, - dbg_context: &FunctionDebugContext, dbg_var: Self::DIVariable, scope_metadata: Self::DIScope, variable_alloca: Self::Value, @@ -58,12 +57,7 @@ pub trait DebugInfoBuilderMethods: BackendTypes { indirect_offsets: &[Size], span: Span, ); - fn set_source_location( - &mut self, - debug_context: &mut FunctionDebugContext, - scope: Self::DIScope, - span: Span, - ); + fn set_source_location(&mut self, scope: Self::DIScope, span: Span); fn insert_reference_to_gdb_debug_scripts_section_global(&mut self); fn set_var_name(&mut self, value: Self::Value, name: &str); } diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index 6b802bf530e86..38906bbaef810 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -3,10 +3,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![feature(arbitrary_self_types)] -#![feature(box_patterns)] -#![feature(box_syntax)] -#![feature(core_intrinsics)] #![feature(never_type)] #![feature(nll)] #![feature(in_band_lifetimes)] diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index aaac7fb4460cd..13792a0c890c4 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -12,7 +12,6 @@ #![feature(generators)] #![feature(generator_trait)] #![feature(fn_traits)] -#![feature(unsize)] #![feature(specialization)] #![feature(optin_builtin_traits)] #![feature(nll)] @@ -20,11 +19,9 @@ #![feature(hash_raw_entry)] #![feature(stmt_expr_attributes)] #![feature(core_intrinsics)] -#![feature(integer_atomics)] #![feature(test)] #![feature(associated_type_bounds)] #![feature(thread_id_value)] -#![cfg_attr(unix, feature(libc))] #![allow(rustc::default_hash_types)] #[macro_use] diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 019ff431bcb97..52c6399498534 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -5,12 +5,7 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![feature(box_syntax)] -#![cfg_attr(unix, feature(libc))] #![feature(nll)] -#![feature(set_stdio)] -#![feature(no_debug)] -#![feature(integer_atomics)] #![recursion_limit = "256"] pub extern crate getopts; diff --git a/src/librustc_error_codes/error_codes/E0277.md b/src/librustc_error_codes/error_codes/E0277.md index 2034a5b988cbf..2e2cd5e01fb6a 100644 --- a/src/librustc_error_codes/error_codes/E0277.md +++ b/src/librustc_error_codes/error_codes/E0277.md @@ -1,5 +1,7 @@ You tried to use a type which doesn't implement some trait in a place which -expected that trait. Erroneous code example: +expected that trait. + +Erroneous code example: ```compile_fail,E0277 // here we declare the Foo trait with a bar method diff --git a/src/librustc_error_codes/error_codes/E0282.md b/src/librustc_error_codes/error_codes/E0282.md index 54a9de0025a3d..49d2205f92c2a 100644 --- a/src/librustc_error_codes/error_codes/E0282.md +++ b/src/librustc_error_codes/error_codes/E0282.md @@ -1,3 +1,11 @@ +The compiler could not infer a type and asked for a type annotation. + +Erroneous code example: + +```compile_fail,E0282 +let x = "hello".chars().rev().collect(); +``` + This error indicates that type inference did not result in one unique possible type, and extra information is required. In most cases this can be provided by adding a type annotation. Sometimes you need to specify a generic type @@ -8,13 +16,9 @@ parameter with a `FromIterator` bound, which for a `char` iterator is implemented by `Vec` and `String` among others. Consider the following snippet that reverses the characters of a string: -```compile_fail,E0282 -let x = "hello".chars().rev().collect(); -``` - -In this case, the compiler cannot infer what the type of `x` should be: -`Vec` and `String` are both suitable candidates. To specify which type to -use, you can use a type annotation on `x`: +In the first code example, the compiler cannot infer what the type of `x` should +be: `Vec` and `String` are both suitable candidates. To specify which type +to use, you can use a type annotation on `x`: ``` let x: Vec = "hello".chars().rev().collect(); diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 97667febc3ca2..594e813def8a9 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -4,9 +4,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(crate_visibility_modifier)] -#![cfg_attr(unix, feature(libc))] #![feature(nll)] -#![feature(optin_builtin_traits)] pub use emitter::ColorConfig; diff --git a/src/librustc_hir/lib.rs b/src/librustc_hir/lib.rs index f54fa291bd6e8..e4edd34bd6e23 100644 --- a/src/librustc_hir/lib.rs +++ b/src/librustc_hir/lib.rs @@ -12,7 +12,7 @@ extern crate rustc_data_structures; pub mod def; -pub mod def_id; +pub use rustc_span::def_id; mod hir; pub mod hir_id; pub mod intravisit; diff --git a/src/librustc_hir/print.rs b/src/librustc_hir/print.rs index b0d2f96c71a03..071c3de4b1c2c 100644 --- a/src/librustc_hir/print.rs +++ b/src/librustc_hir/print.rs @@ -454,14 +454,17 @@ impl<'a> State<'a> { fn print_associated_type( &mut self, ident: ast::Ident, + generics: &hir::Generics<'_>, bounds: Option>, ty: Option<&hir::Ty<'_>>, ) { self.word_space("type"); self.print_ident(ident); + self.print_generic_params(&generics.params); if let Some(bounds) = bounds { self.print_bounds(":", bounds); } + self.print_where_clause(&generics.where_clause); if let Some(ty) = ty { self.s.space(); self.word_space("="); @@ -902,6 +905,7 @@ impl<'a> State<'a> { hir::TraitItemKind::Type(ref bounds, ref default) => { self.print_associated_type( ti.ident, + &ti.generics, Some(bounds), default.as_ref().map(|ty| &**ty), ); @@ -930,7 +934,7 @@ impl<'a> State<'a> { self.ann.nested(self, Nested::Body(body)); } hir::ImplItemKind::TyAlias(ref ty) => { - self.print_associated_type(ii.ident, None, Some(ty)); + self.print_associated_type(ii.ident, &ii.generics, None, Some(ty)); } hir::ImplItemKind::OpaqueTy(bounds) => { self.word_space("type"); diff --git a/src/librustc_hir/stable_hash_impls.rs b/src/librustc_hir/stable_hash_impls.rs index 294074cd3e5a4..e8407b537011b 100644 --- a/src/librustc_hir/stable_hash_impls.rs +++ b/src/librustc_hir/stable_hash_impls.rs @@ -1,6 +1,5 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use crate::def_id::DefId; use crate::hir::{BodyId, Expr, ImplItemId, ItemId, Mod, TraitItemId, Ty, VisibilityKind}; use crate::hir_id::HirId; @@ -8,7 +7,6 @@ use crate::hir_id::HirId; /// This is a hack to allow using the `HashStable_Generic` derive macro /// instead of implementing everything in librustc. pub trait HashStableContext: syntax::HashStableContext + rustc_target::HashStableContext { - fn hash_def_id(&mut self, _: DefId, hasher: &mut StableHasher); fn hash_hir_id(&mut self, _: HirId, hasher: &mut StableHasher); fn hash_body_id(&mut self, _: BodyId, hasher: &mut StableHasher); fn hash_reference_to_item(&mut self, _: HirId, hasher: &mut StableHasher); @@ -24,12 +22,6 @@ impl HashStable for HirId { } } -impl HashStable for DefId { - fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { - hcx.hash_def_id(*self, hasher) - } -} - impl HashStable for BodyId { fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { hcx.hash_body_id(*self, hasher) diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index 7ce4def2886b8..ca824fde7efc1 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -3,7 +3,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(in_band_lifetimes)] #![feature(nll)] -#![feature(specialization)] #![recursion_limit = "256"] #[macro_use] diff --git a/src/librustc_interface/lib.rs b/src/librustc_interface/lib.rs index e4e6849ab8e59..ba1e2216ca805 100644 --- a/src/librustc_interface/lib.rs +++ b/src/librustc_interface/lib.rs @@ -2,10 +2,8 @@ #![feature(box_syntax)] #![feature(set_stdio)] #![feature(nll)] -#![feature(arbitrary_self_types)] #![feature(generator_trait)] #![feature(generators)] -#![cfg_attr(unix, feature(libc))] #![recursion_limit = "256"] #[cfg(unix)] diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 78e9d0f14f2de..6e2db65c84005 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -28,7 +28,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![cfg_attr(test, feature(test))] #![feature(bool_to_option)] -#![feature(box_patterns)] #![feature(box_syntax)] #![feature(crate_visibility_modifier)] #![feature(never_type)] diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index d94f23ff8bc6a..d4cc3c32616ac 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -1,15 +1,11 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(bool_to_option)] -#![feature(box_patterns)] #![feature(core_intrinsics)] #![feature(crate_visibility_modifier)] #![feature(drain_filter)] #![feature(in_band_lifetimes)] -#![feature(libc)] #![feature(nll)] #![feature(proc_macro_internals)] -#![feature(proc_macro_quote)] -#![feature(rustc_private)] #![feature(specialization)] #![feature(stmt_expr_attributes)] #![recursion_limit = "256"] diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index f064869d66471..4f1b90e34cf00 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -6,21 +6,15 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(nll)] #![feature(in_band_lifetimes)] -#![feature(inner_deref)] #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(crate_visibility_modifier)] -#![feature(core_intrinsics)] -#![feature(decl_macro)] #![feature(drain_filter)] #![feature(exhaustive_patterns)] #![feature(iter_order_by)] #![feature(never_type)] #![feature(specialization)] -#![feature(try_trait)] -#![feature(unicode_internals)] -#![feature(slice_concat_ext)] #![feature(trusted_len)] #![feature(try_blocks)] #![feature(associated_type_bounds)] diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 94a5f2b3bf86d..a8c66be359c4a 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -68,6 +68,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx let fn_mut = tcx.lang_items().fn_mut_trait().unwrap(); let call_mut = tcx .associated_items(fn_mut) + .iter() .find(|it| it.kind == ty::AssocKind::Method) .unwrap() .def_id; diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 1be3da4b3d85a..091ae1bbb799d 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -539,7 +539,7 @@ where debug!("destructor_call_block({:?}, {:?})", self, succ); let tcx = self.tcx(); let drop_trait = tcx.lang_items().drop_trait().unwrap(); - let drop_fn = tcx.associated_items(drop_trait).next().unwrap(); + let drop_fn = tcx.associated_items(drop_trait)[0]; let ty = self.place_ty(self.place); let substs = tcx.mk_substs_trait(ty, &[]); diff --git a/src/librustc_passes/reachable.rs b/src/librustc_passes/reachable.rs index 667898046ac36..888f4370dd5e8 100644 --- a/src/librustc_passes/reachable.rs +++ b/src/librustc_passes/reachable.rs @@ -362,12 +362,12 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx return; } - let provided_trait_methods = self.tcx.provided_trait_methods(trait_def_id); - self.worklist.reserve(provided_trait_methods.len()); - for default_method in provided_trait_methods { - let hir_id = self.tcx.hir().as_local_hir_id(default_method.def_id).unwrap(); - self.worklist.push(hir_id); - } + // FIXME(#53488) remove `let` + let tcx = self.tcx; + self.worklist.extend( + tcx.provided_trait_methods(trait_def_id) + .map(|assoc| tcx.hir().as_local_hir_id(assoc.def_id).unwrap()), + ); } } } diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs index 4009cc6d725ab..12debfb66a431 100644 --- a/src/librustc_passes/stability.rs +++ b/src/librustc_passes/stability.rs @@ -468,6 +468,7 @@ impl Visitor<'tcx> for Checker<'tcx> { let trait_item_def_id = self .tcx .associated_items(trait_did) + .iter() .find(|item| item.ident.name == impl_item.ident.name) .map(|item| item.def_id); if let Some(def_id) = trait_item_def_id { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index af4ba4c0eb20e..2e63c3e170605 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -9,7 +9,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(bool_to_option)] #![feature(crate_visibility_modifier)] -#![feature(label_break_value)] #![feature(nll)] #![recursion_limit = "256"] diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index e32f47443667b..401e172275113 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -423,6 +423,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { qualname.push_str(&self.tcx.def_path_str(def_id)); self.tcx .associated_items(def_id) + .iter() .find(|item| item.ident.name == ident.name) .map(|item| decl_id = Some(item.def_id)); } @@ -717,6 +718,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { let ti = self.tcx.associated_item(decl_id); self.tcx .associated_items(ti.container.id()) + .iter() .find(|item| { item.ident.name == ti.ident.name && item.defaultness.has_value() }) diff --git a/src/librustc_hir/def_id.rs b/src/librustc_span/def_id.rs similarity index 95% rename from src/librustc_hir/def_id.rs rename to src/librustc_span/def_id.rs index 7ee778ddd8ec7..6cdfd0500ca84 100644 --- a/src/librustc_hir/def_id.rs +++ b/src/librustc_span/def_id.rs @@ -1,3 +1,5 @@ +use crate::HashStableContext; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::AtomicRef; use rustc_index::vec::Idx; use rustc_serialize::{Decoder, Encoder}; @@ -18,15 +20,6 @@ pub enum CrateNum { Index(CrateId), } -impl ::std::fmt::Debug for CrateNum { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - match self { - CrateNum::Index(id) => write!(fmt, "crate{}", id.private), - CrateNum::ReservedForIncrCompCache => write!(fmt, "crate for decoding incr comp cache"), - } - } -} - /// Item definitions in the currently-compiled crate would have the `CrateNum` /// `LOCAL_CRATE` in their `DefId`. pub const LOCAL_CRATE: CrateNum = CrateNum::Index(CrateId::from_u32_const(0)); @@ -100,6 +93,15 @@ impl rustc_serialize::UseSpecializedDecodable for CrateNum { } } +impl ::std::fmt::Debug for CrateNum { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + match self { + CrateNum::Index(id) => write!(fmt, "crate{}", id.private), + CrateNum::ReservedForIncrCompCache => write!(fmt, "crate for decoding incr comp cache"), + } + } +} + rustc_index::newtype_index! { /// A DefIndex is an index into the hir-map for a crate, identifying a /// particular definition. It should really be considered an interned @@ -207,3 +209,9 @@ impl fmt::Debug for LocalDefId { impl rustc_serialize::UseSpecializedEncodable for LocalDefId {} impl rustc_serialize::UseSpecializedDecodable for LocalDefId {} + +impl HashStable for DefId { + fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + hcx.hash_def_id(*self, hasher) + } +} diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs index 413bd77daae24..b7c6b0c4f690e 100644 --- a/src/librustc_span/lib.rs +++ b/src/librustc_span/lib.rs @@ -8,9 +8,6 @@ #![feature(crate_visibility_modifier)] #![feature(nll)] #![feature(optin_builtin_traits)] -#![feature(rustc_attrs)] -#![feature(specialization)] -#![feature(step_trait)] use rustc_data_structures::AtomicRef; use rustc_macros::HashStable_Generic; @@ -25,7 +22,8 @@ use edition::Edition; pub mod hygiene; use hygiene::Transparency; pub use hygiene::{DesugaringKind, ExpnData, ExpnId, ExpnKind, MacroKind, SyntaxContext}; - +pub mod def_id; +use def_id::DefId; mod span_encoding; pub use span_encoding::{Span, DUMMY_SP}; @@ -1561,6 +1559,7 @@ fn lookup_line(lines: &[BytePos], pos: BytePos) -> isize { /// instead of implementing everything in librustc. pub trait HashStableContext { fn hash_spans(&self) -> bool; + fn hash_def_id(&mut self, _: DefId, hasher: &mut StableHasher); fn byte_pos_to_line_and_col( &mut self, byte: BytePos, diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs index a9db0254a7d11..71150e74f70d4 100644 --- a/src/librustc_target/lib.rs +++ b/src/librustc_target/lib.rs @@ -8,7 +8,6 @@ //! LLVM. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![feature(box_syntax)] #![feature(bool_to_option)] #![feature(nll)] diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs index aa05165e3de32..b032acf82f582 100644 --- a/src/librustc_ty/ty.rs +++ b/src/librustc_ty/ty.rs @@ -206,12 +206,10 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] { } } -fn associated_items<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::AssocItemsIterator<'tcx> { - ty::AssocItemsIterator { - items: tcx.arena.alloc_from_iter( - tcx.associated_item_def_ids(def_id).iter().map(|did| tcx.associated_item(*did)), - ), - } +fn associated_items<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx [ty::AssocItem] { + tcx.arena.alloc_from_iter( + tcx.associated_item_def_ids(def_id).iter().map(|did| tcx.associated_item(*did)), + ) } fn def_span(tcx: TyCtxt<'_>, def_id: DefId) -> Span { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 6bd120d818d09..2909d0f8c54e7 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1109,7 +1109,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { trait_def_id: DefId, assoc_name: ast::Ident, ) -> bool { - self.tcx().associated_items(trait_def_id).any(|item| { + self.tcx().associated_items(trait_def_id).iter().any(|item| { item.kind == ty::AssocKind::Type && self.tcx().hygienic_eq(assoc_name, item.ident, trait_def_id) }) @@ -1347,6 +1347,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.adjust_ident_and_get_scope(binding.item_name, candidate.def_id(), hir_ref_id); let assoc_ty = tcx .associated_items(candidate.def_id()) + .iter() .find(|i| i.kind == ty::AssocKind::Type && i.ident.modern() == assoc_ident) .expect("missing associated type"); @@ -1512,6 +1513,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ty::Predicate::Trait(pred, _) => { associated_types.entry(span).or_default().extend( tcx.associated_items(pred.def_id()) + .iter() .filter(|item| item.kind == ty::AssocKind::Type) .map(|item| item.def_id), ); @@ -1969,6 +1971,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let bound_span = self .tcx() .associated_items(bound.def_id()) + .iter() .find(|item| { item.kind == ty::AssocKind::Type && self.tcx().hygienic_eq(assoc_name, item.ident, bound.def_id()) @@ -2198,6 +2201,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.adjust_ident_and_get_scope(assoc_ident, trait_did, hir_ref_id); let item = tcx .associated_items(trait_did) + .iter() .find(|i| Namespace::from(i.kind) == Namespace::Type && i.ident.modern() == assoc_ident) .expect("missing associated type"); diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 26777b3b01048..707125b3fd522 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -248,7 +248,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if is_gen { // Check that we deduce the signature from the `<_ as std::ops::Generator>::Return` // associated item and not yield. - let return_assoc_item = self.tcx.associated_items(gen_trait).nth(1).unwrap().def_id; + let return_assoc_item = self.tcx.associated_items(gen_trait)[1].def_id; if return_assoc_item != projection.projection_def_id() { debug!("deduce_sig_from_projection: not return assoc item of generator"); return None; @@ -673,7 +673,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // The `Future` trait has only one associted item, `Output`, // so check that this is what we see. - let output_assoc_item = self.tcx.associated_items(future_trait).nth(0).unwrap().def_id; + let output_assoc_item = self.tcx.associated_items(future_trait)[0].def_id; if output_assoc_item != predicate.projection_ty.item_def_id { span_bug!( cause_span, diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index e0f9fcc69325c..8c7f1330820e3 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -536,6 +536,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let item_def_id = self .tcx .associated_items(deref_trait) + .iter() .find(|item| item.kind == ty::AssocKind::Type) .unwrap() .def_id; diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index e90c2ef5e4361..67d8030a9d69b 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -474,8 +474,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_name: ast::Ident, ns: Namespace, ) -> Option { - self.tcx.associated_items(def_id).find(|item| { - Namespace::from(item.kind) == ns && self.tcx.hygienic_eq(item_name, item.ident, def_id) - }) + self.tcx + .associated_items(def_id) + .iter() + .find(|item| { + Namespace::from(item.kind) == ns + && self.tcx.hygienic_eq(item_name, item.ident, def_id) + }) + .copied() } } diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 2444fc60f77ba..497a401a031e5 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -1696,10 +1696,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let max_dist = max(name.as_str().len(), 3) / 3; self.tcx .associated_items(def_id) + .iter() .filter(|x| { let dist = lev_distance(&*name.as_str(), &x.ident.as_str()); Namespace::from(x.kind) == Namespace::Value && dist > 0 && dist <= max_dist }) + .copied() .collect() } else { self.fcx @@ -1707,7 +1709,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { .map_or(Vec::new(), |x| vec![x]) } } else { - self.tcx.associated_items(def_id).collect() + self.tcx.associated_items(def_id).to_vec() } } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 7e5d27d93b3cb..54a5330df399d 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1976,6 +1976,7 @@ fn check_impl_items_against_trait<'tcx>( let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id)); let ty_trait_item = tcx .associated_items(impl_trait_ref.def_id) + .iter() .find(|ac| { Namespace::from(&impl_item.kind) == Namespace::from(ac.kind) && tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id) @@ -1983,6 +1984,7 @@ fn check_impl_items_against_trait<'tcx>( .or_else(|| { // Not compatible, but needed for the error message tcx.associated_items(impl_trait_ref.def_id) + .iter() .find(|ac| tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id)) }); @@ -2096,7 +2098,7 @@ fn check_impl_items_against_trait<'tcx>( if !is_implemented && !traits::impl_is_default(tcx, impl_id) { if !trait_item.defaultness.has_value() { - missing_items.push(trait_item); + missing_items.push(*trait_item); } else if associated_type_overridden { invalidated_items.push(trait_item.ident); } @@ -5096,7 +5098,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Check for `Future` implementations by constructing a predicate to // prove: `::Output == U` let future_trait = self.tcx.lang_items().future_trait().unwrap(); - let item_def_id = self.tcx.associated_items(future_trait).next().unwrap().def_id; + let item_def_id = self.tcx.associated_items(future_trait)[0].def_id; let predicate = ty::Predicate::Projection(ty::Binder::bind(ty::ProjectionPredicate { // `::Output` diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs index 3e17b661cf4ce..fb9c173f52000 100644 --- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs +++ b/src/librustc_typeck/coherence/inherent_impls_overlap.rs @@ -1,6 +1,6 @@ use crate::namespace::Namespace; use rustc::traits::{self, IntercrateMode, SkipLeakCheck}; -use rustc::ty::TyCtxt; +use rustc::ty::{AssocItem, TyCtxt}; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; @@ -17,38 +17,60 @@ struct InherentOverlapChecker<'tcx> { } impl InherentOverlapChecker<'tcx> { + /// Checks whether any associated items in impls 1 and 2 share the same identifier and + /// namespace. + fn impls_have_common_items(&self, impl1: DefId, impl2: DefId) -> bool { + let impl_items1 = self.tcx.associated_items(impl1); + let impl_items2 = self.tcx.associated_items(impl2); + + for item1 in &impl_items1[..] { + for item2 in &impl_items2[..] { + // Avoid costly `.modern()` calls as much as possible by doing them as late as we + // can. Compare raw symbols first. + if item1.ident.name == item2.ident.name + && Namespace::from(item1.kind) == Namespace::from(item2.kind) + { + // Symbols and namespace match, compare hygienically. + if item1.ident.modern() == item2.ident.modern() { + return true; + } + } + } + } + + false + } + fn check_for_common_items_in_impls( &self, impl1: DefId, impl2: DefId, overlap: traits::OverlapResult<'_>, ) { - let name_and_namespace = |def_id| { - let item = self.tcx.associated_item(def_id); - (item.ident.modern(), Namespace::from(item.kind)) - }; + let name_and_namespace = + |assoc: &AssocItem| (assoc.ident.modern(), Namespace::from(assoc.kind)); - let impl_items1 = self.tcx.associated_item_def_ids(impl1); - let impl_items2 = self.tcx.associated_item_def_ids(impl2); + let impl_items1 = self.tcx.associated_items(impl1); + let impl_items2 = self.tcx.associated_items(impl2); - for &item1 in &impl_items1[..] { + for item1 in &impl_items1[..] { let (name, namespace) = name_and_namespace(item1); - for &item2 in &impl_items2[..] { + for item2 in &impl_items2[..] { if (name, namespace) == name_and_namespace(item2) { let mut err = struct_span_err!( self.tcx.sess, - self.tcx.span_of_impl(item1).unwrap(), + self.tcx.span_of_impl(item1.def_id).unwrap(), E0592, "duplicate definitions with name `{}`", name ); err.span_label( - self.tcx.span_of_impl(item1).unwrap(), + self.tcx.span_of_impl(item1.def_id).unwrap(), format!("duplicate definitions for `{}`", name), ); err.span_label( - self.tcx.span_of_impl(item2).unwrap(), + self.tcx.span_of_impl(item2.def_id).unwrap(), format!("other definition for `{}`", name), ); @@ -66,27 +88,21 @@ impl InherentOverlapChecker<'tcx> { } } - fn check_for_overlapping_inherent_impls(&self, ty_def_id: DefId) { - let impls = self.tcx.inherent_impls(ty_def_id); - - for (i, &impl1_def_id) in impls.iter().enumerate() { - for &impl2_def_id in &impls[(i + 1)..] { - traits::overlapping_impls( - self.tcx, - impl1_def_id, - impl2_def_id, - IntercrateMode::Issue43355, - // We go ahead and just skip the leak check for - // inherent impls without warning. - SkipLeakCheck::Yes, - |overlap| { - self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap); - false - }, - || true, - ); - } - } + fn check_for_overlapping_inherent_impls(&self, impl1_def_id: DefId, impl2_def_id: DefId) { + traits::overlapping_impls( + self.tcx, + impl1_def_id, + impl2_def_id, + IntercrateMode::Issue43355, + // We go ahead and just skip the leak check for + // inherent impls without warning. + SkipLeakCheck::Yes, + |overlap| { + self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap); + false + }, + || true, + ); } } @@ -97,8 +113,16 @@ impl ItemLikeVisitor<'v> for InherentOverlapChecker<'tcx> { | hir::ItemKind::Struct(..) | hir::ItemKind::Trait(..) | hir::ItemKind::Union(..) => { - let type_def_id = self.tcx.hir().local_def_id(item.hir_id); - self.check_for_overlapping_inherent_impls(type_def_id); + let ty_def_id = self.tcx.hir().local_def_id(item.hir_id); + let impls = self.tcx.inherent_impls(ty_def_id); + + for (i, &impl1_def_id) in impls.iter().enumerate() { + for &impl2_def_id in &impls[(i + 1)..] { + if self.impls_have_common_items(impl1_def_id, impl2_def_id) { + self.check_for_overlapping_inherent_impls(impl1_def_id, impl2_def_id); + } + } + } } _ => {} } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 05ea9b1ac56dc..474868f0dd6c4 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -58,10 +58,8 @@ This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![allow(non_camel_case_types)] #![feature(bool_to_option)] -#![feature(box_patterns)] #![feature(box_syntax)] #![feature(crate_visibility_modifier)] -#![feature(exhaustive_patterns)] #![feature(in_band_lifetimes)] #![feature(nll)] #![feature(try_blocks)] diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 18ebd254507ea..288446b6219ce 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -87,7 +87,6 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { .cx .tcx .provided_trait_methods(trait_def_id) - .into_iter() .map(|meth| meth.ident.to_string()) .collect(); @@ -115,6 +114,8 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { .cx .tcx .associated_items(impl_def_id) + .iter() + .copied() .collect::>() .clean(self.cx), polarity: None, diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index df72bf0b56e61..90ce8802f6584 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -191,7 +191,7 @@ pub fn record_extern_fqn(cx: &DocContext<'_>, did: DefId, kind: clean::TypeKind) pub fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait { let auto_trait = cx.tcx.trait_def(did).has_auto_impl; - let trait_items = cx.tcx.associated_items(did).map(|item| item.clean(cx)).collect(); + let trait_items = cx.tcx.associated_items(did).iter().map(|item| item.clean(cx)).collect(); let predicates = cx.tcx.predicates_of(did); let generics = (cx.tcx.generics_of(did), predicates).clean(cx); let generics = filter_non_trait_generics(did, generics); @@ -376,6 +376,7 @@ pub fn build_impl( } else { ( tcx.associated_items(did) + .iter() .filter_map(|item| { if associated_trait.is_some() || item.vis == ty::Visibility::Public { Some(item.clean(cx)) @@ -401,9 +402,7 @@ pub fn build_impl( let provided = trait_ .def_id() - .map(|did| { - tcx.provided_trait_methods(did).into_iter().map(|meth| meth.ident.to_string()).collect() - }) + .map(|did| tcx.provided_trait_methods(did).map(|meth| meth.ident.to_string()).collect()) .unwrap_or_default(); debug!("build_impl: impl {:?} for {:?}", trait_.def_id(), for_.def_id()); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f140f11b09098..87edc88611f3a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2108,11 +2108,7 @@ impl Clean> for doctree::Impl<'_> { let provided: FxHashSet = trait_ .def_id() .map(|did| { - cx.tcx - .provided_trait_methods(did) - .into_iter() - .map(|meth| meth.ident.to_string()) - .collect() + cx.tcx.provided_trait_methods(did).map(|meth| meth.ident.to_string()).collect() }) .unwrap_or_default(); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index ed3f0f94e0ed8..4e0a2d9427431 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -3,19 +3,15 @@ html_playground_url = "https://play.rust-lang.org/" )] #![feature(rustc_private)] -#![feature(arbitrary_self_types)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(in_band_lifetimes)] #![feature(nll)] -#![feature(set_stdio)] #![feature(test)] #![feature(vec_remove_item)] #![feature(ptr_offset_from)] #![feature(crate_visibility_modifier)] -#![feature(drain_filter)] #![feature(never_type)] -#![feature(unicode_internals)] #![recursion_limit = "256"] extern crate env_logger; diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 332d19fbfaeca..9ecf6d531299f 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -206,6 +206,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { return cx .tcx .associated_items(did) + .iter() .find(|item| item.ident.name == item_name) .and_then(|item| match item.kind { ty::AssocKind::Method => Some("method"), diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 280fb078f7de4..b990e71bef0dd 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -10,7 +10,6 @@ Core encoding and decoding interfaces. test(attr(allow(unused_variables), deny(warnings))) )] #![feature(box_syntax)] -#![feature(core_intrinsics)] #![feature(specialization)] #![feature(never_type)] #![feature(nll)] diff --git a/src/test/pretty/gat-bounds.pp b/src/test/pretty/gat-bounds.pp new file mode 100644 index 0000000000000..0c95add490110 --- /dev/null +++ b/src/test/pretty/gat-bounds.pp @@ -0,0 +1,25 @@ +// Check that associated types print generic parameters and where clauses. +// See issue #67509. + +// pretty-compare-only +// pp-exact:gat-bounds.pp + +#![feature(generic_associated_types)] + +trait X { + type + Y: Trait + where + Self: Sized; +} + +impl X for () { + type + Y + where + Self: Sized + = + u32; +} + +fn main() { } diff --git a/src/test/pretty/gat-bounds.rs b/src/test/pretty/gat-bounds.rs new file mode 100644 index 0000000000000..1275f432a3c50 --- /dev/null +++ b/src/test/pretty/gat-bounds.rs @@ -0,0 +1,17 @@ +// Check that associated types print generic parameters and where clauses. +// See issue #67509. + +// pretty-compare-only +// pp-exact:gat-bounds.pp + +#![feature(generic_associated_types)] + +trait X { + type Y: Trait where Self: Sized; +} + +impl X for () { + type Y where Self: Sized = u32; +} + +fn main() { } diff --git a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr index a316d8f1698ac..3eb8e0ec18288 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr @@ -10,7 +10,7 @@ error: internal compiler error: mutable allocation in constant LL | const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:357:17 +thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:355:17 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic