8000 Rollup of 9 pull requests by Centril · Pull Request #65449 · rust-lang/rust · GitHub
[go: up one dir, main page]

Skip to content

Rollup of 9 pull requests #65449

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

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
48fff6f
don't assume we can *always* find a return type hint in async fn
nikomatsakis Oct 9, 2019
061b906
Return `false` from `needs_drop` for all zero-sized arrays
ecstatic-morse Oct 13, 2019
8fd16ba
Remove special case for zero-sized arrays from indirectly mut locals
ecstatic-morse Oct 13, 2019
c08a871
Add regression test for #65348
ecstatic-morse Oct 13, 2019
c50664d
Prefer statx on linux if available
oxalica Oct 4, 2019
55cddb8
Fix missing guard
oxalica Oct 10, 2019
f81b154
Add troubleshooting section to PGO chapter in rustc book.
michaelwoerister Oct 14, 2019
e3b7f3d
Fix cfgs for current libc
oxalica Oct 13, 2019
7528234
Add regression test for issue #64153.
michaelwoerister Oct 14, 2019
af05b23
Fix issue #64153 by checking for .rcgu.o suffix when trying to identi…
michaelwoerister Oct 15, 2019
53187c5
Slides path lifetime to the lifetime resolver
Phosphorus15 Oct 11, 2019
1fb8cfb
Organize `never_type` tests
Centril Oct 15, 2019
dee53d7
Fix suggestion to constrain trait for method to be found
estebank Oct 9, 2019
fa3a4ae
Implement AsRef<[T]> for List<T>
spastorino Oct 15, 2019
07ccdcf
Rollup merge of #65094 - oxalica:linux-statx, r=alexcrichton
Centril Oct 15, 2019
2e686ef
Rollup merge of #65235 - nikomatsakis:issue-65159-async-fn-return-ice…
Centril Oct 15, 2019
b2416f4
Rollup merge of #65242 - estebank:contrain-trait-sugg, r=varkor
Centril Oct 15, 2019
077a26a
Rollup merge of #65307 - Phosphorus15:master, r=varkor
Centril Oct 15, 2019
39e8aa1
Rollup merge of #65389 - ecstatic-morse:zero-sized-array-no-drop, r=e…
Centril Oct 15, 2019
d4ba3e2
Rollup merge of #65402 - michaelwoerister:pgo-troubleshooting-docs, r…
Centril Oct 15, 2019
d03b09f
Rollup merge of #65435 - michaelwoerister:fix-issue-64153, r=alexcric…
Centril Oct 15, 2019
4ba1658
Rollup merge of #65438 - Centril:almost, r=varkor
Centril Oct 15, 2019
9ce03a6
Rollup merge of #65444 - spastorino:as-ref-for-list, r=Mark-Simulacrum
Centril Oct 15, 2019
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
113 changes: 70 additions & 43 deletions src/librustc_typeck/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -777,19 +777,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else {
"items from traits can only be used if the trait is implemented and in scope"
});
let mut msg = format!(
let message = |action| format!(
"the following {traits_define} an item `{name}`, perhaps you need to {action} \
{one_of_them}:",
traits_define = if candidates.len() == 1 {
"trait defines"
} else {
"traits define"
},
action = if let Some(param) = param_type {
format!("restrict type parameter `{}` with", param)
} else {
"implement".to_string()
},
action = action,
one_of_them = if candidates.len() == 1 {
"it"
} else {
Expand All @@ -809,50 +805,81 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Get the `hir::Param` to verify whether it already has any bounds.
// We do this to avoid suggesting code that ends up as `T: FooBar`,
// instead we suggest `T: Foo + Bar` in that case.
let mut has_bounds = None;
let mut impl_trait = false;
if let Node::GenericParam(ref param) = hir.get(id) {
let kind = &param.kind;
if let hir::GenericParamKind::Type { synthetic: Some(_), .. } = kind {
// We've found `fn foo(x: impl Trait)` instead of
// `fn foo<T>(x: T)`. We want to suggest the correct
// `fn foo(x: impl Trait + TraitBound)` instead of
// `fn foo<T: TraitBound>(x: T)`. (See #63706.)
impl_trait = true;
has_bounds = param.bounds.get(1);
} else {
has_bounds = param.bounds.get(0);
match hir.get(id) {
Node::GenericParam(ref param) => {
let mut impl_trait = false;
let has_bounds = if let hir::GenericParamKind::Type {
synthetic: Some(_), ..
} = &param.kind {
// We've found `fn foo(x: impl Trait)` instead of
// `fn foo<T>(x: T)`. We want to suggest the correct
// `fn foo(x: impl Trait + TraitBound)` instead of
// `fn foo<T: TraitBound>(x: T)`. (#63706)
impl_trait = true;
param.bounds.get(1)
} else {
param.bounds.get(0)
};
let sp = hir.span(id);
let sp = if let Some(first_bound) = has_bounds {
// `sp` only covers `T`, change it so that it covers
// `T:` when appropriate
sp.until(first_bound.span())
} else {
sp
};
// FIXME: contrast `t.def_id` against `param.bounds` to not suggest
// traits already there. That can happen when the cause is that
// we're in a const scope or associated function used as a method.
err.span_suggestions(
sp,
&message(format!(
"restrict type parameter `{}` with",
param.name.ident().as_str(),
)),
candidates.iter().map(|t| format!(
"{}{} {}{}",
param.name.ident().as_str(),
if impl_trait { " +" } else { ":" },
self.tcx.def_path_str(t.def_id),
if has_bounds.is_some() { " + "} else { "" },
)),
Applicability::MaybeIncorrect,
);
suggested = true;
}
Node::Item(hir::Item {
kind: hir::ItemKind::Trait(.., bounds, _), ident, ..
}) => {
let (sp, sep, article) = if bounds.is_empty() {
(ident.span.shrink_to_hi(), ":", "a")
} else {
(bounds.last().unwrap().span().shrink_to_hi(), " +", "another")
};
err.span_suggestions(
sp,
&message(format!("add {} supertrait for", article)),
candidates.iter().map(|t| format!(
"{} {}",
sep,
self.tcx.def_path_str(t.def_id),
)),
Applicability::MaybeIncorrect,
);
suggested = true;
}
_ => {}
}
let sp = hir.span(id);
// `sp` only covers `T`, change it so that it covers `T:` when appropriate.
let sp = if let Some(first_bound) = has_bounds {
sp.until(first_bound.span())
} else {
sp
};

// FIXME: contrast `t.def_id` against `param.bounds` to not suggest traits
// already there. That can happen when the cause is that we're in a const
// scope or associated function used as a method.
err.span_suggestions(
sp,
&msg[..],
candidates.iter().map(|t| format!(
"{}{} {}{}",
param,
if impl_trait { " +" } else { ":" },
self.tcx.def_path_str(t.def_id),
if has_bounds.is_some() { " + " } else { "" },
)),
Applicability::MaybeIncorrect,
);
suggested = true;
}
};
}

if !suggested {
let mut msg = message(if let Some(param) = param_type {
format!("restrict type parameter `{}` with", param)
} else {
"implement".to_string()
});
for (i, trait_info) in candidates.iter().enumerate() {
msg.push_str(&format!(
"\ncandidate #{}: `{}`",
Expand Down
47 changes: 47 additions & 0 deletions src/test/ui/suggestions/constrain-trait.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// run-rustfix
// check-only

#[derive(Debug)]
struct Demo {
a: String
}

trait GetString {
fn get_a(&self) -> &String;
}

trait UseString: std::fmt::Debug + GetString {
fn use_string(&self) {
println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found for type `&Self`
}
}

trait UseString2: GetString {
fn use_string(&self) {
println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found for type `&Self`
}
}

impl GetString for Demo {
fn get_a(&self) -> &String {
&self.a
}
}

impl UseString for Demo {}
impl UseString2 for Demo {}


#[cfg(test)]
mod tests {
use crate::{Demo, UseString};

#[test]
fn it_works() {
let d = Demo { a: "test".to_string() };
d.use_string();
}
}


fn main() {}
47 changes: 47 additions & 0 deletions src/test/ui/suggestions/constrain-trait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// run-rustfix
// check-only

#[derive(Debug)]
struct Demo {
a: String
}

trait GetString {
fn get_a(&self) -> &String;
}

trait UseString: std::fmt::Debug {
fn use_string(&self) {
println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found for type `&Self`
}
}

trait UseString2 {
fn use_string(&self) {
println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found for type `&Self`
}
}

impl GetString for Demo {
fn get_a(&self) -> &String {
&self.a
}
}

impl UseString for Demo {}
impl UseString2 for Demo {}


#[cfg(test)]
mod tests {
use crate::{Demo, UseString};

#[test]
fn it_works() {
let d = Demo { a: "test".to_string() };
d.use_string();
}
}


fn main() {}
27 changes: 27 additions & 0 deletions src/test/ui/suggestions/constrain-trait.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
error[E0599]: no method named `get_a` found for type `&Self` in the current scope
--> $DIR/constrain-trait.rs:15:31
|
LL | println!("{:?}", self.get_a());
| ^^^^^ method not found in `&Self`
|
= help: items from traits can only be used if the type parameter is bounded by the trait
help: the following trait defines an item `get_a`, perhaps you need to add another supertrait for it:
|
LL | trait UseString: std::fmt::Debug + GetString {
| ^^^^^^^^^^^

error[E0599]: no method named `get_a` found for type `&Self` in the current scope
--> $DIR/constrain-trait.rs:21:31
|
LL | println!("{:?}", self.get_a());
| ^^^^^ method not found in `&Self`
|
= help: items from traits can only be used if the type parameter is bounded by the trait
help: the following trait defines an item `get_a`, perhaps you need to add a supertrait for it:
|
LL | trait UseString2: GetString {
| ^^^^^^^^^^^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0599`.
0