diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-07 05:48:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-07 05:48:48 +0000 |
commit | ef24de24a82fe681581cc130f342363c47c0969a (patch) | |
tree | 0d494f7e1a38b95c92426f58fe6eaa877303a86c /compiler/rustc_hir_analysis/src/astconv/mod.rs | |
parent | Releasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip |
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_hir_analysis/src/astconv/mod.rs')
-rw-r--r-- | compiler/rustc_hir_analysis/src/astconv/mod.rs | 91 |
1 files changed, 66 insertions, 25 deletions
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 56b1fd369..2fcb45ef8 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -36,7 +36,7 @@ use rustc_middle::ty::{ use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::symbol::{kw, Ident, Symbol}; -use rustc_span::{sym, Span, DUMMY_SP}; +use rustc_span::{sym, BytePos, Span, DUMMY_SP}; use rustc_target::spec::abi; use rustc_trait_selection::traits::wf::object_region_bounds; use rustc_trait_selection::traits::{self, NormalizeExt, ObligationCtxt}; @@ -567,9 +567,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ); if let ty::BoundConstness::ConstIfConst = constness - && generics.has_self && !tcx.has_attr(def_id, sym::const_trait) + && generics.has_self + && !tcx.has_attr(def_id, sym::const_trait) { - tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span } ); + tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span }); } (args, arg_count) @@ -915,7 +916,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // Type aliases defined in crates that have the // feature `lazy_type_alias` enabled get encoded as a type alias that normalization will // then actually instantiate the where bounds of. - let alias_ty = tcx.mk_alias_ty(did, args); + let alias_ty = ty::AliasTy::new(tcx, did, args); Ty::new_alias(tcx, ty::Weak, alias_ty) } else { tcx.at(span).type_of(did).instantiate(tcx, args) @@ -1017,7 +1018,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } err.span_suggestions( span, - "use the fully-qualified path", + "use fully-qualified syntax", suggestions, Applicability::MachineApplicable, ); @@ -1061,6 +1062,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) }, param_name, + Some(ty_param_def_id), assoc_name, span, None, @@ -1074,6 +1076,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &self, all_candidates: impl Fn() -> I, ty_param_name: impl Display, + ty_param_def_id: Option<LocalDefId>, assoc_name: Ident, span: Span, is_equality: Option<ty::Term<'tcx>>, @@ -1088,13 +1091,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.trait_defines_associated_item_named(r.def_id(), ty::AssocKind::Const, assoc_name) }); - let (bound, next_cand) = match (matching_candidates.next(), const_candidates.next()) { + let (mut bound, mut next_cand) = match (matching_candidates.next(), const_candidates.next()) + { (Some(bound), _) => (bound, matching_candidates.next()), (None, Some(bound)) => (bound, const_candidates.next()), (None, None) => { let reported = self.complain_about_assoc_type_not_found( all_candidates, &ty_param_name.to_string(), + ty_param_def_id, assoc_name, span, ); @@ -1103,6 +1108,37 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }; debug!(?bound); + // look for a candidate that is not the same as our first bound, disregarding + // whether the bound is const. + while let Some(mut bound2) = next_cand { + debug!(?bound2); + let tcx = self.tcx(); + if bound2.bound_vars() != bound.bound_vars() { + break; + } + + let generics = tcx.generics_of(bound.def_id()); + let Some(host_index) = generics.host_effect_index else { break }; + + // always return the bound that contains the host param. + if let ty::ConstKind::Param(_) = bound2.skip_binder().args.const_at(host_index).kind() { + (bound, bound2) = (bound2, bound); + } + + let unconsted_args = bound + .skip_binder() + .args + .iter() + .enumerate() + .map(|(n, arg)| if host_index == n { tcx.consts.true_.into() } else { arg }); + + if unconsted_args.eq(bound2.skip_binder().args.iter()) { + next_cand = matching_candidates.next().or_else(|| const_candidates.next()); + } else { + break; + } + } + if let Some(bound2) = next_cand { debug!(?bound2); @@ -1142,30 +1178,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.span_label( bound_span, format!( - "ambiguous `{}` from `{}`", - assoc_name, + "ambiguous `{assoc_name}` from `{}`", bound.print_only_trait_path(), ), ); if let Some(constraint) = &is_equality { where_bounds.push(format!( - " T: {trait}::{assoc} = {constraint}", + " T: {trait}::{assoc_name} = {constraint}", trait=bound.print_only_trait_path(), - assoc=assoc_name, - constraint=constraint, )); } else { err.span_suggestion_verbose( span.with_hi(assoc_name.span.lo()), - "use fully qualified syntax to disambiguate", - format!("<{} as {}>::", ty_param_name, bound.print_only_trait_path()), + "use fully-qualified syntax to disambiguate", + format!("<{ty_param_name} as {}>::", bound.print_only_trait_path()), Applicability::MaybeIncorrect, ); } } else { err.note(format!( - "associated type `{}` could derive from `{}`", - ty_param_name, + "associated type `{ty_param_name}` could derive from `{}`", bound.print_only_trait_path(), )); } @@ -1173,8 +1205,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if !where_bounds.is_empty() { err.help(format!( "consider introducing a new type parameter `T` and adding `where` constraints:\ - \n where\n T: {},\n{}", - ty_param_name, + \n where\n T: {ty_param_name},\n{}", where_bounds.join(",\n"), )); } @@ -1275,8 +1306,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { return; }; // Get the span of the generics args *including* the leading `::`. - let args_span = - assoc_segment.ident.span.shrink_to_hi().to(args.span_ext); + // We do so by stretching args.span_ext to the left by 2. Earlier + // it was done based on the end of assoc segment but that sometimes + // led to impossible spans and caused issues like #116473 + let args_span = args.span_ext.with_lo(args.span_ext.lo() - BytePos(2)); if tcx.generics_of(adt_def.did()).count() == 0 { // FIXME(estebank): we could also verify that the arguments being // work for the `enum`, instead of just looking if it takes *any*. @@ -1394,6 +1427,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) }, kw::SelfUpper, + None, assoc_ident, span, None, @@ -1684,7 +1718,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .chain(args.into_iter().skip(parent_args.len())), ); - let ty = Ty::new_alias(tcx, ty::Inherent, tcx.mk_alias_ty(assoc_item, args)); + let ty = Ty::new_alias(tcx, ty::Inherent, ty::AliasTy::new(tcx, assoc_item, args)); return Ok(Some((ty, assoc_item))); } @@ -1917,9 +1951,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } else { Some(( match segment.res { - Res::PrimTy(ty) => format!("{} `{}`", segment.res.descr(), ty.name()), + Res::PrimTy(ty) => { + format!("{} `{}`", segment.res.descr(), ty.name()) + } Res::Def(_, def_id) - if let Some(name) = self.tcx().opt_item_name(def_id) => { + if let Some(name) = self.tcx().opt_item_name(def_id) => + { format!("{} `{name}`", segment.res.descr()) } Res::Err => "this type".to_string(), @@ -2249,7 +2286,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.note(msg); } for segment in path.segments { - if let Some(args) = segment.args && segment.ident.name == kw::SelfUpper { + if let Some(args) = segment.args + && segment.ident.name == kw::SelfUpper + { if generics == 0 { // FIXME(estebank): we could also verify that the arguments being // work for the `enum`, instead of just looking if it takes *any*. @@ -2631,7 +2670,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .iter() .enumerate() .map(|(i, a)| { - if let hir::TyKind::Infer = a.kind && !self.allow_ty_infer() { + if let hir::TyKind::Infer = a.kind + && !self.allow_ty_infer() + { if let Some(suggested_ty) = self.suggest_trait_fn_ty_for_impl_fn_infer(hir_id, Some(i)) { @@ -2660,7 +2701,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.ast_ty_to_ty(output) } } - hir::FnRetTy::DefaultReturn(..) => Ty::new_unit(tcx,), + hir::FnRetTy::DefaultReturn(..) => Ty::new_unit(tcx), }; debug!(?output_ty); |