diff options
| author | bors <bors@rust-lang.org> | 2019-08-15 00:32:05 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-08-15 00:32:05 +0000 |
| commit | 9e9a136fcec5eb78f09a14dfd072a51ae2550269 (patch) | |
| tree | b193fe082d78583740df368de6f546ca35890cbb /src/librustc | |
| parent | 082cf2f9d136166cd1d552d3fb5abb1c46c99a14 (diff) | |
| parent | 78cd9d1fd5cd59fbab62325b1bcb4bb21c2cb30a (diff) | |
| download | rust-9e9a136fcec5eb78f09a14dfd072a51ae2550269.tar.gz rust-9e9a136fcec5eb78f09a14dfd072a51ae2550269.zip | |
Auto merge of #63575 - Centril:rollup-anlv9g5, r=Centril
Rollup of 11 pull requests Successful merges: - #62984 (Add lint for excess trailing semicolons) - #63075 (Miri: Check that a ptr is aligned and inbounds already when evaluating `*`) - #63490 (libsyntax: cleanup and refactor `pat.rs`) - #63507 (When needing type annotations in local bindings, account for impl Trait and closures) - #63509 (Point at the right enclosing scope when using `await` in non-async fn) - #63528 (syntax: Remove `DummyResult::expr_only`) - #63537 (expand: Unimplement `MutVisitor` on `MacroExpander`) - #63542 (Add NodeId for Arm, Field and FieldPat) - #63543 (Merge Variant and Variant_) - #63560 (move test that shouldn't be in test/run-pass/) - #63570 (Adjust tracking issues for `MaybeUninit<T>` gates) Failed merges: r? @ghost
Diffstat (limited to 'src/librustc')
| -rw-r--r-- | src/librustc/hir/check_attr.rs | 2 | ||||
| -rw-r--r-- | src/librustc/hir/intravisit.rs | 12 | ||||
| -rw-r--r-- | src/librustc/hir/lowering/expr.rs | 5 | ||||
| -rw-r--r-- | src/librustc/hir/lowering/item.rs | 14 | ||||
| -rw-r--r-- | src/librustc/hir/map/collector.rs | 8 | ||||
| -rw-r--r-- | src/librustc/hir/map/def_collector.rs | 6 | ||||
| -rw-r--r-- | src/librustc/hir/map/mod.rs | 42 | ||||
| -rw-r--r-- | src/librustc/hir/mod.rs | 8 | ||||
| -rw-r--r-- | src/librustc/hir/print.rs | 6 | ||||
| -rw-r--r-- | src/librustc/ich/impls_hir.rs | 2 | ||||
| -rw-r--r-- | src/librustc/infer/error_reporting/need_type_info.rs | 212 | ||||
| -rw-r--r-- | src/librustc/lint/context.rs | 4 | ||||
| -rw-r--r-- | src/librustc/lint/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/dead.rs | 12 | ||||
| -rw-r--r-- | src/librustc/middle/stability.rs | 8 | ||||
| -rw-r--r-- | src/librustc/mir/interpret/pointer.rs | 5 | ||||
| -rw-r--r-- | src/librustc/ty/sty.rs | 3 |
17 files changed, 245 insertions, 106 deletions
diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 22124d4ee41..eae956c978a 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -336,7 +336,7 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> { fn is_c_like_enum(item: &hir::Item) -> bool { if let hir::ItemKind::Enum(ref def, _) = item.node { for variant in &def.variants { - match variant.node.data { + match variant.data { hir::VariantData::Unit(..) => { /* continue */ } _ => { return false; } } diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index b5c760bc9a0..71d7464540a 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -577,15 +577,15 @@ pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V, variant: &'v Variant, generics: &'v Generics, parent_item_id: HirId) { - visitor.visit_ident(variant.node.ident); - visitor.visit_id(variant.node.id); - visitor.visit_variant_data(&variant.node.data, - variant.node.ident.name, + visitor.visit_ident(variant.ident); + visitor.visit_id(variant.id); + visitor.visit_variant_data(&variant.data, + variant.ident.name, generics, parent_item_id, variant.span); - walk_list!(visitor, visit_anon_const, &variant.node.disr_expr); - walk_list!(visitor, visit_attribute, &variant.node.attrs); + walk_list!(visitor, visit_anon_const, &variant.disr_expr); + walk_list!(visitor, visit_attribute, &variant.attrs); } pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs index d273006fbe0..e3a5400942d 100644 --- a/src/librustc/hir/lowering/expr.rs +++ b/src/librustc/hir/lowering/expr.rs @@ -677,6 +677,7 @@ impl LoweringContext<'_> { let fn_decl = self.lower_fn_decl(decl, None, false, None); self.with_new_scopes(|this| { + let prev = this.current_item; this.current_item = Some(fn_decl_span); let mut generator_kind = None; let body_id = this.lower_fn_body(decl, |this| { @@ -690,8 +691,10 @@ impl LoweringContext<'_> { generator_kind, movability, ); + let capture_clause = this.lower_capture_clause(capture_clause); + this.current_item = prev; hir::ExprKind::Closure( - this.lower_capture_clause(capture_clause), + capture_clause, fn_decl, body_id, fn_decl_span, diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs index dd95d99d4e1..51a0c4184f9 100644 --- a/src/librustc/hir/lowering/item.rs +++ b/src/librustc/hir/lowering/item.rs @@ -757,14 +757,12 @@ impl LoweringContext<'_> { } fn lower_variant(&mut self, v: &Variant) -> hir::Variant { - Spanned { - node: hir::VariantKind { - ident: v.node.ident, - id: self.lower_node_id(v.node.id), - attrs: self.lower_attrs(&v.node.attrs), - data: self.lower_variant_data(&v.node.data), - disr_expr: v.node.disr_expr.as_ref().map(|e| self.lower_anon_const(e)), - }, + hir::Variant { + attrs: self.lower_attrs(&v.attrs), + data: self.lower_variant_data(&v.data), + disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const(e)), + id: self.lower_node_id(v.id), + ident: v.ident, span: v.span, } } diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index b6807f7d3bb..effe2c0cc6a 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -544,11 +544,11 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_variant(&mut self, v: &'hir Variant, g: &'hir Generics, item_id: HirId) { - self.insert(v.span, v.node.id, Node::Variant(v)); - self.with_parent(v.node.id, |this| { + self.insert(v.span, v.id, Node::Variant(v)); + self.with_parent(v.id, |this| { // Register the constructor of this variant. - if let Some(ctor_hir_id) = v.node.data.ctor_hir_id() { - this.insert(v.span, ctor_hir_id, Node::Ctor(&v.node.data)); + if let Some(ctor_hir_id) = v.data.ctor_hir_id() { + this.insert(v.span, ctor_hir_id, Node::Ctor(&v.data)); } intravisit::walk_variant(this, v, g, item_id); }); diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 2964b130ddd..df9bd3a35a6 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -155,11 +155,11 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { } fn visit_variant(&mut self, v: &'a Variant, g: &'a Generics, item_id: NodeId) { - let def = self.create_def(v.node.id, - DefPathData::TypeNs(v.node.ident.as_interned_str()), + let def = self.create_def(v.id, + DefPathData::TypeNs(v.ident.as_interned_str()), v.span); self.with_parent(def, |this| { - if let Some(ctor_hir_id) = v.node.data.ctor_id() { + if let Some(ctor_hir_id) = v.data.ctor_id() { this.create_def(ctor_hir_id, DefPathData::Ctor, v.span); } visit::walk_variant(this, v, g, item_id) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index b85738dd29a..7292428ec37 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -649,12 +649,34 @@ impl<'hir> Map<'hir> { } } - pub fn is_const_scope(&self, hir_id: HirId) -> bool { - self.walk_parent_nodes(hir_id, |node| match *node { - Node::Item(Item { node: ItemKind::Const(_, _), .. }) => true, - Node::Item(Item { node: ItemKind::Fn(_, header, _, _), .. }) => header.is_const(), + /// Whether the expression pointed at by `hir_id` belongs to a `const` evaluation context. + /// Used exclusively for diagnostics, to avoid suggestion function calls. + pub fn is_const_context(&self, hir_id: HirId) -> bool { + let parent_id = self.get_parent_item(hir_id); + match self.get(parent_id) { + Node::Item(&Item { + node: ItemKind::Const(..), + .. + }) + | Node::TraitItem(&TraitItem { + node: TraitItemKind::Const(..), + .. + }) + | Node::ImplItem(&ImplItem { + node: ImplItemKind::Const(..), + .. + }) + | Node::AnonConst(_) + | Node::Item(&Item { + node: ItemKind::Static(..), + .. + }) => true, + Node::Item(&Item { + node: ItemKind::Fn(_, header, ..), + .. + }) => header.constness == Constness::Const, _ => false, - }, |_| false).map(|id| id != CRATE_HIR_ID).unwrap_or(false) + } } /// If there is some error when walking the parents (e.g., a node does not @@ -885,7 +907,7 @@ impl<'hir> Map<'hir> { _ => bug!("struct ID bound to non-struct {}", self.node_to_string(id)) } } - Some(Node::Variant(variant)) => &variant.node.data, + Some(Node::Variant(variant)) => &variant.data, Some(Node::Ctor(data)) => data, _ => bug!("expected struct or variant, found {}", self.node_to_string(id)) } @@ -918,7 +940,7 @@ impl<'hir> Map<'hir> { Node::ForeignItem(fi) => fi.ident.name, Node::ImplItem(ii) => ii.ident.name, Node::TraitItem(ti) => ti.ident.name, - Node::Variant(v) => v.node.ident.name, + Node::Variant(v) => v.ident.name, Node::Field(f) => f.ident.name, Node::Lifetime(lt) => lt.name.ident().name, Node::GenericParam(param) => param.name.ident().name, @@ -939,7 +961,7 @@ impl<'hir> Map<'hir> { Some(Node::ForeignItem(fi)) => Some(&fi.attrs[..]), Some(Node::TraitItem(ref ti)) => Some(&ti.attrs[..]), Some(Node::ImplItem(ref ii)) => Some(&ii.attrs[..]), - Some(Node::Variant(ref v)) => Some(&v.node.attrs[..]), + Some(Node::Variant(ref v)) => Some(&v.attrs[..]), Some(Node::Field(ref f)) => Some(&f.attrs[..]), Some(Node::Expr(ref e)) => Some(&*e.attrs), Some(Node::Stmt(ref s)) => Some(s.node.attrs()), @@ -1133,7 +1155,7 @@ impl<T:Named> Named for Spanned<T> { fn name(&self) -> Name { self.node.name() } impl Named for Item { fn name(&self) -> Name { self.ident.name } } impl Named for ForeignItem { fn name(&self) -> Name { self.ident.name } } -impl Named for VariantKind { fn name(&self) -> Name { self.ident.name } } +impl Named for Variant { fn name(&self) -> Name { self.ident.name } } impl Named for StructField { fn name(&self) -> Name { self.ident.name } } impl Named for TraitItem { fn name(&self) -> Name { self.ident.name } } impl Named for ImplItem { fn name(&self) -> Name { self.ident.name } } @@ -1310,7 +1332,7 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String { } Some(Node::Variant(ref variant)) => { format!("variant {} in {}{}", - variant.node.ident, + variant.ident, path_str(), id_str) } Some(Node::Field(ref field)) => { diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 3d049fe4ccd..dccc2774f52 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1541,7 +1541,7 @@ pub enum ExprKind { Match(P<Expr>, HirVec<Arm>, MatchSource), /// A closure (e.g., `move |a, b, c| {a + b + c}`). /// - /// The final span is the span of the argument block `|...|`. + /// The `Span` is the argument block `|...|`. /// /// This may also be a generator literal or an `async block` as indicated by the /// `Option<GeneratorMovability>`. @@ -2193,7 +2193,7 @@ pub struct EnumDef { } #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] -pub struct VariantKind { +pub struct Variant { /// Name of the variant. #[stable_hasher(project(name))] pub ident: Ident, @@ -2205,10 +2205,10 @@ pub struct VariantKind { pub data: VariantData, /// Explicit discriminant (e.g., `Foo = 1`). pub disr_expr: Option<AnonConst>, + /// Span + pub span: Span } -pub type Variant = Spanned<VariantKind>; - #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum UseKind { /// One import, e.g., `use foo::bar` or `use foo::bar as baz`. diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 11ba5120530..0cbfe4d75f1 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -737,7 +737,7 @@ impl<'a> State<'a> { for v in variants { self.space_if_not_bol(); self.maybe_print_comment(v.span.lo()); - self.print_outer_attributes(&v.node.attrs); + self.print_outer_attributes(&v.attrs); self.ibox(INDENT_UNIT); self.print_variant(v); self.s.word(","); @@ -829,8 +829,8 @@ impl<'a> State<'a> { pub fn print_variant(&mut self, v: &hir::Variant) { self.head(""); let generics = hir::Generics::empty(); - self.print_struct(&v.node.data, &generics, v.node.ident.name, v.span, false); - if let Some(ref d) = v.node.disr_expr { + self.print_struct(&v.data, &generics, v.ident.name, v.span, false); + if let Some(ref d) = v.disr_expr { self.s.space(); self.word_space("="); self.print_anon_const(d); diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 30d76f240d1..1fd4e00de49 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -304,7 +304,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod { } } -impl_stable_hash_for_spanned!(hir::VariantKind); +impl_stable_hash_for_spanned!(hir::Variant); impl<'a> HashStable<StableHashingContext<'a>> for hir::Item { diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 770d5155777..3267505708b 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -1,5 +1,5 @@ use crate::hir::def::Namespace; -use crate::hir::{self, Local, Pat, Body, HirId}; +use crate::hir::{self, Body, FunctionRetTy, Expr, ExprKind, HirId, Local, Pat}; use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; use crate::infer::InferCtxt; use crate::infer::type_variable::TypeVariableOriginKind; @@ -7,7 +7,7 @@ use crate::ty::{self, Ty, Infer, TyVar}; use crate::ty::print::Print; use syntax::source_map::DesugaringKind; use syntax_pos::Span; -use errors::DiagnosticBuilder; +use errors::{Applicability, DiagnosticBuilder}; struct FindLocalByTypeVisitor<'a, 'tcx> { infcx: &'a InferCtxt<'a, 'tcx>, @@ -16,9 +16,26 @@ struct FindLocalByTypeVisitor<'a, 'tcx> { found_local_pattern: Option<&'tcx Pat>, found_arg_pattern: Option<&'tcx Pat>, found_ty: Option<Ty<'tcx>>, + found_closure: Option<&'tcx ExprKind>, } impl<'a, 'tcx> FindLocalByTypeVisitor<'a, 'tcx> { + fn new( + infcx: &'a InferCtxt<'a, 'tcx>, + target_ty: Ty<'tcx>, + hir_map: &'a hir::map::Map<'tcx>, + ) -> Self { + Self { + infcx, + target_ty, + hir_map, + found_local_pattern: None, + found_arg_pattern: None, + found_ty: None, + found_closure: None, + } + } + fn node_matches_type(&mut self, hir_id: HirId) -> Option<Ty<'tcx>> { let ty_opt = self.infcx.in_progress_tables.and_then(|tables| { tables.borrow().node_type_opt(hir_id) @@ -72,6 +89,60 @@ impl<'a, 'tcx> Visitor<'tcx> for FindLocalByTypeVisitor<'a, 'tcx> { } intravisit::walk_body(self, body); } + + fn visit_expr(&mut self, expr: &'tcx Expr) { + if let (ExprKind::Closure(_, _fn_decl, _id, _sp, _), Some(_)) = ( + &expr.node, + self.node_matches_type(expr.hir_id), + ) { + self.found_closure = Some(&expr.node); + } + intravisit::walk_expr(self, expr); + } +} + +/// Suggest giving an appropriate return type to a closure expression. +fn closure_return_type_suggestion( + span: Span, + err: &mut DiagnosticBuilder<'_>, + output: &FunctionRetTy, + body: &Body, + name: &str, + ret: &str, +) { + let (arrow, post) = match output { + FunctionRetTy::DefaultReturn(_) => ("-> ", " "), + _ => ("", ""), + }; + let suggestion = match body.value.node { + ExprKind::Block(..) => { + vec![(output.span(), format!("{}{}{}", arrow, ret, post))] + } + _ => { + vec![ + (output.span(), format!("{}{}{}{{ ", arrow, ret, post)), + (body.value.span.shrink_to_hi(), " }".to_string()), + ] + } + }; + err.multipart_suggestion( + "give this closure an explicit return type without `_` placeholders", + suggestion, + Applicability::HasPlaceholders, + ); + err.span_label(span, InferCtxt::missing_type_msg(&name)); +} + +/// Given a closure signature, return a `String` containing a list of all its argument types. +fn closure_args(fn_sig: &ty::PolyFnSig<'_>) -> String { + fn_sig.inputs() + .skip_binder() + .iter() + .next() + .map(|args| args.tuple_fields() + .map(|arg| arg.to_string()) + .collect::<Vec<_>>().join(", ")) + .unwrap_or_default() } impl<'a, 'tcx> InferCtxt<'a, 'tcx> { @@ -106,16 +177,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let ty = self.resolve_vars_if_possible(&ty); let name = self.extract_type_name(&ty, None); - let mut err_span = span; - - let mut local_visitor = FindLocalByTypeVisitor { - infcx: &self, - target_ty: ty, - hir_map: &self.tcx.hir(), - found_local_pattern: None, - found_arg_pattern: None, - found_ty: None, - }; + let mut local_visitor = FindLocalByTypeVisitor::new(&self, ty, &self.tcx.hir()); let ty_to_string = |ty: Ty<'tcx>| -> String { let mut s = String::new(); let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS); @@ -136,6 +198,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let expr = self.tcx.hir().expect_expr(body_id.hir_id); local_visitor.visit_expr(expr); } + let err_span = if let Some(pattern) = local_visitor.found_arg_pattern { + pattern.span + } else { + span + }; + + let is_named_and_not_impl_trait = |ty: Ty<'_>| { + &ty.to_string() != "_" && + // FIXME: Remove this check after `impl_trait_in_bindings` is stabilized. #63527 + (!ty.is_impl_trait() || self.tcx.features().impl_trait_in_bindings) + }; + + let ty_msg = match local_visitor.found_ty { + Some(ty::TyS { sty: ty::Closure(def_id, substs), .. }) => { + let fn_sig = substs.closure_sig(*def_id, self.tcx); + let args = closure_args(&fn_sig); + let ret = fn_sig.output().skip_binder().to_string(); + format!(" for the closure `fn({}) -> {}`", args, ret) + } + Some(ty) if is_named_and_not_impl_trait(ty) => { + let ty = ty_to_string(ty); + format!(" for `{}`", ty) + } + _ => String::new(), + }; // When `name` corresponds to a type argument, show the path of the full type we're // trying to infer. In the following example, `ty_msg` contains @@ -150,27 +237,58 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // | consider giving `b` the explicit type `std::result::Result<i32, E>`, where // | the type parameter `E` is specified // ``` - let (ty_msg, suffix) = match &local_visitor.found_ty { - Some(ty) if &ty.to_string() != "_" && name == "_" => { + let mut err = struct_span_err!( + self.tcx.sess, + err_span, + E0282, + "type annotations needed{}", + ty_msg, + ); + + let suffix = match local_visitor.found_ty { + Some(ty::TyS { sty: ty::Closure(def_id, substs), .. }) => { + let fn_sig = substs.closure_sig(*def_id, self.tcx); + let ret = fn_sig.output().skip_binder().to_string(); + + if let Some(ExprKind::Closure(_, decl, body_id, ..)) = local_visitor.found_closure { + if let Some(body) = self.tcx.hir().krate().bodies.get(body_id) { + closure_return_type_suggestion( + span, + &mut err, + &decl.output, + &body, + &name, + &ret, + ); + // We don't want to give the other suggestions when the problem is the + // closure return type. + return err; + } + } + + // This shouldn't be reachable, but just in case we leave a reasonable fallback. + let args = closure_args(&fn_sig); + // This suggestion is incomplete, as the user will get further type inference + // errors due to the `_` placeholders and the introduction of `Box`, but it does + // nudge them in the right direction. + format!("a boxed closure type like `Box<dyn Fn({}) -> {}>`", args, ret) + } + Some(ty) if is_named_and_not_impl_trait(ty) && name == "_" => { let ty = ty_to_string(ty); - (format!(" for `{}`", ty), - format!("the explicit type `{}`, with the type parameters specified", ty)) + format!("the explicit type `{}`, with the type parameters specified", ty) } - Some(ty) if &ty.to_string() != "_" && ty.to_string() != name => { + Some(ty) if is_named_and_not_impl_trait(ty) && ty.to_string() != name => { let ty = ty_to_string(ty); - (format!(" for `{}`", ty), - format!( - "the explicit type `{}`, where the type parameter `{}` is specified", + format!( + "the explicit type `{}`, where the type parameter `{}` is specified", ty, name, - )) + ) } - _ => (String::new(), "a type".to_owned()), + _ => "a type".to_string(), }; - let mut labels = vec![(span, InferCtxt::missing_type_msg(&name))]; if let Some(pattern) = local_visitor.found_arg_pattern { - err_span = pattern.span; // We don't want to show the default label for closures. // // So, before clearing, the output would look something like this: @@ -187,39 +305,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // ^ consider giving this closure parameter the type `[_; 0]` // with the type parameter `_` specified // ``` - labels.clear(); - labels.push(( + err.span_label( pattern.span, format!("consider giving this closure parameter {}", suffix), - )); + ); } else if let Some(pattern) = local_visitor.found_local_pattern { - if let Some(simple_ident) = pattern.simple_ident() { + let msg = if let Some(simple_ident) = pattern.simple_ident() { match pattern.span.desugaring_kind() { - None => labels.push(( - pattern.span, - format!("consider giving `{}` {}", simple_ident, suffix), - )), - Some(DesugaringKind::ForLoop) => labels.push(( - pattern.span, - "the element type for this iterator is not specified".to_owned(), - )), - _ => {} + None => { + format!("consider giving `{}` {}", simple_ident, suffix) + } + Some(DesugaringKind::ForLoop) => { + "the element type for this iterator is not specified".to_string() + } + _ => format!("this needs {}", suffix), } } else { - labels.push((pattern.span, format!("consider giving this pattern {}", suffix))); - } - }; - - let mut err = struct_span_err!( - self.tcx.sess, - err_span, - E0282, - "type annotations needed{}", - ty_msg, - ); - - for (target_span, label_message) in labels { - err.span_label(target_span, label_message); + format!("consider giving this pattern {}", suffix) + }; + err.span_label(pattern.span, msg); + } + if !err.span.span_labels().iter().any(|span_label| { + span_label.label.is_some() && span_label.span == span + }) && local_visitor.found_arg_pattern.is_none() + { // Avoid multiple labels pointing at `span`. + err.span_label(span, InferCtxt::missing_type_msg(&name)); } err diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 3584a128290..1b73361dcd4 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -1060,7 +1060,7 @@ for LateContextAndPass<'a, 'tcx, T> { v: &'tcx hir::Variant, g: &'tcx hir::Generics, item_id: hir::HirId) { - self.with_lint_attrs(v.node.id, &v.node.attrs, |cx| { + self.with_lint_attrs(v.id, &v.attrs, |cx| { lint_callback!(cx, check_variant, v, g); hir_visit::walk_variant(cx, v, g, item_id); lint_callback!(cx, check_variant_post, v, g); @@ -1236,7 +1236,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> } fn visit_variant(&mut self, v: &'a ast::Variant, g: &'a ast::Generics, item_id: ast::NodeId) { - self.with_lint_attrs(item_id, &v.node.attrs, |cx| { + self.with_lint_attrs(item_id, &v.attrs, |cx| { run_early_pass!(cx, check_variant, v, g); ast_visit::walk_variant(cx, v, g, item_id); run_early_pass!(cx, check_variant_post, v, g); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 8ddf4603490..8cb5b1e26d9 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -846,7 +846,7 @@ impl intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> { v: &'tcx hir::Variant, g: &'tcx hir::Generics, item_id: hir::HirId) { - self.with_lint_attrs(v.node.id, &v.node.attrs, |builder| { + self.with_lint_attrs(v.id, &v.attrs, |builder| { intravisit::walk_variant(builder, v, g, item_id); }) } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 55fa261f1ed..1f3adf00923 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -366,12 +366,12 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> { match item.node { hir::ItemKind::Enum(ref enum_def, _) => { if allow_dead_code { - self.worklist.extend(enum_def.variants.iter().map(|variant| variant.node.id)); + self.worklist.extend(enum_def.variants.iter().map(|variant| variant.id)); } for variant in &enum_def.variants { - if let Some(ctor_hir_id) = variant.node.data.ctor_hir_id() { - self.struct_constructors.insert(ctor_hir_id, variant.node.id); + if let Some(ctor_hir_id) = variant.data.ctor_hir_id() { + self.struct_constructors.insert(ctor_hir_id, variant.id); } } } @@ -497,7 +497,7 @@ impl DeadVisitor<'tcx> { && !has_allow_dead_code_or_lang_attr(self.tcx, field.hir_id, &field.attrs) } - fn should_warn_about_variant(&mut self, variant: &hir::VariantKind) -> bool { + fn should_warn_about_variant(&mut self, variant: &hir::Variant) -> bool { !self.symbol_is_live(variant.id) && !has_allow_dead_code_or_lang_attr(self.tcx, variant.id, @@ -596,8 +596,8 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { variant: &'tcx hir::Variant, g: &'tcx hir::Generics, id: hir::HirId) { - if self.should_warn_about_variant(&variant.node) { - self.warn_dead_code(variant.node.id, variant.span, variant.node.ident.name, + if self.should_warn_about_variant(&variant) { + self.warn_dead_code(variant.id, variant.span, variant.ident.name, "variant", "constructed"); } else { intravisit::walk_variant(self, variant, g, id); diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 5ab762ab225..d02259bf301 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -290,10 +290,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { } fn visit_variant(&mut self, var: &'tcx Variant, g: &'tcx Generics, item_id: HirId) { - self.annotate(var.node.id, &var.node.attrs, var.span, AnnotationKind::Required, + self.annotate(var.id, &var.attrs, var.span, AnnotationKind::Required, |v| { - if let Some(ctor_hir_id) = var.node.data.ctor_hir_id() { - v.annotate(ctor_hir_id, &var.node.attrs, var.span, AnnotationKind::Required, + if let Some(ctor_hir_id) = var.data.ctor_hir_id() { + v.annotate(ctor_hir_id, &var.attrs, var.span, AnnotationKind::Required, |_| {}); } @@ -372,7 +372,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> { } fn visit_variant(&mut self, var: &'tcx Variant, g: &'tcx Generics, item_id: HirId) { - self.check_missing_stability(var.node.id, var.span, "variant"); + self.check_missing_stability(var.id, var.span, "variant"); intravisit::walk_variant(self, var, g, item_id); } diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs index 0a998513379..b55e6bc54bc 100644 --- a/src/librustc/mir/interpret/pointer.rs +++ b/src/librustc/mir/interpret/pointer.rs @@ -189,8 +189,11 @@ impl<'tcx, Tag> Pointer<Tag> { Pointer { alloc_id: self.alloc_id, offset: self.offset, tag: () } } + /// Test if the pointer is "inbounds" of an allocation of the given size. + /// A pointer is "inbounds" even if its offset is equal to the size; this is + /// a "one-past-the-end" pointer. #[inline(always)] - pub fn check_in_alloc( + pub fn check_inbounds_alloc( self, allocation_size: Size, msg: CheckInAllocMsg, diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 42e367b8518..42390c209d6 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -2068,6 +2068,9 @@ impl<'tcx> TyS<'tcx> { Error => { // ignore errors (#54954) ty::Binder::dummy(FnSig::fake()) } + Closure(..) => bug!( + "to get the signature of a closure, use `closure_sig()` not `fn_sig()`", + ), _ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self) } } |
