Skip to content
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

Lint against single-use lifetime names #46441

Merged
merged 1 commit into from
Dec 20, 2017

Conversation

gaurikholkar-zz
Copy link

@gaurikholkar-zz gaurikholkar-zz commented Dec 2, 2017

This is a fix for #44752

TO-DO

  • change lint message
  • add ui tests

r? @nikomatsakis

@kennytm kennytm added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Dec 2, 2017
/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
pub struct HardwiredLints;

impl LintPass for HardwiredLints {
fn get_lints(&self) -> LintArray {
lint_array!(
UNUSED_IMPORTS,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated reformatting.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed formatting changes @oli-obk

LateBound(ty::DebruijnIndex, /* lifetime decl */ DefId),
LateBoundAnon(ty::DebruijnIndex, /* anon index */ u32),
Free(DefId, /* lifetime decl */ DefId),
EarlyBound(/* index */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move the formatting changes into their own commit or undo them. It's very hard to see the non-formatting changes among them

@nikomatsakis
Copy link
Contributor

Regarding the formatting changes, what I usually find helpful is to have the first commit just rustfmt's the whole file, and then start from there. Then when you rebase, if you get conflicts in this commit, you can just take the "master" version of the code indiscriminately and then re-run rustfmt afterwards. (This...mostly works. Sometimes I find code gets duplicated.)

@gaurikholkar-zz
Copy link
Author

I guess most of it is undone. Will take care of the rest in a separate commit

@gaurikholkar-zz
Copy link
Author

gaurikholkar-zz commented Dec 3, 2017

@nikomatsakis @oli-obk I get this error

note: run with `RUST_BACKTRACE=1` for a backtrace

thread 'rustc' panicked at 'assertion failed: def_id.is_local()', src/librustc/hir/map/mod.rs:309:8
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
   1: std::sys_common::backtrace::print
   2: std::panicking::default_hook::{{closure}}
   3: std::panicking::default_hook
   4: std::panicking::rust_panic_with_hook
   5: std::panicking::begin_panic
   6: rustc::hir::map::Map::def_key
   7: <rustc::middle::resolve_lifetime::LifetimeContext<'a, 'tcx> as rustc::hir::intravisit::Visitor<'tcx>>::visit_path
   8: <rustc::middle::resolve_lifetime::LifetimeContext<'a, 'tcx> as rustc::hir::intravisit::Visitor<'tcx>>::visit_ty
   9: <rustc::middle::resolve_lifetime::LifetimeContext<'a, 'tcx> as rustc::hir::intravisit::Visitor<'tcx>>::visit_impl_item
  10: rustc::hir::intravisit::walk_impl_item_ref
  11: rustc::hir::intravisit::walk_item
  12: <rustc::middle::resolve_lifetime::LifetimeContext<'a, 'tcx> as rustc::hir::intravisit::Visitor<'tcx>>::visit_item
  13: rustc::session::Session::track_errors
  14: rustc::middle::resolve_lifetime::resolve_lifetimes
  15: rustc::ty::maps::<impl rustc::ty::maps::queries::resolve_lifetimes<'tcx>>::compute_result
  16: rustc::dep_graph::graph::DepGraph::with_task_impl
  17: rustc::dep_graph::graph::DepGraph::with_task
  18: rustc_errors::Handler::track_diagnostics
  19: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::cycle_check
  20: rustc::ty::maps::<impl rustc::ty::maps::queries::resolve_lifetimes<'tcx>>::force
  21: rustc::ty::maps::<impl rustc::ty::maps::queries::resolve_lifetimes<'tcx>>::try_get
  22: rustc::ty::maps::TyCtxtAt::resolve_lifetimes
  23: rustc::ty::maps::<impl rustc::ty::context::TyCtxt<'a, 'tcx, 'lcx>>::resolve_lifetimes
  24: core::ops::function::FnOnce::call_once
  25: rustc::ty::maps::<impl rustc::ty::maps::queries::object_lifetime_defaults_map<'tcx>>::compute_result
  26: rustc::dep_graph::graph::DepGraph::with_task_impl
  27: rustc::dep_graph::graph::DepGraph::with_task
  28: rustc_errors::Handler::track_diagnostics
  29: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::cycle_check
  30: rustc::ty::maps::<impl rustc::ty::maps::queries::object_lifetime_defaults_map<'tcx>>::force
  31: rustc::ty::maps::<impl rustc::ty::maps::queries::object_lifetime_defaults_map<'tcx>>::try_get
  32: rustc::ty::maps::TyCtxtAt::object_lifetime_defaults_map
  33: rustc::ty::context::TyCtxt::object_lifetime_defaults
  34: rustc_typeck::collect::generics_of
  35: rustc::ty::maps::<impl rustc::ty::maps::queries::generics_of<'tcx>>::compute_result
  36: rustc::dep_graph::graph::DepGraph::with_task_impl
  37: rustc::dep_graph::graph::DepGraph::with_task
  38: rustc_errors::Handler::track_diagnostics
  39: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::cycle_check
  40: rustc::ty::maps::<impl rustc::ty::maps::queries::generics_of<'tcx>>::force
  41: rustc::ty::maps::<impl rustc::ty::maps::queries::generics_of<'tcx>>::try_get
  42: rustc::ty::maps::TyCtxtAt::generics_of
  43: rustc::ty::maps::<impl rustc::ty::context::TyCtxt<'a, 'tcx, 'lcx>>::generics_of
  44: <rustc_typeck::collect::CollectItemTypesVisitor<'a, 'tcx> as rustc::hir::intravisit::Visitor<'tcx>>::visit_item
  45: rustc_typeck::collect::collect_item_types
  46: rustc_typeck::check_crate
  47: <std::thread::local::LocalKey<T>>::with
  48: rustc::ty::context::tls::enter
  49: <std::thread::local::LocalKey<T>>::with
  50: rustc::ty::context::TyCtxt::create_and_enter
  51: rustc_driver::driver::compile_input
  52: rustc_driver::run_compiler

error: Could not compile `alloc`.

Caused by:
  process didn't exit successfully: `/Users/gkholkar/Desktop/or/rust/build/bootstrap/debug/rustc --crate-name alloc src/liballoc/lib.rs --error-format json --crate-type lib --emit=dep-info,link -C opt-level=2 -C metadata=22e63b537c61a4f8 -C extra-filename=-22e63b537c61a4f8 --out-dir /Users/gkholkar/Desktop/or/rust/build/x86_64-apple-darwin/stage1-std/x86_64-apple-darwin/release/deps --target x86_64-apple-darwin -L dependency=/Users/gkholkar/Desktop/or/rust/build/x86_64-apple-darwin/stage1-std/x86_64-apple-darwin/release/deps -L dependency=/Users/gkholkar/Desktop/or/rust/build/x86_64-apple-darwin/stage1-std/release/deps --extern std_unicode=/Users/gkholkar/Desktop/or/rust/build/x86_64-apple-darwin/stage1-std/x86_64-apple-darwin/release/deps/libstd_unicode-aa82a4fba39f1481.rlib --extern core=/Users/gkholkar/Desktop/or/rust/build/x86_64-apple-darwin/stage1-std/x86_64-apple-darwin/release/deps/libcore-a1b407ed3953731d.rlib` (exit code: 101)
thread 'main' panicked at 'command did not execute successfully: "/Users/gkholkar/Desktop/or/rust/build/x86_64-apple-darwin/stage0/bin/cargo" "build" "--target" "x86_64-apple-darwin" "-j" "4" "--release" "--features" "panic-unwind jemalloc backtrace" "--manifest-path" "/Users/gkholkar/Desktop/or/rust/src/libstd/Cargo.toml" "--message-format" "json"
expected success, got: exit code: 101', src/bootstrap/compile.rs:882:8
stack backtrace:
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
   1: std::sys_common::backtrace::_print
   2: std::panicking::default_hook::{{closure}}
   3: std::panicking::default_hook
   4: std::panicking::rust_panic_with_hook
   5: std::panicking::begin_panic
   6: std::panicking::begin_panic_fmt
   7: bootstrap::compile::run_cargo
   8: <bootstrap::compile::Std as bootstrap::builder::Step>::run
   9: bootstrap::builder::Builder::ensure
  10: <bootstrap::compile::Test as bootstrap::builder::Step>::run
  11: bootstrap::builder::Builder::ensure
  12: <bootstrap::compile::Rustc as bootstrap::builder::Step>::run
  13: bootstrap::builder::Builder::ensure
  14: <bootstrap::compile::Rustc as bootstrap::builder::Step>::make_run
  15: bootstrap::builder::StepDescription::maybe_run
  16: bootstrap::builder::StepDescription::run
  17: bootstrap::builder::Builder::run
  18: bootstrap::Build::build
  19: bootstrap::main
  20: __rust_maybe_catch_panic
  21: std::rt

@gaurikholkar-zz
Copy link
Author

Will fix the ui tests

@oli-obk
Copy link
Contributor

oli-obk commented Dec 4, 2017

They are failing with an ICE: unelided lifetime in signature. Can you get a backtrace for such a failure?

@gaurikholkar-zz
Copy link
Author

Afk for a while. Will check as asap

@bors
Copy link
Contributor

bors commented Dec 5, 2017

☔ The latest upstream changes (presumably #46305) made this pull request unmergeable. Please resolve the merge conflicts.

Copy link
Author

@gaurikholkar-zz gaurikholkar-zz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do I write both the errors occuring on the same line on the .rs files for this test?

@oli-obk
Copy link
Contributor

oli-obk commented Dec 5, 2017

You can write //~^ ERROR foo in the line below. If you have even more messages per line, start adding //~| ERROR bar below a line with the ^

@nikomatsakis
Copy link
Contributor

So I feel like the new code is generating unexpected errors. I'm going to poke around a bit.

@nikomatsakis
Copy link
Contributor

nikomatsakis commented Dec 8, 2017

I'm going to open a PR with just the resolve-lifetimes query work, so we can isolate what is affecting what.

@nikomatsakis
Copy link
Contributor

Blocked on #46657

@gaurikholkar-zz gaurikholkar-zz changed the title Lint against single-use lifetime names WIP Lint against single-use lifetime names Dec 11, 2017
@bors
Copy link
Contributor

bors commented Dec 12, 2017

☔ The latest upstream changes (presumably #46657) made this pull request unmergeable. Please resolve the merge conflicts.

@nikomatsakis
Copy link
Contributor

OK #46657 landed -- @gaurikholkar, can you rebase atop that?

@gaurikholkar-zz
Copy link
Author

@nikomatsakis at it

@gaurikholkar-zz gaurikholkar-zz force-pushed the single_lifetimes branch 3 times, most recently from affef5e to c84e49c Compare December 14, 2017 14:14
@gaurikholkar-zz
Copy link
Author

@nikomatsakis build passed :)

Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking pretty good. I think we need a few more tests. It's probably not quite working right, but I'd be happy to get something landed and try to refine later.

self.visit_early_late(None,
decl,
generics,
|this| { intravisit::walk_item(this, item); });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: formatting

self.visit_early_late(None,
decl,
generics,
|this| { intravisit::walk_foreign_item(this, item); })
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: formatting

@@ -1132,8 +1145,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
tcx, ref mut map, ..
} = *self;
let labels_in_fn = replace(&mut self.labels_in_fn, vec![]);
let xcrate_object_lifetime_defaults =
replace(&mut self.xcrate_object_lifetime_defaults, DefIdMap());
let xcrate_object_lifetime_defaults = replace(&mut self.xcrate_object_lifetime_defaults,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: formatting

&LifetimeUseSet::One(_) => {
let node_id = this.tcx.hir.as_local_node_id(*def_id).unwrap();
debug!("nod id first={:?}", node_id);
let hir_lifetime: Option<&hir::Lifetime> = match this.tcx.hir.get(node_id) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would do:

if let Some(hir_lifetime) = this.tcx.hir.get(node_id) {
    let span = hir_lifetime.span;
    let id = hir_lifetime.span;

    // existing code:
                            debug!("id ={:?} span = {:?} hir_lifetime = {:?}",
                               node_id,
                               span,
                               hir_lifetime);

                        this.tcx
                            .struct_span_lint_node(lint::builtin::SINGLE_USE_LIFETIME,
                                                   id,
                                                   span,
                                                   &format!("lifetime name `{}` only used once",
                                                   hir_lifetime.unwrap().name.name()))
                            .emit();
}

@@ -1239,9 +1289,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
}
}

fn resolve_lifetime_ref(&mut self, lifetime_ref: &hir::Lifetime) {
debug!("resolve_lifetime_ref(lifetime_ref={:?})", lifetime_ref);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nnit: removed handy debug output

hir::map::NodeForeignItem(_) | hir::map::NodeTy(_) | hir::map::NodeTraitRef(_) => None,
hir::map::NodeForeignItem(_) |
hir::map::NodeTy(_) |
hir::map::NodeTraitRef(_) => None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: formatting

for i in 0..lifetimes.len() {
let lifetime_i = &lifetimes[i];

for lifetime in lifetimes {
match lifetime.lifetime.name {
hir::LifetimeName::Static | hir::LifetimeName::Underscore => {
hir::LifetimeName::Static |
hir::LifetimeName::Underscore => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: formatting

@@ -1909,7 +1960,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
);
err.emit();
}
hir::LifetimeName::Implicit | hir::LifetimeName::Name(_) => {}
hir::LifetimeName::Implicit |
hir::LifetimeName::Name(_) => {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: formatting

// except according to those terms.
#![deny(single_use_lifetime)]

fn deref<'x>(v: &'x u32) -> u32 { //~ ERROR lifetime name `'x` only used once
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a test

fn deref<'x>() -> &'x u32 {
    22
}

Ideally, this would not warn, but I suspect your code will. I think that's ok, we can just add a comment like:

// FIXME(#44752) -- this scenario should not be warned

Here are some other scenarios. I will put down the behavior I think we eventually want, but it may not be the behavior that we currently have.

struct Foo<'x> {
    x: &'x u32 // no warning!
}

// Once #44524 is fixed, this should issue a warning. Hence, it's ok if it does so now, though perhaps a bit premature. 
impl<'y> Foo<'y> {
    fn method() { }
}
// Neither should issue a warning, as explicit lifetimes are mandatory in these cases:
struct Foo<'x> {
    x: &'x u32
}

enum Bar<'x> {
    Variant(&'x u32)
}
// Should not issue a warning, as explicit lifetimes are mandatory in these cases:
trait Foo<'x> {
    fn foo(&self, arg: &'x u32);
}

@nikomatsakis
Copy link
Contributor

Oh, in my review, I realize I wasn't clear. The "Nit: formatting" bits was just meant to say that these changes weren't necessary, though also not harmful. Ideally they would be isolated into a separate commit (or else pulled out).

@gaurikholkar-zz gaurikholkar-zz force-pushed the single_lifetimes branch 2 times, most recently from 001aa98 to cfbff3d Compare December 19, 2017 17:46
@nikomatsakis
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Dec 19, 2017

📌 Commit e741dad has been approved by nikomatsakis

@kennytm kennytm added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Dec 19, 2017
@bors
Copy link
Contributor

bors commented Dec 20, 2017

⌛ Testing commit e741dad with merge edbd7d2...

bors added a commit that referenced this pull request Dec 20, 2017
 Lint against single-use lifetime names

This is a fix for #44752

TO-DO

- [x] change lint message
- [x] add ui tests

r? @nikomatsakis
@bors
Copy link
Contributor

bors commented Dec 20, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: nikomatsakis
Pushing edbd7d2 to master...

@bors bors merged commit e741dad into rust-lang:master Dec 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants