about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs7
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_feature/src/active.rs2
-rw-r--r--compiler/rustc_middle/src/lib.rs2
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs36
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs1
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs33
-rw-r--r--compiler/rustc_span/src/lib.rs4
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs44
10 files changed, 95 insertions, 37 deletions
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 0017a28cf1b..0b033e9384c 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -461,7 +461,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                     if let PatKind::Range(Some(_), None, Spanned { .. }) = inner_pat.kind {
                         gate_feature_post!(
                             &self,
-                            half_open_range_patterns,
+                            half_open_range_patterns_in_slices,
                             pat.span,
                             "`X..` patterns in slices are experimental"
                         );
@@ -589,7 +589,10 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
     gate_all!(generators, "yield syntax is experimental");
     gate_all!(raw_ref_op, "raw address of syntax is experimental");
     gate_all!(const_trait_impl, "const trait impls are experimental");
-    gate_all!(half_open_range_patterns, "half-open range patterns are unstable");
+    gate_all!(
+        half_open_range_patterns_in_slices,
+        "half-open range patterns in slices are unstable"
+    );
     gate_all!(inline_const, "inline-const is experimental");
     gate_all!(inline_const_pat, "inline-const in pattern position is experimental");
     gate_all!(associated_const_equality, "associated const equality is incomplete");
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index 8efb7ccc1c7..ca12659695f 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -169,6 +169,8 @@ declare_features! (
     (accepted, global_allocator, "1.28.0", Some(27389), None),
     // FIXME: explain `globs`.
     (accepted, globs, "1.0.0", None, None),
+    /// Allows using `..=X` as a pattern.
+    (accepted, half_open_range_patterns, "CURRENT_RUSTC_VERSION", Some(67264), None),
     /// Allows using the `u128` and `i128` types.
     (accepted, i128_type, "1.26.0", Some(35118), None),
     /// Allows the use of `if let` expressions.
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 71ad54291b2..48c40eae662 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -414,6 +414,8 @@ declare_features! (
     (incomplete, generic_const_exprs, "1.56.0", Some(76560), None),
     /// Allows using `..X`, `..=X`, `...X`, and `X..` as a pattern.
     (active, half_open_range_patterns, "1.41.0", Some(67264), None),
+    /// Allows using `..=X` as a patterns in slices.
+    (active, half_open_range_patterns_in_slices, "CURRENT_RUSTC_VERSION", Some(67264), None),
     /// Allows `if let` guard in match arms.
     (active, if_let_guard, "1.47.0", Some(51114), None),
     /// Allows using imported `main` function
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index a180706e1cf..8d9a0388e21 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -44,7 +44,7 @@
 #![feature(type_alias_impl_trait)]
 #![feature(associated_type_bounds)]
 #![feature(rustc_attrs)]
-#![feature(half_open_range_patterns)]
+#![cfg_attr(bootstrap, feature(half_open_range_patterns))]
 #![feature(control_flow_enum)]
 #![feature(associated_type_defaults)]
 #![feature(trusted_step)]
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index 4d0a8b05eb0..fa75670b2ed 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -1,7 +1,9 @@
 use super::{ForceCollect, Parser, TrailingToken};
 
 use rustc_ast::token;
-use rustc_ast::{self as ast, AttrVec, GenericBounds, GenericParam, GenericParamKind, WhereClause};
+use rustc_ast::{
+    self as ast, AttrVec, GenericBounds, GenericParam, GenericParamKind, TyKind, WhereClause,
+};
 use rustc_errors::{Applicability, PResult};
 use rustc_span::symbol::kw;
 
@@ -31,13 +33,43 @@ impl<'a> Parser<'a> {
         let mut colon_span = None;
         let bounds = if self.eat(&token::Colon) {
             colon_span = Some(self.prev_token.span);
+            // recover from `impl Trait` in type param bound
+            if self.token.is_keyword(kw::Impl) {
+                let impl_span = self.token.span;
+                let snapshot = self.create_snapshot_for_diagnostic();
+                match self.parse_ty() {
+                    Ok(p) => {
+                        if let TyKind::ImplTrait(_, bounds) = &(*p).kind {
+                            let span = impl_span.to(self.token.span.shrink_to_lo());
+                            let mut err = self.struct_span_err(
+                                span,
+                                "expected trait bound, found `impl Trait` type",
+                            );
+                            err.span_label(span, "not a trait");
+                            if let [bound, ..] = &bounds[..] {
+                                err.span_suggestion_verbose(
+                                    impl_span.until(bound.span()),
+                                    "use the trait bounds directly",
+                                    String::new(),
+                                    Applicability::MachineApplicable,
+                                );
+                            }
+                            err.emit();
+                            return Err(err);
+                        }
+                    }
+                    Err(err) => {
+                        err.cancel();
+                    }
+                }
+                self.restore_snapshot(snapshot);
+            }
             self.parse_generic_bounds(colon_span)?
         } else {
             Vec::new()
         };
 
         let default = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
-
         Ok(GenericParam {
             ident,
             id: ast::DUMMY_NODE_ID,
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 0250b518243..56efec422d6 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -777,7 +777,6 @@ impl<'a> Parser<'a> {
     /// expression syntax `...expr` for splatting in expressions.
     fn parse_pat_range_to(&mut self, mut re: Spanned<RangeEnd>) -> PResult<'a, PatKind> {
         let end = self.parse_pat_range_end()?;
-        self.sess.gated_spans.gate(sym::half_open_range_patterns, re.span.to(self.prev_token.span));
         if let RangeEnd::Included(ref mut syn @ RangeSyntax::DotDotDot) = &mut re.node {
             *syn = RangeSyntax::DotDotEq;
             self.struct_span_err(re.span, "range-to patterns with `...` are not allowed")
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index 8fa6160d436..c18d5d06d64 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -1333,12 +1333,41 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                         && let hir::IsAsync::NotAsync = self.tcx.asyncness(lifetime_ref.hir_id.owner.def_id)
                         && !self.tcx.features().anonymous_lifetime_in_impl_trait
                     {
-                        rustc_session::parse::feature_err(
+                        let mut diag =  rustc_session::parse::feature_err(
                             &self.tcx.sess.parse_sess,
                             sym::anonymous_lifetime_in_impl_trait,
                             lifetime_ref.span,
                             "anonymous lifetimes in `impl Trait` are unstable",
-                        ).emit();
+                        );
+
+                        match self.tcx.hir().get_generics(lifetime_ref.hir_id.owner.def_id) {
+                            Some(generics) => {
+
+                                let new_param_sugg_tuple;
+
+                                new_param_sugg_tuple = match generics.span_for_param_suggestion() {
+                                    Some(_) => {
+                                        Some((self.tcx.sess.source_map().span_through_char(generics.span, '<').shrink_to_hi(), "'a, ".to_owned()))
+                                    },
+                                    None => Some((generics.span, "<'a>".to_owned()))
+                                };
+
+                                let mut multi_sugg_vec = vec![(lifetime_ref.span.shrink_to_hi(), "'a ".to_owned())];
+
+                                if let Some(new_tuple) =  new_param_sugg_tuple{
+                                    multi_sugg_vec.push(new_tuple);
+                                }
+
+                                diag.span_label(lifetime_ref.span, "expected named lifetime parameter");
+                                diag.multipart_suggestion("consider introducing a named lifetime parameter",
+                                multi_sugg_vec,
+                                rustc_errors::Applicability::MaybeIncorrect);
+
+                            },
+                            None => { }
+                        }
+
+                        diag.emit();
                         return;
                     }
                     scope = s;
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index f8df4169715..91eef647713 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -298,7 +298,11 @@ impl From<PathBuf> for FileName {
 
 #[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
 pub enum FileNameDisplayPreference {
+    /// Display the path after the application of rewrite rules provided via `--remap-path-prefix`.
+    /// This is appropriate for paths that get embedded into files produced by the compiler.
     Remapped,
+    /// Display the path before the application of rewrite rules provided via `--remap-path-prefix`.
+    /// This is appropriate for use in user-facing output (such as diagnostics).
     Local,
 }
 
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 8cb7d147d02..fe4fd33bdba 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -785,6 +785,7 @@ symbols! {
         globs,
         gt,
         half_open_range_patterns,
+        half_open_range_patterns_in_slices,
         hash,
         hexagon_target_feature,
         hidden,
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 52ee5e6ea93..1afa04007b8 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -8,7 +8,7 @@
 //!   - not reference the erased type `Self` except for in this receiver;
 //!   - not have generic type parameters.
 
-use super::elaborate_predicates;
+use super::{elaborate_predicates, elaborate_trait_ref};
 
 use crate::infer::TyCtxtInferExt;
 use crate::traits::query::evaluate_obligation::InferCtxtExt;
@@ -567,51 +567,37 @@ fn receiver_for_self_ty<'tcx>(
 /// Creates the object type for the current trait. For example,
 /// if the current trait is `Deref`, then this will be
 /// `dyn Deref<Target = Self::Target> + 'static`.
+#[instrument(level = "trace", skip(tcx), ret)]
 fn object_ty_for_trait<'tcx>(
     tcx: TyCtxt<'tcx>,
     trait_def_id: DefId,
     lifetime: ty::Region<'tcx>,
 ) -> Ty<'tcx> {
-    debug!("object_ty_for_trait: trait_def_id={:?}", trait_def_id);
-
     let trait_ref = ty::TraitRef::identity(tcx, trait_def_id);
+    debug!(?trait_ref);
 
     let trait_predicate = trait_ref.map_bound(|trait_ref| {
         ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref))
     });
+    debug!(?trait_predicate);
 
-    let mut associated_types = traits::supertraits(tcx, trait_ref)
-        .flat_map(|super_trait_ref| {
-            tcx.associated_items(super_trait_ref.def_id())
-                .in_definition_order()
-                .map(move |item| (super_trait_ref, item))
-        })
-        .filter(|(_, item)| item.kind == ty::AssocKind::Type)
-        .collect::<Vec<_>>();
-
-    // existential predicates need to be in a specific order
-    associated_types.sort_by_cached_key(|(_, item)| tcx.def_path_hash(item.def_id));
-
-    let projection_predicates = associated_types.into_iter().map(|(super_trait_ref, item)| {
-        // We *can* get bound lifetimes here in cases like
-        // `trait MyTrait: for<'s> OtherTrait<&'s T, Output=bool>`.
-        super_trait_ref.map_bound(|super_trait_ref| {
+    let elaborated_predicates = elaborate_trait_ref(tcx, trait_ref).filter_map(|obligation| {
+        debug!(?obligation);
+        let pred = obligation.predicate.to_opt_poly_projection_pred()?;
+        Some(pred.map_bound(|p| {
             ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
-                term: tcx.mk_projection(item.def_id, super_trait_ref.substs).into(),
-                item_def_id: item.def_id,
-                substs: super_trait_ref.substs,
+                item_def_id: p.projection_ty.item_def_id,
+                substs: p.projection_ty.substs,
+                term: p.term,
             })
-        })
+        }))
     });
 
     let existential_predicates = tcx
-        .mk_poly_existential_predicates(iter::once(trait_predicate).chain(projection_predicates));
-
-    let object_ty = tcx.mk_dynamic(existential_predicates, lifetime, ty::Dyn);
-
-    debug!("object_ty_for_trait: object_ty=`{}`", object_ty);
+        .mk_poly_existential_predicates(iter::once(trait_predicate).chain(elaborated_predicates));
+    debug!(?existential_predicates);
 
-    object_ty
+    tcx.mk_dynamic(existential_predicates, lifetime, ty::Dyn)
 }
 
 /// Checks the method's receiver (the `self` argument) can be dispatched on when `Self` is a