Skip to content

Commit 226b249

Browse files
committed
Auto merge of rust-lang#107400 - matthiaskrgr:rollup-l6bycds, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#107022 (Implement `SpecOptionPartialEq` for `cmp::Ordering`) - rust-lang#107100 (Use proper `InferCtxt` when probing for associated types in astconv) - rust-lang#107103 (Use new solver in `evaluate_obligation` query (when new solver is enabled)) - rust-lang#107190 (Recover from more const arguments that are not wrapped in curly braces) - rust-lang#107306 (Correct suggestions for closure arguments that need a borrow) - rust-lang#107339 (internally change regions to be covariant) - rust-lang#107344 (Minor tweaks in the new solver) - rust-lang#107373 (Don't merge vtables when full debuginfo is enabled.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 2527416 + c89bb15 commit 226b249

39 files changed

+531
-160
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1499,6 +1499,11 @@ pub fn create_vtable_di_node<'ll, 'tcx>(
14991499
return;
15001500
}
15011501

1502+
// When full debuginfo is enabled, we want to try and prevent vtables from being
1503+
// merged. Otherwise debuggers will have a hard time mapping from dyn pointer
1504+
// to concrete type.
1505+
llvm::SetUnnamedAddress(vtable, llvm::UnnamedAddr::No);
1506+
15021507
let vtable_name =
15031508
compute_debuginfo_vtable_name(cx.tcx, ty, poly_trait_ref, VTableNameKind::GlobalVariable);
15041509
let vtable_type_di_node = build_vtable_type_di_node(cx, ty, poly_trait_ref);

compiler/rustc_hir_analysis/src/astconv/mod.rs

+61-45
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
2727
use rustc_hir::def_id::{DefId, LocalDefId};
2828
use rustc_hir::intravisit::{walk_generics, Visitor as _};
2929
use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
30-
use rustc_infer::infer::TyCtxtInferExt;
30+
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
3131
use rustc_middle::middle::stability::AllowUnstable;
3232
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
3333
use rustc_middle::ty::GenericParamDefKind;
@@ -37,7 +37,7 @@ use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECT
3737
use rustc_span::edition::Edition;
3838
use rustc_span::lev_distance::find_best_match_for_name;
3939
use rustc_span::symbol::{kw, Ident, Symbol};
40-
use rustc_span::{sym, Span};
40+
use rustc_span::{sym, Span, DUMMY_SP};
4141
use rustc_target::spec::abi;
4242
use rustc_trait_selection::traits;
4343
use rustc_trait_selection::traits::astconv_object_safety_violations;
@@ -54,7 +54,7 @@ use std::slice;
5454
pub struct PathSeg(pub DefId, pub usize);
5555

5656
pub trait AstConv<'tcx> {
57-
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
57+
fn tcx(&self) -> TyCtxt<'tcx>;
5858

5959
fn item_def_id(&self) -> DefId;
6060

@@ -131,6 +131,8 @@ pub trait AstConv<'tcx> {
131131
{
132132
self
133133
}
134+
135+
fn infcx(&self) -> Option<&InferCtxt<'tcx>>;
134136
}
135137

