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};
})
}
- 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);
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()
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,
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 {
// 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,
);
};
// `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 = {
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);
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> {