]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/hir/lowering.rs
Ignore desugarings when comparing duplicate trait error messages
[rust.git] / src / librustc / hir / lowering.rs
index 8584b534ff240b4c5cb18781653f66197b04318c..bf421da61e4437ce8868e47e53a6bbdf5c71a421 100644 (file)
@@ -67,6 +67,7 @@
 use syntax::ast::*;
 use syntax::errors;
 use syntax::ext::hygiene::{Mark, SyntaxContext};
+use syntax::feature_gate::{emit_feature_err, GateIssue};
 use syntax::print::pprust;
 use syntax::ptr::P;
 use syntax::source_map::{self, respan, CompilerDesugaringKind, Spanned};
@@ -596,7 +597,7 @@ fn expect_full_def(&mut self, id: NodeId) -> Def {
         })
     }
 
-    fn expect_full_def_from_use(&mut self, id: NodeId) -> impl Iterator<Item=Def> {
+    fn expect_full_def_from_use(&mut self, id: NodeId) -> impl Iterator<Item = Def> {
         self.resolver.get_import(id).present_items().map(|pr| {
             if pr.unresolved_segments() != 0 {
                 bug!("path not fully resolved: {:?}", pr);
@@ -989,7 +990,7 @@ fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hi
             None => {
                 self.loop_scopes
                     .last()
-                    .map(|innermost_loop_id| *innermost_loop_id)
+                    .cloned()
                     .map(|id| Ok(self.lower_node_id(id).node_id))
                     .unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
                     .into()
@@ -1054,7 +1055,10 @@ fn lower_arm(&mut self, arm: &Arm) -> hir::Arm {
         hir::Arm {
             attrs: self.lower_attrs(&arm.attrs),
             pats: arm.pats.iter().map(|x| self.lower_pat(x)).collect(),
-            guard: arm.guard.as_ref().map(|ref x| P(self.lower_expr(x))),
+            guard: match arm.guard {
+                Some(Guard::If(ref x)) => Some(hir::Guard::If(P(self.lower_expr(x)))),
+                _ => None,
+            },
             body: P(self.lower_expr(&arm.body)),
         }
     }
@@ -3426,19 +3430,24 @@ fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
                     ParamMode::Optional,
                     ImplTraitContext::Disallowed,
                 );
+                self.check_self_struct_ctor_feature(&qpath);
                 hir::PatKind::TupleStruct(
                     qpath,
                     pats.iter().map(|x| self.lower_pat(x)).collect(),
                     ddpos,
                 )
             }
-            PatKind::Path(ref qself, ref path) => hir::PatKind::Path(self.lower_qpath(
-                p.id,
-                qself,
-                path,
-                ParamMode::Optional,
-                ImplTraitContext::Disallowed,
-            )),
+            PatKind::Path(ref qself, ref path) => {
+                let qpath = self.lower_qpath(
+                    p.id,
+                    qself,
+                    path,
+                    ParamMode::Optional,
+                    ImplTraitContext::Disallowed,
+                );
+                self.check_self_struct_ctor_feature(&qpath);
+                hir::PatKind::Path(qpath)
+            }
             PatKind::Struct(ref path, ref fields, etc) => {
                 let qpath = self.lower_qpath(
                     p.id,
@@ -3825,13 +3834,17 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     attrs: e.attrs.clone(),
                 };
             }
-            ExprKind::Path(ref qself, ref path) => hir::ExprKind::Path(self.lower_qpath(
-                e.id,
-                qself,
-                path,
-                ParamMode::Optional,
-                ImplTraitContext::Disallowed,
-            )),
+            ExprKind::Path(ref qself, ref path) => {
+                let qpath = self.lower_qpath(
+                    e.id,
+                    qself,
+                    path,
+                    ParamMode::Optional,
+                    ImplTraitContext::Disallowed,
+                );
+                self.check_self_struct_ctor_feature(&qpath);
+                hir::ExprKind::Path(qpath)
+            }
             ExprKind::Break(opt_label, ref opt_expr) => {
                 let destination = if self.is_in_loop_condition && opt_label.is_none() {
                     hir::Destination {
@@ -4045,16 +4058,16 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 // expand <head>
                 let head = self.lower_expr(head);
                 let head_sp = head.span;
+                let desugared_span = self.allow_internal_unstable(
+                    CompilerDesugaringKind::ForLoop,
+                    head_sp,
+                );
 
                 let iter = self.str_to_ident("iter");
 
                 let next_ident = self.str_to_ident("__next");
-                let next_sp = self.allow_internal_unstable(
-                    CompilerDesugaringKind::ForLoop,
-                    head_sp,
-                );
                 let next_pat = self.pat_ident_binding_mode(
-                    next_sp,
+                    desugared_span,
                     next_ident,
                     hir::BindingAnnotation::Mutable,
                 );
@@ -4083,8 +4096,11 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 };
 
                 // `mut iter`
-                let iter_pat =
-                    self.pat_ident_binding_mode(head_sp, iter, hir::BindingAnnotation::Mutable);
+                let iter_pat = self.pat_ident_binding_mode(
+                    desugared_span,
+                    iter,
+                    hir::BindingAnnotation::Mutable
+                );
 
                 // `match ::std::iter::Iterator::next(&mut iter) { ... }`
                 let match_expr = {
@@ -4113,8 +4129,12 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat.id));
 
                 // `let mut __next`
-                let next_let =
-                    self.stmt_let_pat(head_sp, None, next_pat, hir::LocalSource::ForLoopDesugar);
+                let next_let = self.stmt_let_pat(
+                    desugared_span,
+                    None,
+                    next_pat,
+                    hir::LocalSource::ForLoopDesugar,
+                );
 
                 // `let <pat> = __next`
                 let pat = self.lower_pat(pat);
@@ -4812,6 +4832,18 @@ fn wrap_in_try_constructor(
                                             ThinVec::new()));
         P(self.expr_call(e.span, from_err, hir_vec![e]))
     }
+
+    fn check_self_struct_ctor_feature(&self, qp: &hir::QPath) {
+        if let hir::QPath::Resolved(_, ref p) = qp {
+            if p.segments.len() == 1 &&
+               p.segments[0].ident.name == keywords::SelfType.name() &&
+               !self.sess.features_untracked().self_struct_ctor {
+                emit_feature_err(&self.sess.parse_sess, "self_struct_ctor",
+                                 p.span, GateIssue::Language,
+                                 "`Self` struct constructors are unstable");
+            }
+        }
+    }
 }
 
 fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body>) -> Vec<hir::BodyId> {