Skip to content

Commit 0da05e9

Browse files
committed
Auto merge of rust-lang#121244 - GuillaumeGomez:rollup-995gu7o, r=GuillaumeGomez
Rollup of 7 pull requests Successful merges: - rust-lang#118264 (Optimize `VecDeque::drain` for (half-)open ranges) - rust-lang#121079 (distribute tool documentations and avoid file conflicts on `x install`) - rust-lang#121100 (Detect when method call on argument could be removed to fulfill failed trait bound) - rust-lang#121160 (rustdoc: fix and refactor HTML rendering a bit) - rust-lang#121198 (Add more checks for `unnamed_fields` during HIR analysis) - rust-lang#121221 (AstConv: Refactor lowering of associated item bindings a bit) - rust-lang#121237 (Use better heuristic for printing Cargo specific diagnostics) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 6672c16 + e033e40 commit 0da05e9

File tree

34 files changed

+765
-541
lines changed

34 files changed

+765
-541
lines changed

compiler/rustc_codegen_ssa/src/errors.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,11 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for LinkingFailed<'_> {
362362
// which by now we have no way to translate.
363363
if contains_undefined_ref {
364364
diag.note(fluent::codegen_ssa_extern_funcs_not_found)
365-
.note(fluent::codegen_ssa_specify_libraries_to_link)
366-
.note(fluent::codegen_ssa_use_cargo_directive);
365+
.note(fluent::codegen_ssa_specify_libraries_to_link);
366+
367+
if rustc_session::utils::was_invoked_from_cargo() {
368+
diag.note(fluent::codegen_ssa_use_cargo_directive);
369+
}
367370
}
368371
diag
369372
}

compiler/rustc_hir/src/hir.rs

+6
Original file line numberDiff line numberDiff line change
@@ -2998,6 +2998,12 @@ impl<'hir> Item<'hir> {
29982998
ItemId { owner_id: self.owner_id }
29992999
}
30003000

3001+
/// Check if this is an [`ItemKind::Enum`], [`ItemKind::Struct`] or
3002+
/// [`ItemKind::Union`].
3003+
pub fn is_adt(&self) -> bool {
3004+
matches!(self.kind, ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..))
3005+
}
3006+
30013007
expect_methods_self_kind! {
30023008
expect_extern_crate, Option<Symbol>, ItemKind::ExternCrate(s), *s;
30033009

compiler/rustc_hir_analysis/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ hir_analysis_invalid_union_field =
198198
hir_analysis_invalid_union_field_sugg =
199199
wrap the field type in `ManuallyDrop<...>`
200200
201+
hir_analysis_invalid_unnamed_field_ty = unnamed fields can only have struct or union types
202+
201203
hir_analysis_late_bound_const_in_apit = `impl Trait` can only mention const parameters from an fn or impl
202204
.label = const parameter declared here
203205

compiler/rustc_hir_analysis/src/astconv/bounds.rs

+83-81
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ use rustc_span::{ErrorGuaranteed, Span};
99
use rustc_trait_selection::traits;
1010
use smallvec::SmallVec;
1111

12-
use crate::astconv::{
13-
AstConv, ConvertedBinding, ConvertedBindingKind, OnlySelfBounds, PredicateFilter,
14-
};
12+
use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter};
1513
use crate::bounds::Bounds;
1614
use crate::errors;
1715

@@ -238,7 +236,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
238236
&self,
239237
hir_ref_id: hir::HirId,
240238
trait_ref: ty::PolyTraitRef<'tcx>,
241-
binding: &ConvertedBinding<'_, 'tcx>,
239+
binding: &hir::TypeBinding<'tcx>,
242240
bounds: &mut Bounds<'tcx>,
243241
speculative: bool,
244242
dup_bindings: &mut FxIndexMap<DefId, Span>,
@@ -263,21 +261,20 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
263261

264262
let tcx = self.tcx();
265263

266-
let assoc_kind =
267-
if binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation {
268-
ty::AssocKind::Fn
269-
} else if let ConvertedBindingKind::Equality(term) = binding.kind
270-
&& let ty::TermKind::Const(_) = term.node.unpack()
271-
{
272-
ty::AssocKind::Const
273-
} else {
274-
ty::AssocKind::Type
275-
};
264+
let assoc_kind = if binding.gen_args.parenthesized
265+
== hir::GenericArgsParentheses::ReturnTypeNotation
266+
{
267+
ty::AssocKind::Fn
268+
} else if let hir::TypeBindingKind::Equality { term: hir::Term::Const(_) } = binding.kind {
269+
ty::AssocKind::Const
270+
} else {
271+
ty::AssocKind::Type
272+
};
276273

