diff options
| author | bors <bors@rust-lang.org> | 2021-10-27 18:42:13 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-10-27 18:42:13 +0000 |
| commit | 4e0d3973fafdfb1c51011bc74e44257b5e3863f1 (patch) | |
| tree | 6a7fe3cc445869485a6ce5f05c91cab291708bf0 /compiler | |
| parent | dd757b9e0622815be615addb3031770922b87874 (diff) | |
| parent | 623c3e144ef292f935e4d8603f7e512de6dc9d69 (diff) | |
| download | rust-4e0d3973fafdfb1c51011bc74e44257b5e3863f1.tar.gz rust-4e0d3973fafdfb1c51011bc74e44257b5e3863f1.zip | |
Auto merge of #90347 - matthiaskrgr:rollup-rp2ms7j, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #90239 (Consistent big O notation in map.rs) - #90267 (fix: inner attribute followed by outer attribute causing ICE) - #90288 (Add hint for people missing `TryFrom`, `TryInto`, `FromIterator` import pre-2021) - #90304 (Add regression test for #75961) - #90344 (Add tracking issue number to const_cstr_unchecked) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_ast/src/tokenstream.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/diagnostics.rs | 56 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/diagnostics.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/method/suggest.rs | 14 |
4 files changed, 64 insertions, 13 deletions
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 5d994dbad4d..51cabb50cd3 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -221,12 +221,6 @@ impl AttrAnnotatedTokenStream { for attr in &data.attrs { match attr.style { crate::AttrStyle::Outer => { - assert!( - inner_attrs.len() == 0, - "Found outer attribute {:?} after inner attrs {:?}", - attr, - inner_attrs - ); outer_attrs.push(attr); } crate::AttrStyle::Inner => { diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index f94266c3aea..ccfab263bd4 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -66,6 +66,8 @@ crate struct ImportSuggestion { pub descr: &'static str, pub path: Path, pub accessible: bool, + /// An extra note that should be issued if this item is suggested + pub note: Option<String>, } /// Adjust the impl span so that just the `impl` keyword is taken by removing @@ -872,11 +874,38 @@ impl<'a> Resolver<'a> { } if candidates.iter().all(|v: &ImportSuggestion| v.did != did) { + // See if we're recommending TryFrom, TryInto, or FromIterator and add + // a note about editions + let note = if let Some(did) = did { + let requires_note = !did.is_local() + && this.cstore().item_attrs(did, this.session).iter().any( + |attr| { + if attr.has_name(sym::rustc_diagnostic_item) { + [sym::TryInto, sym::TryFrom, sym::FromIterator] + .map(|x| Some(x)) + .contains(&attr.value_str()) + } else { + false + } + }, + ); + + requires_note.then(|| { + format!( + "'{}' is included in the prelude starting in Edition 2021", + path_names_to_string(&path) + ) + }) + } else { + None + }; + candidates.push(ImportSuggestion { did, descr: res.descr(), path, accessible: child_accessible, + note, }); } } @@ -1764,12 +1793,14 @@ crate fn show_candidates( return; } - let mut accessible_path_strings: Vec<(String, &str, Option<DefId>)> = Vec::new(); - let mut inaccessible_path_strings: Vec<(String, &str, Option<DefId>)> = Vec::new(); + let mut accessible_path_strings: Vec<(String, &str, Option<DefId>, &Option<String>)> = + Vec::new(); + let mut inaccessible_path_strings: Vec<(String, &str, Option<DefId>, &Option<String>)> = + Vec::new(); candidates.iter().for_each(|c| { (if c.accessible { &mut accessible_path_strings } else { &mut inaccessible_path_strings }) - .push((path_names_to_string(&c.path), c.descr, c.did)) + .push((path_names_to_string(&c.path), c.descr, c.did, &c.note)) }); // we want consistent results across executions, but candidates are produced @@ -1792,6 +1823,10 @@ crate fn show_candidates( let instead = if instead { " instead" } else { "" }; let mut msg = format!("consider importing {} {}{}", determiner, kind, instead); + for note in accessible_path_strings.iter().map(|cand| cand.3.as_ref()).flatten() { + err.note(note); + } + if let Some(span) = use_placement_span { for candidate in &mut accessible_path_strings { // produce an additional newline to separate the new use statement @@ -1820,7 +1855,7 @@ crate fn show_candidates( assert!(!inaccessible_path_strings.is_empty()); if inaccessible_path_strings.len() == 1 { - let (name, descr, def_id) = &inaccessible_path_strings[0]; + let (name, descr, def_id, note) = &inaccessible_path_strings[0]; let msg = format!("{} `{}` exists but is inaccessible", descr, name); if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) { @@ -1832,12 +1867,15 @@ crate fn show_candidates( } else { err.note(&msg); } + if let Some(note) = (*note).as_deref() { + err.note(note); + } } else { - let (_, descr_first, _) = &inaccessible_path_strings[0]; + let (_, descr_first, _, _) = &inaccessible_path_strings[0]; let descr = if inaccessible_path_strings .iter() .skip(1) - .all(|(_, descr, _)| descr == descr_first) + .all(|(_, descr, _, _)| descr == descr_first) { descr_first.to_string() } else { @@ -1848,7 +1886,7 @@ crate fn show_candidates( let mut has_colon = false; let mut spans = Vec::new(); - for (name, _, def_id) in &inaccessible_path_strings { + for (name, _, def_id, _) in &inaccessible_path_strings { if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) { let span = definitions.def_span(local_def_id); let span = session.source_map().guess_head_span(span); @@ -1868,6 +1906,10 @@ crate fn show_candidates( multi_span.push_span_label(span, format!("`{}`: not accessible", name)); } + for note in inaccessible_path_strings.iter().map(|cand| cand.3.as_ref()).flatten() { + err.note(note); + } + err.span_note(multi_span, &msg); } } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 1748a9be8e1..5f90fcdfa64 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1502,6 +1502,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { descr: "module", path, accessible: true, + note: None, }, )); } else { diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 183ebc559ae..28b19981c2d 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -1203,6 +1203,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut candidates = valid_out_of_scope_traits; candidates.sort(); candidates.dedup(); + + // `TryFrom` and `FromIterator` have no methods + let edition_fix = candidates + .iter() + .find(|did| self.tcx.is_diagnostic_item(sym::TryInto, **did)) + .map(|&d| d); + err.help("items from traits can only be used if the trait is in scope"); let msg = format!( "the following {traits_are} implemented but not in scope; \ @@ -1212,6 +1219,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); self.suggest_use_candidates(err, msg, candidates); + if let Some(did) = edition_fix { + err.note(&format!( + "'{}' is included in the prelude starting in Edition 2021", + with_crate_prefix(|| self.tcx.def_path_str(did)) + )); + } + true } else { false |
