Skip to content

Commit 9bee7f0

Browse files
committed
WIP: identify the case where we need to serialize path
1 parent dbc9da7 commit 9bee7f0

File tree

1 file changed

+40
-10
lines changed

1 file changed

+40
-10
lines changed

compiler/rustc_typeck/src/check/method/prelude2021.rs

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use hir::def_id::DefId;
22
use hir::HirId;
3+
use hir::ItemKind;
34
use rustc_ast::Mutability;
45
use rustc_errors::Applicability;
56
use rustc_hir as hir;
67
use rustc_middle::ty::Ty;
78
use rustc_session::lint::builtin::FUTURE_PRELUDE_COLLISION;
9+
use rustc_span::symbol::kw::Underscore;
810
use rustc_span::symbol::{sym, Ident};
911
use rustc_span::Span;
1012

@@ -51,7 +53,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5153
|lint| {
5254
let sp = call_expr.span;
5355
let trait_name =
54-
self.trait_path_or_bare_name(call_expr.hir_id, pick.item.container.id());
56+
self.trait_path_or_bare_name(span, call_expr.hir_id, pick.item.container.id());
5557

5658
let mut lint = lint.build(&format!(
5759
"trait method `{}` will become ambiguous in Rust 2021",
@@ -147,7 +149,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
147149
self.tcx.struct_span_lint_hir(FUTURE_PRELUDE_COLLISION, expr_id, span, |lint| {
148150
// "type" refers to either a type or, more likely, a trait from which
149151
// the associated function or method is from.
150-
let trait_path = self.trait_path_or_bare_name(expr_id, pick.item.container.id());
152+
let trait_path = self.trait_path_or_bare_name(span, expr_id, pick.item.container.id());
151153
let trait_generics = self.tcx.generics_of(pick.item.container.id());
152154

153155
let parameter_count = trait_generics.count() - (trait_generics.has_self as usize);
@@ -183,27 +185,55 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
183185
});
184186
}
185187

186-
fn trait_path_or_bare_name(&self, expr_hir_id: HirId, trait_def_id: DefId) -> String {
187-
self.trait_path(expr_hir_id, trait_def_id).unwrap_or_else(|| {
188+
fn trait_path_or_bare_name(
189+
&self,
190+
span: Span,
191+
expr_hir_id: HirId,
192+
trait_def_id: DefId,
193+
) -> String {
194+
self.trait_path(span, expr_hir_id, trait_def_id).unwrap_or_else(|| {
188195
let key = self.tcx.def_key(trait_def_id);
189196
format!("{}", key.disambiguated_data.data)
190197
})
191198
}
192199

193-
fn trait_path(&self, expr_hir_id: HirId, trait_def_id: DefId) -> Option<String> {
200+
fn trait_path(&self, span: Span, expr_hir_id: HirId, trait_def_id: DefId) -> Option<String> {
194201
let applicable_traits = self.tcx.in_scope_traits(expr_hir_id)?;
195202
let applicable_trait = applicable_traits.iter().find(|t| t.def_id == trait_def_id)?;
196203
if applicable_trait.import_ids.is_empty() {
197204
// The trait was declared within the module, we only need to use its name.
198205
return None;
199206
}
200207

201-
for &import_id in &applicable_trait.import_ids {
202-
let hir_id = self.tcx.hir().local_def_id_to_hir_id(import_id);
203-
let item = self.tcx.hir().expect_item(hir_id);
204-
debug!(?item, ?import_id, "import_id");
208+
let import_items: Vec<_> = applicable_trait
209+
.import_ids
210+
.iter()
211+
.map(|&import_id| {
212+
let hir_id = self.tcx.hir().local_def_id_to_hir_id(import_id);
213+
self.tcx.hir().expect_item(hir_id)
214+
})
215+
.collect();
216+
217+
// Find an identifier with which this trait was imported (note that `_` doesn't count).
218+
let any_id = import_items
219+
.iter()
220+
.filter_map(|item| if item.ident.name != Underscore { Some(item.ident) } else { None })
221+
.next();
222+
if let Some(any_id) = any_id {
223+
return Some(format!("{}", any_id));
205224
}
206225

207-
return None;
226+
// All that is left is `_`! We need to use the full path. It doesn't matter which one we pick,
227+
// so just take the first one.
228+
match import_items[0].kind {
229+
ItemKind::Use(path, _) => {
230+
// FIXME: serialize path into something readable like a::b, there must be a fn for this
231+
debug!("no name for trait, found import of path: {:?}", path);
232+
return None;
233+
}
234+
_ => {
235+
span_bug!(span, "unexpected item kind, expected a use: {:?}", import_items[0].kind);
236+
}
237+
}
208238
}
209239
}

0 commit comments

Comments
 (0)