277274
let candidate = if self.trait_defines_associated_item_named(
278275
trait_ref.def_id(),
279276
assoc_kind,
280-
binding.item_name,
277+
binding.ident,
281278
) {
282279
// Simple case: The assoc item is defined in the current trait.
283280
trait_ref
@@ -289,14 +286,14 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
289286
trait_ref.skip_binder().print_only_trait_name(),
290287
None,
291288
assoc_kind,
292-
binding.item_name,
289+
binding.ident,
293290
path_span,
294-
Some(&binding),
291+
Some(binding),
295292
)?
296293
};
297294

298295
let (assoc_ident, def_scope) =
299-
tcx.adjust_ident_and_get_scope(binding.item_name, candidate.def_id(), hir_ref_id);
296+
tcx.adjust_ident_and_get_scope(binding.ident, candidate.def_id(), hir_ref_id);
300297

301298
// We have already adjusted the item name above, so compare with `.normalize_to_macros_2_0()`
302299
// instead of calling `filter_by_name_and_kind` which would needlessly normalize the
@@ -312,7 +309,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
312309
.dcx()
313310
.struct_span_err(
314311
binding.span,
315-
format!("{} `{}` is private", assoc_item.kind, binding.item_name),
312+
format!("{} `{}` is private", assoc_item.kind, binding.ident),
316313
)
317314
.with_span_label(binding.span, format!("private {}", assoc_item.kind))
318315
.emit();
@@ -327,7 +324,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
327324
tcx.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified {
328325
span: binding.span,
329326
prev_span: *prev_span,
330-
item_name: binding.item_name,
327+
item_name: binding.ident,
331328
def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
332329
});
333330
})
@@ -390,14 +387,12 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
390387
{
391388
alias_ty
392389
} else {
393-
return Err(self.tcx().dcx().emit_err(
394-
crate::errors::ReturnTypeNotationOnNonRpitit {
395-
span: binding.span,
396-
ty: tcx.liberate_late_bound_regions(assoc_item.def_id, output),
397-
fn_span: tcx.hir().span_if_local(assoc_item.def_id),
398-
note: (),
399-
},
400-
));
390+
return Err(tcx.dcx().emit_err(crate::errors::ReturnTypeNotationOnNonRpitit {
391+
span: binding.span,
392+
ty: tcx.liberate_late_bound_regions(assoc_item.def_id, output),
393+
fn_span: tcx.hir().span_if_local(assoc_item.def_id),
394+
note: (),
395+
}));
401396
};
402397

