summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_analysis/src/astconv/mod.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
commitef24de24a82fe681581cc130f342363c47c0969a (patch)
tree0d494f7e1a38b95c92426f58fe6eaa877303a86c /compiler/rustc_hir_analysis/src/astconv/mod.rs
parentReleasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-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.rs91
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);