136138
#[derive(Debug)]
@@ -2132,48 +2134,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
21322134
)
21332135
.emit() // Already reported in an earlier stage.
21342136
} else {
2135-
// Find all the `impl`s that `qself_ty` has for any trait that has the
2136-
// associated type, so that we suggest the right one.
2137-
let infcx = tcx.infer_ctxt().build();
2138-
// We create a fresh `ty::ParamEnv` instead of the one for `self.item_def_id()`
2139-
// to avoid a cycle error in `src/test/ui/resolve/issue-102946.rs`.
2140-
let param_env = ty::ParamEnv::empty();
2141-
let traits: Vec<_> = self
2142-
.tcx()
2143-
.all_traits()
2144-
.filter(|trait_def_id| {
2145-
// Consider only traits with the associated type
2146-
tcx.associated_items(*trait_def_id)
2147-
.in_definition_order()
2148-
.any(|i| {
2149-
i.kind.namespace() == Namespace::TypeNS
2150-
&& i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
2151-
&& matches!(i.kind, ty::AssocKind::Type)
2152-
})
2153-
// Consider only accessible traits
2154-
&& tcx.visibility(*trait_def_id)
2155-
.is_accessible_from(self.item_def_id(), tcx)
2156-
&& tcx.all_impls(*trait_def_id)
2157-
.any(|impl_def_id| {
2158-
let trait_ref = tcx.impl_trait_ref(impl_def_id);
2159-
trait_ref.map_or(false, |trait_ref| {
2160-
let impl_ = trait_ref.subst(
2161-
tcx,
2162-
infcx.fresh_substs_for_item(span, impl_def_id),
2163-
);
2164-
infcx
2165-
.can_eq(
2166-
param_env,
2167-
tcx.erase_regions(impl_.self_ty()),
2168-
tcx.erase_regions(qself_ty),
2169-
)
2170-
.is_ok()
2171-
})
2172-
&& tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative
2173-
})
2174-
})
2175-
.map(|trait_def_id| tcx.def_path_str(trait_def_id))
2176-
.collect();
2137+
let traits: Vec<_> =
2138+
self.probe_traits_that_match_assoc_ty(qself_ty, assoc_ident);
21772139

21782140
// Don't print `TyErr` to the user.
21792141
self.report_ambiguous_associated_type(
@@ -2232,6 +2194,60 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
22322194
Ok((ty, DefKind::AssocTy, assoc_ty_did))
22332195
}
22342196

2197+
fn probe_traits_that_match_assoc_ty(
2198+
&self,
2199+
qself_ty: Ty<'tcx>,
2200+
assoc_ident: Ident,
2201+
) -> Vec<String> {
2202+
let tcx = self.tcx();
2203+
2204+
// In contexts that have no inference context, just make a new one.
2205+
// We do need a local variable to store it, though.
2206+
let infcx_;
2207+
let infcx = if let Some(infcx) = self.infcx() {
2208+
infcx
2209+
} else {
2210+
assert!(!qself_ty.needs_infer());
2211+
infcx_ = tcx.infer_ctxt().build();
2212+
&infcx_
2213+
};
2214+
2215+
tcx.all_traits()
2216+
.filter(|trait_def_id| {
2217+
// Consider only traits with the associated type
2218+
tcx.associated_items(*trait_def_id)
2219+
.in_definition_order()
2220+
.any(|i| {
2221+
i.kind.namespace() == Namespace::TypeNS
2222+
&& i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
2223+
&& matches!(i.kind, ty::AssocKind::Type)
2224+
})
2225+
// Consider only accessible traits
2226+
&& tcx.visibility(*trait_def_id)
2227+
.is_accessible_from(self.item_def_id(), tcx)
2228+
&& tcx.all_impls(*trait_def_id)
2229+
.any(|impl_def_id| {
2230+
let trait_ref = tcx.impl_trait_ref(impl_def_id);
2231+
trait_ref.map_or(false, |trait_ref| {
2232+
let impl_ = trait_ref.subst(
2233+
tcx,
2234+
infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id),
2235+
);
2236+
infcx
2237+
.can_eq(
2238+
ty::ParamEnv::empty(),
2239+
tcx.erase_regions(impl_.self_ty()),
2240+
tcx.erase_regions(qself_ty),
2241+
)
2242+
.is_ok()
2243+
})
2244+
&& tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative
2245+
})
2246+
})
2247+
.map(|trait_def_id| tcx.def_path_str(trait_def_id))
2248+
.collect()
2249+
}
2250+
22352251
fn lookup_assoc_ty(
22362252
&self,
22372253
ident: Ident,

compiler/rustc_hir_analysis/src/collect.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use rustc_hir as hir;
2525
use rustc_hir::def_id::{DefId, LocalDefId};
2626
use rustc_hir::intravisit::{self, Visitor};
2727
use rustc_hir::{GenericParamKind, Node};
28-
use rustc_infer::infer::TyCtxtInferExt;
28+
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
2929
use rustc_infer::traits::ObligationCause;
3030
use rustc_middle::hir::nested_filter;
3131
use rustc_middle::ty::query::Providers;
@@ -517,6 +517,10 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
517517
fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) {
518518
// There's no place to record types from signatures?
519519
}
520+
521+
fn infcx(&self) -> Option<&InferCtxt<'tcx>> {
522+
None
523+
}
520524
}
521525

522526
/// Synthesize a new lifetime name that doesn't clash with any of the lifetimes already present.

compiler/rustc_hir_analysis/src/variance/constraints.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
225225
}
226226

227227
ty::Ref(region, ty, mutbl) => {
228-
let contra = self.contravariant(variance);
229-
self.add_constraints_from_region(current, region, contra);
228+
self.add_constraints_from_region(current, region, variance);
230229
self.add_constraints_from_mt(current, &ty::TypeAndMut { ty, mutbl }, variance);
231230
}
232231