403398
// Finally, move the fn return type's bound vars over to account for the early bound
@@ -410,9 +405,11 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
410405
let bound_vars = tcx.late_bound_vars(binding.hir_id);
411406
ty::Binder::bind_with_vars(instantiation_output, bound_vars)
412407
} else {
413-
// Append the generic arguments of the associated type to the `trait_ref`.
408+
// Create the generic arguments for the associated type or constant by joining the
409+
// parent arguments (the arguments of the trait) and the own arguments (the ones of
410+
// the associated item itself) and construct an alias type using them.
414411
candidate.map_bound(|trait_ref| {
415-
let ident = Ident::new(assoc_item.name, binding.item_name.span);
412+
let ident = Ident::new(assoc_item.name, binding.ident.span);
416413
let item_segment = hir::PathSegment {
417414
ident,
418415
hir_id: binding.hir_id,
@@ -421,77 +418,82 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
421418
infer_args: false,
422419
};
423420

424-
let args_trait_ref_and_assoc_item = self.create_args_for_associated_item(
421+
let alias_args = self.create_args_for_associated_item(
425422
path_span,
426423
assoc_item.def_id,
427424
&item_segment,
428425
trait_ref.args,
429426
);
427+
debug!(?alias_args);
430428

431-
debug!(?args_trait_ref_and_assoc_item);
432-
433-
ty::AliasTy::new(tcx, assoc_item.def_id, args_trait_ref_and_assoc_item)
429+
// Note that we're indeed also using `AliasTy` (alias *type*) for associated
430+
// *constants* to represent *const projections*. Alias *term* would be a more
431+
// appropriate name but alas.
432+
ty::AliasTy::new(tcx, assoc_item.def_id, alias_args)
434433
})
435434
};
436435

437-
if !speculative {
438-
// Find any late-bound regions declared in `ty` that are not
439-
// declared in the trait-ref or assoc_item. These are not well-formed.
440-
//
441-
// Example:
442-
//
443-
// for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
444-
// for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
445-
if let ConvertedBindingKind::Equality(ty) = binding.kind {
446-
let late_bound_in_trait_ref =
447-
tcx.collect_constrained_late_bound_regions(&projection_ty);
448-
let late_bound_in_ty =
449-
tcx.collect_referenced_late_bound_regions(&trait_ref.rebind(ty.node));
450-
debug!(?late_bound_in_trait_ref);
451-
debug!(?late_bound_in_ty);
452-
453-
// FIXME: point at the type params that don't have appropriate lifetimes:
454-
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
455-
// ---- ---- ^^^^^^^
456-
self.validate_late_bound_regions(
457-
late_bound_in_trait_ref,
458-
late_bound_in_ty,
459-
|br_name| {
460-
struct_span_code_err!(
461-
tcx.dcx(),
462-
binding.span,
463-
E0582,
464-
"binding for associated type `{}` references {}, \
465-
which does not appear in the trait input types",
466-
binding.item_name,
467-
br_name
468-
)
469-
},
470-
);
471-
}
472-
}
473-
474436
match binding.kind {
475-
ConvertedBindingKind::Equality(..) if let ty::AssocKind::Fn = assoc_kind => {
476-
return Err(self.tcx().dcx().emit_err(
477-
crate::errors::ReturnTypeNotationEqualityBound { span: binding.span },
478-
));
437+
hir::TypeBindingKind::Equality { .. } if let ty::AssocKind::Fn = assoc_kind => {
438+
return Err(tcx.dcx().emit_err(crate::errors::ReturnTypeNotationEqualityBound {
439+
span: binding.span,
440+
}));
479441
}
480-
ConvertedBindingKind::Equality(term) => {
442+
hir::TypeBindingKind::Equality { term } => {
443+
let term = match term {
444+
hir::Term::Ty(ty) => self.ast_ty_to_ty(ty).into(),
445+
hir::Term::Const(ct) => ty::Const::from_anon_const(tcx, ct.def_id).into(),
446+
};
447+
448+
if !speculative {
449+
// Find any late-bound regions declared in `ty` that are not
450+
// declared in the trait-ref or assoc_item. These are not well-formed.
451+
//
452+
// Example:
453+
//
454+
// for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
455+
// for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
456+
let late_bound_in_projection_ty =
457+
tcx.collect_constrained_late_bound_regions(&projection_ty);
458+
let late_bound_in_term =
459+
tcx.collect_referenced_late_bound_regions(&trait_ref.rebind(term));
460+
debug!(?late_bound_in_projection_ty);
461+
debug!(?late_bound_in_term);
462+
463+
// FIXME: point at the type params that don't have appropriate lifetimes:
464+
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
465+
// ---- ---- ^^^^^^^
466+
// NOTE(associated_const_equality): This error should be impossible to trigger
467+
// with associated const equality bounds.
468+
self.validate_late_bound_regions(
469+
late_bound_in_projection_ty,
470+
late_bound_in_term,
471+
|br_name| {
472+
struct_span_code_err!(
473+
tcx.dcx(),
474+
binding.span,
475+
E0582,
476+
"binding for associated type `{}` references {}, \
477+
which does not appear in the trait input types",
478+
binding.ident,
479+
br_name
480+
)
481+
},
482+
);
483+
}
484+
481485
// "Desugar" a constraint like `T: Iterator<Item = u32>` this to
482486
// the "projection predicate" for:
483487
//
484488
// `<T as Iterator>::Item = u32`
485489
bounds.push_projection_bound(
486490
tcx,
487-
projection_ty.map_bound(|projection_ty| ty::ProjectionPredicate {
488-
projection_ty,
489-
term: term.node,
490-
}),
491+
projection_ty
492+
.map_bound(|projection_ty| ty::ProjectionPredicate { projection_ty, term }),
491493
binding.span,
492494
);
493495
}
494-
ConvertedBindingKind::Constraint(ast_bounds) => {
496+
hir::TypeBindingKind::Constraint { bounds: ast_bounds } => {
495497
// "Desugar" a constraint like `T: Iterator<Item: Debug>` to
496498
//
497499
// `<T as Iterator>::Item: Debug`

compiler/rustc_hir_analysis/src/astconv/errors.rs

+25-20
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::astconv::{AstConv, ConvertedBindingKind};
1+
use crate::astconv::AstConv;
22
use crate::errors::{
33
self, AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams,
44
ParenthesizedFnTraitExpansion,
@@ -111,7 +111,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
111111
assoc_kind: ty::AssocKind,
112112
assoc_name: Ident,
113113
span: Span,
114-
binding: Option<&super::ConvertedBinding<'_, 'tcx>>,
114+
binding: Option<&hir::TypeBinding<'tcx>>,
115115
) -> ErrorGuaranteed
116116
where
117117
I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
@@ -243,7 +243,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
243243
None,
244244
) && suggested_name != assoc_name.name
245245
{
246-
// We suggested constraining a type parameter, but the associated type on it
246+
// We suggested constraining a type parameter, but the associated item on it
247247
// was also not an exact match, so we also suggest changing it.
248248
err.span_suggestion_verbose(
249249
assoc_name.span,
@@ -258,16 +258,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
258258
}
259259
}
260260

261-
// If we still couldn't find any associated type, and only one associated type exists,
261+
// If we still couldn't find any associated item, and only one associated item exists,
262262
// suggests using it.
263263
if let [candidate_name] = all_candidate_names.as_slice() {
264-
// this should still compile, except on `#![feature(associated_type_defaults)]`
265-
// where it could suggests `type A = Self::A`, thus recursing infinitely
266-
let applicability = if tcx.features().associated_type_defaults {
267-
Applicability::Unspecified
268-
} else {
269-
Applicability::MaybeIncorrect
270-
};
264+
// This should still compile, except on `#![feature(associated_type_defaults)]`
265+
// where it could suggests `type A = Self::A`, thus recursing infinitely.
266+
let applicability =
267+
if assoc_kind == ty::AssocKind::Type && tcx.features().associated_type_defaults {
268+
Applicability::Unspecified
269+
} else {
270+
Applicability::MaybeIncorrect
271+
};
271272

272273
err.sugg = Some(errors::AssocItemNotFoundSugg::Other {
273274
span: assoc_name.span,
@@ -289,13 +290,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
289290
assoc_kind: ty::AssocKind,
290291
ident: Ident,
291292
span: Span,
292-
binding: Option<&super::ConvertedBinding<'_, 'tcx>>,
293+
binding: Option<&hir::TypeBinding<'tcx>>,
293294
) -> ErrorGuaranteed {
294295
let tcx = self.tcx();
295296

296297
let bound_on_assoc_const_label = if let ty::AssocKind::Const = assoc_item.kind
297298
&& let Some(binding) = binding
298-
&& let ConvertedBindingKind::Constraint(_) = binding.kind
299+
&& let hir::TypeBindingKind::Constraint { .. } = binding.kind
299300
{
300301
let lo = if binding.gen_args.span_ext.is_dummy() {
301302
ident.span
@@ -309,25 +310,29 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
309310

310311
// FIXME(associated_const_equality): This has quite a few false positives and negatives.
311312
let wrap_in_braces_sugg = if let Some(binding) = binding
312-
&& let ConvertedBindingKind::Equality(term) = binding.kind
313-
&& let ty::TermKind::Ty(ty) = term.node.unpack()
313+
&& let hir::TypeBindingKind::Equality { term: hir::Term::Ty(hir_ty) } = binding.kind
314+
&& let ty = self.ast_ty_to_ty(hir_ty)
314315
&& (ty.is_enum() || ty.references_error())
315316
&& tcx.features().associated_const_equality
316317
{
317318
Some(errors::AssocKindMismatchWrapInBracesSugg {
318-
lo: term.span.shrink_to_lo(),
319-
hi: term.span.shrink_to_hi(),
319+
lo: hir_ty.span.shrink_to_lo(),
320+
hi: hir_ty.span.shrink_to_hi(),
320321
})
321322
} else {
322323
None
323324
};
324325

325326
// For equality bounds, we want to blame the term (RHS) instead of the item (LHS) since
326-
// one can argue that that's more “untuitive” to the user.
327+
// one can argue that that's more “intuitive” to the user.
327328
let (span, expected_because_label, expected, got) = if let Some(binding) = binding
328-
&& let ConvertedBindingKind::Equality(term) = binding.kind
329+
&& let hir::TypeBindingKind::Equality { term } = binding.kind
329330
{
330-
(term.span, Some(ident.span), assoc_item.kind, assoc_kind)
331+
let span = match term {
332+
hir::Term::Ty(ty) => ty.span,
333+
hir::Term::Const(ct) => tcx.def_span(ct.def_id),
334+
};
335+
(span, Some(ident.span), assoc_item.kind, assoc_kind)
331336
} else {
332337
(ident.span, None, assoc_kind, assoc_item.kind)
333338
};

0 commit comments

Comments
 (0)