Skip to content

Rollup of 3 pull requests #64491

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Sep 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 18 additions & 20 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,26 +205,24 @@ pub struct LocalTableInContext<'a, V> {
fn validate_hir_id_for_typeck_tables(local_id_root: Option<DefId>,
hir_id: hir::HirId,
mut_access: bool) {
if cfg!(debug_assertions) {
if let Some(local_id_root) = local_id_root {
if hir_id.owner != local_id_root.index {
ty::tls::with(|tcx| {
bug!("node {} with HirId::owner {:?} cannot be placed in \
TypeckTables with local_id_root {:?}",
tcx.hir().node_to_string(hir_id),
DefId::local(hir_id.owner),
local_id_root)
});
}
} else {
// We use "Null Object" TypeckTables in some of the analysis passes.
// These are just expected to be empty and their `local_id_root` is
// `None`. Therefore we cannot verify whether a given `HirId` would
// be a valid key for the given table. Instead we make sure that
// nobody tries to write to such a Null Object table.
if mut_access {
bug!("access to invalid TypeckTables")
}
if let Some(local_id_root) = local_id_root {
if hir_id.owner != local_id_root.index {
ty::tls::with(|tcx| {
bug!("node {} with HirId::owner {:?} cannot be placed in \
TypeckTables with local_id_root {:?}",
tcx.hir().node_to_string(hir_id),
DefId::local(hir_id.owner),
local_id_root)
});
}
} else {
// We use "Null Object" TypeckTables in some of the analysis passes.
// These are just expected to be empty and their `local_id_root` is
// `None`. Therefore we cannot verify whether a given `HirId` would
// be a valid key for the given table. Instead we make sure that
// nobody tries to write to such a Null Object table.
if mut_access {
bug!("access to invalid TypeckTables")
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_lint/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,8 @@ impl UnusedParens {
right_pos: Option<BytePos>) {
match value.node {
ast::ExprKind::Paren(ref inner) => {
if !Self::is_expr_parens_necessary(inner, followed_by_block) {
if !Self::is_expr_parens_necessary(inner, followed_by_block) &&
value.attrs.is_empty() {
let expr_text = if let Ok(snippet) = cx.sess().source_map()
.span_to_snippet(value.span) {
snippet
Expand Down
119 changes: 63 additions & 56 deletions src/librustc_save_analysis/dump_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
self.save_ctxt.span_from_span(span)
}

fn lookup_def_id(&self, ref_id: NodeId) -> Option<DefId> {
self.save_ctxt.lookup_def_id(ref_id)
}

pub fn dump_crate_info(&mut self, name: &str, krate: &ast::Crate) {
let source_file = self.tcx.sess.local_crate_source_file.as_ref();
let crate_root = source_file.map(|source_file| {
Expand Down Expand Up @@ -223,13 +227,6 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
}
}

fn lookup_def_id(&self, ref_id: NodeId) -> Option<DefId> {
match self.save_ctxt.get_path_res(ref_id) {
Res::PrimTy(..) | Res::SelfTy(..) | Res::Err => None,
def => Some(def.def_id()),
}
}

fn process_formals(&mut self, formals: &'l [ast::Param], qualname: &str) {
for arg in formals {
self.visit_pat(&arg.pat);
Expand Down Expand Up @@ -283,36 +280,32 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
) {
debug!("process_method: {}:{}", id, ident);

if let Some(mut method_data) = self.save_ctxt.get_method_data(id, ident, span) {
let sig_str = crate::make_signature(&sig.decl, &generics);
if body.is_some() {
self.nest_tables(
id,
|v| v.process_formals(&sig.decl.inputs, &method_data.qualname),
);
}
let hir_id = self.tcx.hir().node_to_hir_id(id);
self.nest_tables(id, |v| {
if let Some(mut method_data) = v.save_ctxt.get_method_data(id, ident, span) {
v.process_formals(&sig.decl.inputs, &method_data.qualname);
v.process_generic_params(&generics, &method_data.qualname, id);

self.process_generic_params(&generics, &method_data.qualname, id);
method_data.value = crate::make_signature(&sig.decl, &generics);
method_data.sig = sig::method_signature(id, ident, generics, sig, &v.save_ctxt);

method_data.value = sig_str;
method_data.sig = sig::method_signature(id, ident, generics, sig, &self.save_ctxt);
let hir_id = self.tcx.hir().node_to_hir_id(id);
self.dumper.dump_def(&access_from_vis!(self.save_ctxt, vis, hir_id), method_data);
}
v.dumper.dump_def(&access_from_vis!(v.save_ctxt, vis, hir_id), method_data);
}

// walk arg and return types
for arg in &sig.decl.inputs {
self.visit_ty(&arg.ty);
}
// walk arg and return types
for arg in &sig.decl.inputs {
v.visit_ty(&arg.ty);
}

if let ast::FunctionRetTy::Ty(ref ret_ty) = sig.decl.output {
self.visit_ty(ret_ty);
}
if let ast::FunctionRetTy::Ty(ref ret_ty) = sig.decl.output {
v.visit_ty(ret_ty);
}

// walk the fn body
if let Some(body) = body {
self.nest_tables(id, |v| v.visit_block(body));
}
// walk the fn body
if let Some(body) = body {
v.visit_block(body);
}
});
}

fn process_struct_field_def(&mut self, field: &ast::StructField, parent_id: NodeId) {
Expand Down Expand Up @@ -377,26 +370,31 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
ty_params: &'l ast::Generics,
body: &'l ast::Block,
) {
if let Some(fn_data) = self.save_ctxt.get_item_data(item) {
down_cast_data!(fn_data, DefData, item.span);
self.nest_tables(
item.id,
|v| v.process_formals(&decl.inputs, &fn_data.qualname),
);
self.process_generic_params(ty_params, &fn_data.qualname, item.id);
let hir_id = self.tcx.hir().node_to_hir_id(item.id);
self.dumper.dump_def(&access_from!(self.save_ctxt, item, hir_id), fn_data);
}
let hir_id = self.tcx.hir().node_to_hir_id(item.id);
self.nest_tables(item.id, |v| {
if let Some(fn_data) = v.save_ctxt.get_item_data(item) {
down_cast_data!(fn_data, DefData, item.span);
v.process_formals(&decl.inputs, &fn_data.qualname);
v.process_generic_params(ty_params, &fn_data.qualname, item.id);

for arg in &decl.inputs {
self.visit_ty(&arg.ty);
}
v.dumper.dump_def(&access_from!(v.save_ctxt, item, hir_id), fn_data);
}

if let ast::FunctionRetTy::Ty(ref ret_ty) = decl.output {
self.visit_ty(&ret_ty);
}
for arg in &decl.inputs {
v.visit_ty(&arg.ty)
}

if let ast::FunctionRetTy::Ty(ref ret_ty) = decl.output {
if let ast::TyKind::ImplTrait(..) = ret_ty.node {
// FIXME: Opaque type desugaring prevents us from easily
// processing trait bounds. See `visit_ty` for more details.
} else {
v.visit_ty(&ret_ty);
}
}

self.nest_tables(item.id, |v| v.visit_block(&body));
v.visit_block(&body);
});
}

fn process_static_or_const_item(
Expand Down Expand Up @@ -1113,11 +1111,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
// FIXME: uses of the assoc type should ideally point to this
// 'def' and the name here should be a ref to the def in the
// trait.
for bound in bounds.iter() {
if let ast::GenericBound::Trait(trait_ref, _) = bound {
self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path)
}
}
self.process_bounds(&bounds);
}
ast::ImplItemKind::Macro(_) => {}
}
Expand Down Expand Up @@ -1364,10 +1358,10 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
self.visit_ty(&ty);
self.process_generic_params(ty_params, &qualname, item.id);
}
OpaqueTy(ref _bounds, ref ty_params) => {
OpaqueTy(ref bounds, ref ty_params) => {
let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
// FIXME do something with _bounds

let value = String::new();
if !self.span.filter_generated(item.ident.span) {
let span = self.span_from_span(item.ident.span);
Expand All @@ -1393,6 +1387,7 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
);
}

self.process_bounds(bounds);
self.process_generic_params(ty_params, &qualname, item.id);
}
Mac(_) => (),
Expand Down Expand Up @@ -1449,6 +1444,18 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
self.visit_ty(element);
self.nest_tables(length.id, |v| v.visit_expr(&length.value));
}
ast::TyKind::ImplTrait(id, ref bounds) => {
// FIXME: As of writing, the opaque type lowering introduces
// another DefPath scope/segment (used to declare the resulting
// opaque type item).
// However, the synthetic scope does *not* have associated
// typeck tables, which means we can't nest it and we fire an
// assertion when resolving the qualified type paths in trait
// bounds...
// This will panic if called on return type `impl Trait`, which
// we guard against in `process_fn`.
self.nest_tables(id, |v| v.process_bounds(bounds));
}
_ => visit::walk_ty(self, t),
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/librustc_save_analysis/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
let impl_id = self.next_impl_id();
let span = self.span_from_span(sub_span);

let type_data = self.lookup_ref_id(typ.id);
let type_data = self.lookup_def_id(typ.id);
type_data.map(|type_data| {
Data::RelationData(Relation {
kind: RelationKind::Impl {
Expand All @@ -322,7 +322,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
from: id_from_def_id(type_data),
to: trait_ref
.as_ref()
.and_then(|t| self.lookup_ref_id(t.ref_id))
.and_then(|t| self.lookup_def_id(t.ref_id))
.map(id_from_def_id)
.unwrap_or_else(|| null_id()),
},
Expand Down Expand Up @@ -495,7 +495,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
}

pub fn get_trait_ref_data(&self, trait_ref: &ast::TraitRef) -> Option<Ref> {
self.lookup_ref_id(trait_ref.ref_id).and_then(|def_id| {
self.lookup_def_id(trait_ref.ref_id).and_then(|def_id| {
let span = trait_ref.path.span;
if generated_code(span) {
return None;
Expand Down Expand Up @@ -870,7 +870,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
})
}

fn lookup_ref_id(&self, ref_id: NodeId) -> Option<DefId> {
fn lookup_def_id(&self, ref_id: NodeId) -> Option<DefId> {
match self.get_path_res(ref_id) {
Res::PrimTy(_) | Res::SelfTy(..) | Res::Err => None,
def => Some(def.def_id()),
Expand Down
3 changes: 2 additions & 1 deletion src/libstd/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1956,7 +1956,8 @@ pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
/// # Platform-specific behavior
///
/// This function currently corresponds to the `opendir` function on Unix
/// and the `FindFirstFile` function on Windows.
/// and the `FindFirstFile` function on Windows. Advancing the iterator
/// currently corresponds to `readdir` on Unix and `FindNextFile` on Windows.
/// Note that, this [may change in the future][changes].
///
/// [changes]: ../io/index.html#platform-specific-behavior
Expand Down
6 changes: 5 additions & 1 deletion src/test/ui/lint/issue-54538-unused-parens-lint.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(box_patterns)]
#![feature(box_patterns, stmt_expr_attributes)]

#![feature(or_patterns)]
//~^ WARN the feature `or_patterns` is incomplete
Expand All @@ -17,6 +17,10 @@ fn lint_on_top_level() {
let _ = |(a): u8| 0; //~ ERROR unnecessary parentheses around pattern
}

fn _no_lint_attr() {
let _x = #[allow(dead_code)] (1 + 2);
}

// Don't lint in these cases (#64106).
fn or_patterns_no_lint() {
match Box::new(0) {
Expand Down
Loading