@@ -258,9 +257,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
258257
}
259258

260259
ty::Dynamic(data, r, _) => {
261-
// The type `Foo<T+'a>` is contravariant w/r/t `'a`:
262-
let contra = self.contravariant(variance);
263-
self.add_constraints_from_region(current, r, contra);
260+
// The type `dyn Trait<T> +'a` is covariant w/r/t `'a`:
261+
self.add_constraints_from_region(current, r, variance);
264262

265263
if let Some(poly_trait_ref) = data.principal() {
266264
self.add_constraints_from_invariant_substs(

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,10 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
324324
let ty = if !ty.has_escaping_bound_vars() { self.normalize(span, ty) } else { ty };
325325
self.write_ty(hir_id, ty)
326326
}
327+
328+
fn infcx(&self) -> Option<&infer::InferCtxt<'tcx>> {
329+
Some(&self.infcx)
330+
}
327331
}
328332

329333
/// Represents a user-provided type in the raw form (never normalized).

compiler/rustc_infer/src/infer/glb.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
7979
debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
8080

8181
let origin = Subtype(Box::new(self.fields.trace.clone()));
82-
Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().glb_regions(
82+
// GLB(&'static u8, &'a u8) == &RegionLUB('static, 'a) u8 == &'static u8
83+
Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().lub_regions(
8384
self.tcx(),
8485
origin,
8586
a,

compiler/rustc_infer/src/infer/lub.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
7979
debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
8080

8181
let origin = Subtype(Box::new(self.fields.trace.clone()));
82-
Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().lub_regions(
82+
// LUB(&'static u8, &'a u8) == &RegionGLB('static, 'a) u8 == &'a u8
83+
Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().glb_regions(
8384
self.tcx(),
8485
origin,
8586
a,

compiler/rustc_infer/src/infer/nll_relate/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -663,13 +663,13 @@ where
663663
debug!(?v_b);
664664

665665
if self.ambient_covariance() {
666-
// Covariance: a <= b. Hence, `b: a`.
667-
self.push_outlives(v_b, v_a, self.ambient_variance_info);
666+
// Covariant: &'a u8 <: &'b u8. Hence, `'a: 'b`.
667+
self.push_outlives(v_a, v_b, self.ambient_variance_info);
668668
}
669669

670670
if self.ambient_contravariance() {
671-
// Contravariant: b <= a. Hence, `a: b`.
672-
self.push_outlives(v_a, v_b, self.ambient_variance_info);
671+
// Contravariant: &'b u8 <: &'a u8. Hence, `'b: 'a`.
672+
self.push_outlives(v_b, v_a, self.ambient_variance_info);
673673
}
674674

675675
Ok(a)

compiler/rustc_infer/src/infer/sub.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,13 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
191191
// from the "cause" field, we could perhaps give more tailored
192192
// error messages.
193193
let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
194+
// Subtype(&'a u8, &'b u8) => Outlives('a: 'b) => SubRegion('b, 'a)
194195
self.fields
195196
.infcx
196197
.inner
197198
.borrow_mut()
198199
.unwrap_region_constraints()
199-
.make_subregion(origin, a, b);
200+
.make_subregion(origin, b, a);
200201

201202
Ok(a)
202203
}

compiler/rustc_middle/src/ty/relate.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -443,12 +443,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
443443
if a_repr == b_repr =>
444444
{
445445
let region_bound = relation.with_cause(Cause::ExistentialRegionBound, |relation| {
446-
relation.relate_with_variance(
447-
ty::Contravariant,
448-
ty::VarianceDiagInfo::default(),
449-
a_region,
450-
b_region,
451-
)
446+
relation.relate(a_region, b_region)
452447
})?;
453448
Ok(tcx.mk_dynamic(relation.relate(a_obj, b_obj)?, region_bound, a_repr))
454449
}
@@ -497,12 +492,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
497492
}
498493

499494
(&ty::Ref(a_r, a_ty, a_mutbl), &ty::Ref(b_r, b_ty, b_mutbl)) => {
500-
let r = relation.relate_with_variance(
501-
ty::Contravariant,
502-
ty::VarianceDiagInfo::default(),
503-
a_r,
504-
b_r,
505-
)?;
495+
let r = relation.relate(a_r, b_r)?;
506496
let a_mt = ty::TypeAndMut { ty: a_ty, mutbl: a_mutbl };
507497
let b_mt = ty::TypeAndMut { ty: b_ty, mutbl: b_mutbl };
508498
let mt = relate_type_and_mut(relation, a_mt, b_mt, a)?;

compiler/rustc_parse/src/parser/diagnostics.rs

+22
Original file line numberDiff line numberDiff line change
@@ -2353,6 +2353,28 @@ impl<'a> Parser<'a> {
23532353
Err(err)
23542354
}
23552355

2356+
/// Try to recover from an unbraced const argument whose first token [could begin a type][ty].
2357+
///
2358+
/// [ty]: token::Token::can_begin_type
2359+
pub(crate) fn recover_unbraced_const_arg_that_can_begin_ty(
2360+
&mut self,
2361+
mut snapshot: SnapshotParser<'a>,
2362+
) -> Option<P<ast::Expr>> {
2363+
match snapshot.parse_expr_res(Restrictions::CONST_EXPR, None) {
2364+
// Since we don't know the exact reason why we failed to parse the type or the
2365+
// expression, employ a simple heuristic to weed out some pathological cases.
2366+
Ok(expr) if let token::Comma | token::Gt = snapshot.token.kind => {
2367+
self.restore_snapshot(snapshot);
2368+
Some(expr)
2369+
}
2370+
Ok(_) => None,
2371+
Err(err) => {
2372+
err.cancel();
2373+
None
2374+
}
2375+
}
2376+
}
2377+
23562378
/// Creates a dummy const argument, and reports that the expression must be enclosed in braces
23572379
pub fn dummy_const_arg_needs_braces(
23582380
&self,

compiler/rustc_parse/src/parser/path.rs

+34-14
Original file line numberDiff line numberDiff line change
@@ -675,22 +675,42 @@ impl<'a> Parser<'a> {
675675
GenericArg::Const(self.parse_const_arg()?)
676676
} else if self.check_type() {
677677
// Parse type argument.
678-
let is_const_fn =
679-
self.look_ahead(1, |t| t.kind == token::OpenDelim(Delimiter::Parenthesis));
680-
let mut snapshot = self.create_snapshot_for_diagnostic();
678+
679+
// Proactively create a parser snapshot enabling us to rewind and try to reparse the
680+
// input as a const expression in case we fail to parse a type. If we successfully
681+
// do so, we will report an error that it needs to be wrapped in braces.
682+
let mut snapshot = None;
683+
if self.may_recover() && self.token.can_begin_expr() {
684+
snapshot = Some(self.create_snapshot_for_diagnostic());
685+
}
686+
681687
match self.parse_ty() {
682-
Ok(ty) => GenericArg::Type(ty),
688+
Ok(ty) => {
689+
// Since the type parser recovers from some malformed slice and array types and
690+
// successfully returns a type, we need to look for `TyKind::Err`s in the
691+
// type to determine if error recovery has occurred and if the input is not a
692+
// syntactically valid type after all.
693+
if let ast::TyKind::Slice(inner_ty) | ast::TyKind::Array(inner_ty, _) = &ty.kind
694+
&& let ast::TyKind::Err = inner_ty.kind
695+
&& let Some(snapshot) = snapshot
696+
&& let Some(expr) = self.recover_unbraced_const_arg_that_can_begin_ty(snapshot)
697+
{
698+
return Ok(Some(self.dummy_const_arg_needs_braces(
699+
self.struct_span_err(expr.span, "invalid const generic expression"),
700+
expr.span,
701+
)));
702+
}
703+
704+
GenericArg::Type(ty)
705+
}
683706
Err(err) => {
684-
if is_const_fn {
685-
match (*snapshot).parse_expr_res(Restrictions::CONST_EXPR, None) {
686-
Ok(expr) => {
687-
self.restore_snapshot(snapshot);
688-
return Ok(Some(self.dummy_const_arg_needs_braces(err, expr.span)));
689-
}
690-
Err(err) => {
691-
err.cancel();
692-
}
693-
}
707+
if let Some(snapshot) = snapshot
708+
&& let Some(expr) = self.recover_unbraced_const_arg_that_can_begin_ty(snapshot)
709+
{
710+
return Ok(Some(self.dummy_const_arg_needs_braces(
711+
err,
712+
expr.span,
713+
)));
694714
}
695715
// Try to recover from possible `const` arg without braces.
696716
return self.recover_const_arg(start, err).map(Some);

0 commit comments

Comments
 (0)