Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 226b249

Browse files
committedJan 28, 2023
Auto merge of #107400 - matthiaskrgr:rollup-l6bycds, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #107022 (Implement `SpecOptionPartialEq` for `cmp::Ordering`) - #107100 (Use proper `InferCtxt` when probing for associated types in astconv) - #107103 (Use new solver in `evaluate_obligation` query (when new solver is enabled)) - #107190 (Recover from more const arguments that are not wrapped in curly braces) - #107306 (Correct suggestions for closure arguments that need a borrow) - #107339 (internally change regions to be covariant) - #107344 (Minor tweaks in the new solver) - #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

Lines changed: 5 additions & 0 deletions
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

Lines changed: 61 additions & 45 deletions
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

Lines changed: 5 additions & 1 deletion
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

Lines changed: 3 additions & 5 deletions
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 4 additions & 4 deletions
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 2 additions & 12 deletions
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

Lines changed: 22 additions & 0 deletions
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

Lines changed: 34 additions & 14 deletions
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);

‎compiler/rustc_trait_selection/src/solve/assembly.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//! Code shared by trait and projection goals for candidate assembly.
22
33
use super::infcx_ext::InferCtxtExt;
4+
#[cfg(doc)]
5+
use super::trait_goals::structural_traits::*;
46
use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, QueryResult};
57
use rustc_hir::def_id::DefId;
68
use rustc_infer::traits::query::NoSolution;
@@ -98,52 +100,75 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy + Eq {
98100
assumption: ty::Predicate<'tcx>,
99101
) -> QueryResult<'tcx>;
100102

103+
// A type implements an `auto trait` if its components do as well. These components
104+
// are given by built-in rules from [`instantiate_constituent_tys_for_auto_trait`].
101105
fn consider_auto_trait_candidate(
102106
ecx: &mut EvalCtxt<'_, 'tcx>,
103107
goal: Goal<'tcx, Self>,
104108
) -> QueryResult<'tcx>;
105109

110+
// A trait alias holds if the RHS traits and `where` clauses hold.
106111
fn consider_trait_alias_candidate(
107112
ecx: &mut EvalCtxt<'_, 'tcx>,
108113
goal: Goal<'tcx, Self>,
109114
) -> QueryResult<'tcx>;
110115

116+
// A type is `Copy` or `Clone` if its components are `Sized`. These components
117+
// are given by built-in rules from [`instantiate_constituent_tys_for_sized_trait`].
111118
fn consider_builtin_sized_candidate(
112119
ecx: &mut EvalCtxt<'_, 'tcx>,
113120
goal: Goal<'tcx, Self>,
114121
) -> QueryResult<'tcx>;
115122

123+
// A type is `Copy` or `Clone` if its components are `Copy` or `Clone`. These
124+
// components are given by built-in rules from [`instantiate_constituent_tys_for_copy_clone_trait`].
116125
fn consider_builtin_copy_clone_candidate(
117126
ecx: &mut EvalCtxt<'_, 'tcx>,
118127
goal: Goal<'tcx, Self>,
119128
) -> QueryResult<'tcx>;
120129

130+
// A type is `PointerSized` if we can compute its layout, and that layout
131+
// matches the layout of `usize`.
121132
fn consider_builtin_pointer_sized_candidate(
122133
ecx: &mut EvalCtxt<'_, 'tcx>,
123134
goal: Goal<'tcx, Self>,
124135
) -> QueryResult<'tcx>;
125136

137+
// A callable type (a closure, fn def, or fn ptr) is known to implement the `Fn<A>`
138+
// family of traits where `A` is given by the signature of the type.
126139
fn consider_builtin_fn_trait_candidates(
127140
ecx: &mut EvalCtxt<'_, 'tcx>,
128141
goal: Goal<'tcx, Self>,
129142
kind: ty::ClosureKind,
130143
) -> QueryResult<'tcx>;
131144

145+
// `Tuple` is implemented if the `Self` type is a tuple.
132146
fn consider_builtin_tuple_candidate(
133147
ecx: &mut EvalCtxt<'_, 'tcx>,
134148
goal: Goal<'tcx, Self>,
135149
) -> QueryResult<'tcx>;
136150

151+
// `Pointee` is always implemented.
152+
//
153+
// See the projection implementation for the `Metadata` types for all of
154+
// the built-in types. For structs, the metadata type is given by the struct
155+
// tail.
137156
fn consider_builtin_pointee_candidate(
138157
ecx: &mut EvalCtxt<'_, 'tcx>,
139158
goal: Goal<'tcx, Self>,
140159
) -> QueryResult<'tcx>;
141160

161+
// A generator (that comes from an `async` desugaring) is known to implement
162+
// `Future<Output = O>`, where `O` is given by the generator's return type
163+
// that was computed during type-checking.
142164
fn consider_builtin_future_candidate(
143165
ecx: &mut EvalCtxt<'_, 'tcx>,
144166
goal: Goal<'tcx, Self>,
145167
) -> QueryResult<'tcx>;
146168

169+
// A generator (that doesn't come from an `async` desugaring) is known to
170+
// implement `Generator<R, Yield = Y, Return = O>`, given the resume, yield,
171+
// and return types of the generator computed during type-checking.
147172
fn consider_builtin_generator_candidate(
148173
ecx: &mut EvalCtxt<'_, 'tcx>,
149174
goal: Goal<'tcx, Self>,

‎compiler/rustc_trait_selection/src/solve/mod.rs

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -335,15 +335,13 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
335335
// That won't actually reflect in the query response, so it seems moot.
336336
self.make_canonical_response(Certainty::AMBIGUOUS)
337337
} else {
338-
self.infcx.probe(|_| {
339-
let InferOk { value: (), obligations } = self
340-
.infcx
341-
.at(&ObligationCause::dummy(), goal.param_env)
342-
.sub(goal.predicate.a, goal.predicate.b)?;
343-
self.evaluate_all_and_make_canonical_response(
344-
obligations.into_iter().map(|pred| pred.into()).collect(),
345-
)
346-
})
338+
let InferOk { value: (), obligations } = self
339+
.infcx
340+
.at(&ObligationCause::dummy(), goal.param_env)
341+
.sub(goal.predicate.a, goal.predicate.b)?;
342+
self.evaluate_all_and_make_canonical_response(
343+
obligations.into_iter().map(|pred| pred.into()).collect(),
344+
)
347345
}
348346
}
349347

@@ -376,22 +374,22 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
376374
&mut self,
377375
goal: Goal<'tcx, ty::GenericArg<'tcx>>,
378376
) -> QueryResult<'tcx> {
379-
self.infcx.probe(|_| {
380-
match crate::traits::wf::unnormalized_obligations(
381-
self.infcx,
382-
goal.param_env,
383-
goal.predicate,
384-
) {
385-
Some(obligations) => self.evaluate_all_and_make_canonical_response(
386-
obligations.into_iter().map(|o| o.into()).collect(),
387-
),
388-
None => self.make_canonical_response(Certainty::AMBIGUOUS),
389-
}
390-
})
377+
match crate::traits::wf::unnormalized_obligations(
378+
self.infcx,
379+
goal.param_env,
380+
goal.predicate,
381+
) {
382+
Some(obligations) => self.evaluate_all_and_make_canonical_response(
383+
obligations.into_iter().map(|o| o.into()).collect(),
384+
),
385+
None => self.make_canonical_response(Certainty::AMBIGUOUS),
386+
}
391387
}
392388
}
393389

394390
impl<'tcx> EvalCtxt<'_, 'tcx> {
391+
// Recursively evaluates a list of goals to completion, returning the certainty
392+
// of all of the goals.
395393
fn evaluate_all(
396394
&mut self,
397395
mut goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
@@ -428,6 +426,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
428426
})
429427
}
430428

429+
// Recursively evaluates a list of goals to completion, making a query response.
430+
//
431+
// This is just a convenient way of calling [`EvalCtxt::evaluate_all`],
432+
// then [`EvalCtxt::make_canonical_response`].
431433
fn evaluate_all_and_make_canonical_response(
432434
&mut self,
433435
goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,

‎compiler/rustc_trait_selection/src/solve/project_goals.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
296296
goal: Goal<'tcx, Self>,
297297
assumption: ty::Predicate<'tcx>,
298298
) -> QueryResult<'tcx> {
299-
if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred() {
299+
if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred()
300+
&& poly_projection_pred.projection_def_id() == goal.predicate.def_id()
301+
{
300302
ecx.infcx.probe(|_| {
301303
let assumption_projection_pred =
302304
ecx.infcx.instantiate_bound_vars_with_infer(poly_projection_pred);

‎compiler/rustc_trait_selection/src/solve/trait_goals.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
6565
goal: Goal<'tcx, Self>,
6666
assumption: ty::Predicate<'tcx>,
6767
) -> QueryResult<'tcx> {
68-
if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred() {
68+
if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred()
69+
&& poly_trait_pred.def_id() == goal.predicate.def_id()
70+
{
6971
// FIXME: Constness and polarity
7072
ecx.infcx.probe(|_| {
7173
let assumption_trait_pred =

‎compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3807,13 +3807,13 @@ fn hint_missing_borrow<'tcx>(
38073807
err: &mut Diagnostic,
38083808
) {
38093809
let found_args = match found.kind() {
3810-
ty::FnPtr(f) => f.inputs().skip_binder().iter(),
3810+
ty::FnPtr(f) => infcx.replace_bound_vars_with_placeholders(*f).inputs().iter(),
38113811
kind => {
38123812
span_bug!(span, "found was converted to a FnPtr above but is now {:?}", kind)
38133813
}
38143814
};
38153815
let expected_args = match expected.kind() {
3816-
ty::FnPtr(f) => f.inputs().skip_binder().iter(),
3816+
ty::FnPtr(f) => infcx.replace_bound_vars_with_placeholders(*f).inputs().iter(),
38173817
kind => {
38183818
span_bug!(span, "expected was converted to a FnPtr above but is now {:?}", kind)
38193819
}
@@ -3824,12 +3824,12 @@ fn hint_missing_borrow<'tcx>(
38243824

38253825
let args = fn_decl.inputs.iter().map(|ty| ty);
38263826

3827-
fn get_deref_type_and_refs(mut ty: Ty<'_>) -> (Ty<'_>, usize) {
3828-
let mut refs = 0;
3827+
fn get_deref_type_and_refs(mut ty: Ty<'_>) -> (Ty<'_>, Vec<hir::Mutability>) {
3828+
let mut refs = vec![];
38293829

3830-
while let ty::Ref(_, new_ty, _) = ty.kind() {
3830+
while let ty::Ref(_, new_ty, mutbl) = ty.kind() {
38313831
ty = *new_ty;
3832-
refs += 1;
3832+
refs.push(*mutbl);
38333833
}
38343834

38353835
(ty, refs)
@@ -3843,11 +3843,21 @@ fn hint_missing_borrow<'tcx>(
38433843
let (expected_ty, expected_refs) = get_deref_type_and_refs(*expected_arg);
38443844

38453845
if infcx.can_eq(param_env, found_ty, expected_ty).is_ok() {
3846-
if found_refs < expected_refs {
3847-
to_borrow.push((arg.span.shrink_to_lo(), "&".repeat(expected_refs - found_refs)));
3848-
} else if found_refs > expected_refs {
3846+
// FIXME: This could handle more exotic cases like mutability mismatches too!
3847+
if found_refs.len() < expected_refs.len()
3848+
&& found_refs[..] == expected_refs[expected_refs.len() - found_refs.len()..]
3849+
{
3850+
to_borrow.push((
3851+
arg.span.shrink_to_lo(),
3852+
expected_refs[..expected_refs.len() - found_refs.len()]
3853+
.iter()
3854+
.map(|mutbl| format!("&{}", mutbl.prefix_str()))
3855+
.collect::<Vec<_>>()
3856+
.join(""),
3857+
));
3858+
} else if found_refs.len() > expected_refs.len() {
38493859
let mut span = arg.span.shrink_to_lo();
3850-
let mut left = found_refs - expected_refs;
3860+
let mut left = found_refs.len() - expected_refs.len();
38513861
let mut ty = arg;
38523862
while let hir::TyKind::Ref(_, mut_ty) = &ty.kind && left > 0 {
38533863
span = span.with_hi(mut_ty.ty.span.lo());

‎compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use rustc_middle::ty;
2+
use rustc_session::config::TraitSolver;
23

34
use crate::infer::canonical::OriginalQueryValues;
45
use crate::infer::InferCtxt;
6+
use crate::solve::{Certainty, Goal, InferCtxtEvalExt, MaybeCause};
57
use crate::traits::{EvaluationResult, OverflowError, PredicateObligation, SelectionContext};
68

79
pub trait InferCtxtExt<'tcx> {
@@ -77,12 +79,38 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
7779
_ => obligation.param_env.without_const(),
7880
};
7981

80-
let c_pred = self
81-
.canonicalize_query_keep_static(param_env.and(obligation.predicate), &mut _orig_values);
82-
// Run canonical query. If overflow occurs, rerun from scratch but this time
83-
// in standard trait query mode so that overflow is handled appropriately
84-
// within `SelectionContext`.
85-
self.tcx.at(obligation.cause.span()).evaluate_obligation(c_pred)
82+
if self.tcx.sess.opts.unstable_opts.trait_solver != TraitSolver::Next {
83+
let c_pred = self.canonicalize_query_keep_static(
84+
param_env.and(obligation.predicate),
85+
&mut _orig_values,
86+
);
87+
self.tcx.at(obligation.cause.span()).evaluate_obligation(c_pred)
88+
} else {
89+
self.probe(|snapshot| {
90+
if let Ok((_, certainty)) =
91+
self.evaluate_root_goal(Goal::new(self.tcx, param_env, obligation.predicate))
92+
{
93+
match certainty {
94+
Certainty::Yes => {
95+
if self.opaque_types_added_in_snapshot(snapshot) {
96+
Ok(EvaluationResult::EvaluatedToOkModuloOpaqueTypes)
97+
} else if self.region_constraints_added_in_snapshot(snapshot).is_some()
98+
{
99+
Ok(EvaluationResult::EvaluatedToOkModuloRegions)
100+
} else {
101+
Ok(EvaluationResult::EvaluatedToOk)
102+
}
103+
}
104+
Certainty::Maybe(MaybeCause::Ambiguity) => {
105+
Ok(EvaluationResult::EvaluatedToAmbig)
106+
}
107+
Certainty::Maybe(MaybeCause::Overflow) => Err(OverflowError::Canonical),
108+
}
109+
} else {
110+
Ok(EvaluationResult::EvaluatedToErr)
111+
}
112+
})
113+
}
86114
}
87115

88116
// Helper function that canonicalizes and runs the query. If an
@@ -92,6 +120,9 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
92120
&self,
93121
obligation: &PredicateObligation<'tcx>,
94122
) -> EvaluationResult {
123+
// Run canonical query. If overflow occurs, rerun from scratch but this time
124+
// in standard trait query mode so that overflow is handled appropriately
125+
// within `SelectionContext`.
95126
match self.evaluate_obligation(obligation) {
96127
Ok(result) => result,
97128
Err(OverflowError::Canonical) => {

‎library/core/src/option.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ use crate::marker::Destruct;
551551
use crate::panicking::{panic, panic_str};
552552
use crate::pin::Pin;
553553
use crate::{
554-
convert, hint, mem,
554+
cmp, convert, hint, mem,
555555
ops::{self, ControlFlow, Deref, DerefMut},
556556
};
557557

@@ -2090,6 +2090,12 @@ impl<T: PartialEq> PartialEq for Option<T> {
20902090
}
20912091
}
20922092

2093+
/// This specialization trait is a workaround for LLVM not currently (2023-01)
2094+
/// being able to optimize this itself, even though Alive confirms that it would
2095+
/// be legal to do so: <https://github.com/llvm/llvm-project/issues/52622>
2096+
///
2097+
/// Once that's fixed, `Option` should go back to deriving `PartialEq`, as
2098+
/// it used to do before <https://github.com/rust-lang/rust/pull/103556>.
20932099
#[unstable(feature = "spec_option_partial_eq", issue = "none", reason = "exposed only for rustc")]
20942100
#[doc(hidden)]
20952101
pub trait SpecOptionPartialEq: Sized {
@@ -2146,6 +2152,14 @@ impl<T> SpecOptionPartialEq for crate::ptr::NonNull<T> {
21462152
}
21472153
}
21482154

2155+
#[stable(feature = "rust1", since = "1.0.0")]
2156+
impl SpecOptionPartialEq for cmp::Ordering {
2157+
#[inline]
2158+
fn eq(l: &Option<Self>, r: &Option<Self>) -> bool {
2159+
l.map_or(2, |x| x as i8) == r.map_or(2, |x| x as i8)
2160+
}
2161+
}
2162+
21492163
/////////////////////////////////////////////////////////////////////////////
21502164
// The Option Iterators
21512165
/////////////////////////////////////////////////////////////////////////////

‎tests/codegen/debug-vtable.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@
99
// compile-flags: -Cdebuginfo=2 -Copt-level=0 -Csymbol-mangling-version=v0
1010
// ignore-tidy-linelength
1111

12+
// Make sure that vtables don't have the unnamed_addr attribute when debuginfo is enabled.
13+
// This helps debuggers more reliably map from dyn pointer to concrete type.
14+
// CHECK: @vtable.0 = private constant <{
15+
// CHECK: @vtable.1 = private constant <{
16+
// CHECK: @vtable.2 = private constant <{
17+
// CHECK: @vtable.3 = private constant <{
18+
// CHECK: @vtable.4 = private constant <{
19+
1220
// NONMSVC: ![[USIZE:[0-9]+]] = !DIBasicType(name: "usize"
1321
// MSVC: ![[USIZE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_typedef, name: "usize"
1422
// NONMSVC: ![[PTR:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "*const ()"

‎tests/codegen/option-nonzero-eq.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#![crate_type = "lib"]
44

55
extern crate core;
6+
use core::cmp::Ordering;
67
use core::num::{NonZeroU32, NonZeroI64};
78
use core::ptr::NonNull;
89

@@ -32,3 +33,12 @@ pub fn non_null_eq(l: Option<NonNull<u8>>, r: Option<NonNull<u8>>) -> bool {
3233
// CHECK-NEXT: ret i1
3334
l == r
3435
}
36+
37+
// CHECK-lABEL: @ordering_eq
38+
#[no_mangle]
39+
pub fn ordering_eq(l: Option<Ordering>, r: Option<Ordering>) -> bool {
40+
// CHECK: start:
41+
// CHECK-NEXT: icmp eq i8
42+
// CHECK-NEXT: ret i1
43+
l == r
44+
}

‎tests/ui/const-generics/bad-const-generic-exprs.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,34 @@ fn main() {
1313
let _: Wow<A.0>;
1414
//~^ ERROR expected one of
1515
//~| HELP expressions must be enclosed in braces to be used as const generic arguments
16-
17-
// FIXME(compiler-errors): This one is still unsatisfying,
18-
// and probably a case I could see someone typing by accident..
16+
let _: Wow<[]>;
17+
//~^ ERROR expected type
18+
//~| HELP expressions must be enclosed in braces to be used as const generic arguments
1919
let _: Wow<[12]>;
20-
//~^ ERROR expected type, found
21-
//~| ERROR type provided when a constant was expected
20+
//~^ ERROR expected type
21+
//~| ERROR invalid const generic expression
22+
//~| HELP expressions must be enclosed in braces to be used as const generic arguments
23+
let _: Wow<[0, 1, 3]>;
24+
//~^ ERROR expected type
25+
//~| HELP expressions must be enclosed in braces to be used as const generic arguments
26+
let _: Wow<[0xff; 8]>;
27+
//~^ ERROR expected type
28+
//~| ERROR invalid const generic expression
29+
//~| HELP expressions must be enclosed in braces to be used as const generic arguments
30+
let _: Wow<[1, 2]>; // Regression test for issue #81698.
31+
//~^ ERROR expected type
32+
//~| HELP expressions must be enclosed in braces to be used as const generic arguments
33+
let _: Wow<&0>;
34+
//~^ ERROR expected type
35+
//~| HELP expressions must be enclosed in braces to be used as const generic arguments
36+
let _: Wow<("", 0)>;
37+
//~^ ERROR expected type
38+
//~| HELP expressions must be enclosed in braces to be used as const generic arguments
39+
let _: Wow<(1 + 2) * 3>;
40+
//~^ ERROR expected type
41+
//~| HELP expressions must be enclosed in braces to be used as const generic arguments
42+
// FIXME(fmease): This one is pretty bad.
43+
let _: Wow<!0>;
44+
//~^ ERROR expected one of
45+
//~| HELP you might have meant to end the type parameters here
2246
}

‎tests/ui/const-generics/bad-const-generic-exprs.stderr

Lines changed: 103 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,118 @@ help: expressions must be enclosed in braces to be used as const generic argumen
4242
LL | let _: Wow<{ A.0 }>;
4343
| + +
4444

45+
error: expected type, found `]`
46+
--> $DIR/bad-const-generic-exprs.rs:16:17
47+
|
48+
LL | let _: Wow<[]>;
49+
| ^ expected type
50+
|
51+
help: expressions must be enclosed in braces to be used as const generic arguments
52+
|
53+
LL | let _: Wow<{ [] }>;
54+
| + +
55+
4556
error: expected type, found `12`
4657
--> $DIR/bad-const-generic-exprs.rs:19:17
4758
|
4859
LL | let _: Wow<[12]>;
4960
| ^^ expected type
5061

51-
error[E0747]: type provided when a constant was expected
62+
error: invalid const generic expression
5263
--> $DIR/bad-const-generic-exprs.rs:19:16
5364
|
5465
LL | let _: Wow<[12]>;
5566
| ^^^^
67+
|
68+
help: expressions must be enclosed in braces to be used as const generic arguments
69+
|
70+
LL | let _: Wow<{ [12] }>;
71+
| + +
72+
73+
error: expected type, found `0`
74+
--> $DIR/bad-const-generic-exprs.rs:23:17
75+
|
76+
LL | let _: Wow<[0, 1, 3]>;
77+
| ^ expected type
78+
|
79+
help: expressions must be enclosed in braces to be used as const generic arguments
80+
|
81+
LL | let _: Wow<{ [0, 1, 3] }>;
82+
| + +
83+
84+
error: expected type, found `0xff`
85+
--> $DIR/bad-const-generic-exprs.rs:26:17
86+
|
87+
LL | let _: Wow<[0xff; 8]>;
88+
| ^^^^ expected type
89+
90+
error: invalid const generic expression
91+
--> $DIR/bad-const-generic-exprs.rs:26:16
92+
|
93+
LL | let _: Wow<[0xff; 8]>;
94+
| ^^^^^^^^^
95+
|
96+
help: expressions must be enclosed in braces to be used as const generic arguments
97+
|
98+
LL | let _: Wow<{ [0xff; 8] }>;
99+
| + +
100+
101+
error: expected type, found `1`
102+
--> $DIR/bad-const-generic-exprs.rs:30:17
103+
|
104+
LL | let _: Wow<[1, 2]>; // Regression test for issue #81698.
105+
| ^ expected type
106+
|
107+
help: expressions must be enclosed in braces to be used as const generic arguments
108+
|
109+
LL | let _: Wow<{ [1, 2] }>; // Regression test for issue #81698.
110+
| + +
111+
112+
error: expected type, found `0`
113+
--> $DIR/bad-const-generic-exprs.rs:33:17
114+
|
115+
LL | let _: Wow<&0>;
116+
| ^ expected type
117+
|
118+
help: expressions must be enclosed in braces to be used as const generic arguments
119+
|
120+
LL | let _: Wow<{ &0 }>;
121+
| + +
122+
123+
error: expected type, found `""`
124+
--> $DIR/bad-const-generic-exprs.rs:36:17
125+
|
126+
LL | let _: Wow<("", 0)>;
127+
| ^^ expected type
128+
|
129+
help: expressions must be enclosed in braces to be used as const generic arguments
130+
|
131+
LL | let _: Wow<{ ("", 0) }>;
132+
| + +
133+
134+
error: expected type, found `1`
135+
--> $DIR/bad-const-generic-exprs.rs:39:17
136+
|
137+
LL | let _: Wow<(1 + 2) * 3>;
138+
| ^ expected type
139+
|
140+
help: expressions must be enclosed in braces to be used as const generic arguments
141+
|
142+
LL | let _: Wow<{ (1 + 2) * 3 }>;
143+
| + +
144+
145+
error: expected one of `,` or `>`, found `0`
146+
--> $DIR/bad-const-generic-exprs.rs:43:17
147+
|
148+
LL | let _: Wow<!0>;
149+
| - ^ expected one of `,` or `>`
150+
| |
151+
| while parsing the type for `_`
152+
|
153+
help: you might have meant to end the type parameters here
154+
|
155+
LL | let _: Wow<!>0>;
156+
| +
56157

57-
error: aborting due to 6 previous errors
158+
error: aborting due to 15 previous errors
58159

59-
For more information about this error, try `rustc --explain E0747`.

‎tests/ui/error-codes/E0208.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![feature(rustc_attrs)]
22

33
#[rustc_variance]
4-
struct Foo<'a, T> { //~ ERROR [-, o]
4+
struct Foo<'a, T> { //~ ERROR [+, o]
55
t: &'a mut T,
66
}
77

‎tests/ui/error-codes/E0208.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: [-, o]
1+
error: [+, o]
22
--> $DIR/E0208.rs:4:1
33
|
44
LL | struct Foo<'a, T> {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use std::cell::RefCell;
2+
use std::collections::HashMap;
3+
use std::rc::Rc;
4+
5+
pub struct Trader<'a> {
6+
closure: Box<dyn Fn(&mut Trader) + 'a>,
7+
}
8+
9+
impl<'a> Trader<'a> {
10+
pub fn new() -> Self {
11+
Trader {
12+
closure: Box::new(|_| {}),
13+
}
14+
}
15+
pub fn set_closure(&mut self, function: impl Fn(&mut Trader) + 'a) {
16+
//foo
17+
}
18+
}
19+
20+
fn main() {
21+
let closure = |trader : Trader| {
22+
println!("Woooosh!");
23+
};
24+
25+
let mut trader = Trader::new();
26+
trader.set_closure(closure);
27+
//~^ ERROR type mismatch in closure arguments
28+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error[E0631]: type mismatch in closure arguments
2+
--> $DIR/late-bound-in-borrow-closure-sugg.rs:26:24
3+
|
4+
LL | let closure = |trader : Trader| {
5+
| ----------------- found signature defined here
6+
...
7+
LL | trader.set_closure(closure);
8+
| ----------- ^^^^^^^ expected due to this
9+
| |
10+
| required by a bound introduced by this call
11+
|
12+
= note: expected closure signature `for<'a, 'b> fn(&'a mut Trader<'b>) -> _`
13+
found closure signature `for<'a> fn(Trader<'a>) -> _`
14+
note: required by a bound in `Trader::<'a>::set_closure`
15+
--> $DIR/late-bound-in-borrow-closure-sugg.rs:15:50
16+
|
17+
LL | pub fn set_closure(&mut self, function: impl Fn(&mut Trader) + 'a) {
18+
| ^^^^^^^^^^^^^^^ required by this bound in `Trader::<'a>::set_closure`
19+
help: consider borrowing the argument
20+
|
21+
LL | let closure = |trader : &mut Trader| {
22+
| ++++
23+
24+
error: aborting due to previous error
25+
26+
For more information about this error, try `rustc --explain E0631`.

‎tests/ui/typeck/issue-107087.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
struct A<T>(T);
2+
3+
trait Foo {
4+
type B;
5+
}
6+
7+
impl Foo for A<u32> {
8+
type B = i32;
9+
}
10+
11+
impl Foo for A<i32> {
12+
type B = i32;
13+
}
14+
15+
fn main() {
16+
A::B::<>::C
17+
//~^ ERROR ambiguous associated type
18+
}

‎tests/ui/typeck/issue-107087.stderr

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0223]: ambiguous associated type
2+
--> $DIR/issue-107087.rs:16:5
3+
|
4+
LL | A::B::<>::C
5+
| ^^^^^^^^ help: use the fully-qualified path: `<A<_> as Foo>::B`
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0223`.

‎tests/ui/variance/variance-associated-types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ trait Trait<'a> {
1010
}
1111

1212
#[rustc_variance]
13-
struct Foo<'a, T : Trait<'a>> { //~ ERROR [-, +]
13+
struct Foo<'a, T : Trait<'a>> { //~ ERROR [+, +]
1414
field: (T, &'a ())
1515
}
1616

‎tests/ui/variance/variance-associated-types.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: [-, +]
1+
error: [+, +]
22
--> $DIR/variance-associated-types.rs:13:1
33
|
44
LL | struct Foo<'a, T : Trait<'a>> {

‎tests/ui/variance/variance-regions-direct.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// Regions that just appear in normal spots are contravariant:
77

88
#[rustc_variance]
9-
struct Test2<'a, 'b, 'c> { //~ ERROR [-, -, -]
9+
struct Test2<'a, 'b, 'c> { //~ ERROR [+, +, +]
1010
x: &'a isize,
1111
y: &'b [isize],
1212
c: &'c str
@@ -15,7 +15,7 @@ struct Test2<'a, 'b, 'c> { //~ ERROR [-, -, -]
1515
// Those same annotations in function arguments become covariant:
1616

1717
#[rustc_variance]
18-
struct Test3<'a, 'b, 'c> { //~ ERROR [+, +, +]
18+
struct Test3<'a, 'b, 'c> { //~ ERROR [-, -, -]
1919
x: extern "Rust" fn(&'a isize),
2020
y: extern "Rust" fn(&'b [isize]),
2121
c: extern "Rust" fn(&'c str),
@@ -24,15 +24,15 @@ struct Test3<'a, 'b, 'c> { //~ ERROR [+, +, +]
2424
// Mutability induces invariance:
2525

2626
#[rustc_variance]
27-
struct Test4<'a, 'b:'a> { //~ ERROR [-, o]
27+
struct Test4<'a, 'b:'a> { //~ ERROR [+, o]
2828
x: &'a mut &'b isize,
2929
}
3030

3131
// Mutability induces invariance, even when in a
3232
// contravariant context:
3333

3434
#[rustc_variance]
35-
struct Test5<'a, 'b:'a> { //~ ERROR [+, o]
35+
struct Test5<'a, 'b:'a> { //~ ERROR [-, o]
3636
x: extern "Rust" fn(&'a mut &'b isize),
3737
}
3838

@@ -42,7 +42,7 @@ struct Test5<'a, 'b:'a> { //~ ERROR [+, o]
4242
// argument list occurs in an invariant context.
4343

4444
#[rustc_variance]
45-
struct Test6<'a, 'b:'a> { //~ ERROR [-, o]
45+
struct Test6<'a, 'b:'a> { //~ ERROR [+, o]
4646
x: &'a mut extern "Rust" fn(&'b isize),
4747
}
4848

@@ -56,7 +56,7 @@ struct Test7<'a> { //~ ERROR [*]
5656
// Try enums too.
5757

5858
#[rustc_variance]
59-
enum Test8<'a, 'b, 'c:'b> { //~ ERROR [+, -, o]
59+
enum Test8<'a, 'b, 'c:'b> { //~ ERROR [-, +, o]
6060
Test8A(extern "Rust" fn(&'a isize)),
6161
Test8B(&'b [isize]),
6262
Test8C(&'b mut &'c str),

‎tests/ui/variance/variance-regions-direct.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1-
error: [-, -, -]
1+
error: [+, +, +]
22
--> $DIR/variance-regions-direct.rs:9:1
33
|
44
LL | struct Test2<'a, 'b, 'c> {
55
| ^^^^^^^^^^^^^^^^^^^^^^^^
66

7-
error: [+, +, +]
7+
error: [-, -, -]
88
--> $DIR/variance-regions-direct.rs:18:1
99
|
1010
LL | struct Test3<'a, 'b, 'c> {
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^
1212

13-
error: [-, o]
13+
error: [+, o]
1414
--> $DIR/variance-regions-direct.rs:27:1
1515
|
1616
LL | struct Test4<'a, 'b:'a> {
1717
| ^^^^^^^^^^^^^^^^^^^^^^^
1818

19-
error: [+, o]
19+
error: [-, o]
2020
--> $DIR/variance-regions-direct.rs:35:1
2121
|
2222
LL | struct Test5<'a, 'b:'a> {
2323
| ^^^^^^^^^^^^^^^^^^^^^^^
2424

25-
error: [-, o]
25+
error: [+, o]
2626
--> $DIR/variance-regions-direct.rs:45:1
2727
|
2828
LL | struct Test6<'a, 'b:'a> {
@@ -34,7 +34,7 @@ error: [*]
3434
LL | struct Test7<'a> {
3535
| ^^^^^^^^^^^^^^^^
3636

37-
error: [+, -, o]
37+
error: [-, +, o]
3838
--> $DIR/variance-regions-direct.rs:59:1
3939
|
4040
LL | enum Test8<'a, 'b, 'c:'b> {

‎tests/ui/variance/variance-regions-indirect.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
#![feature(rustc_attrs)]
66

77
#[rustc_variance]
8-
enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [+, -, o, *]
8+
enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [-, +, o, *]
99
Test8A(extern "Rust" fn(&'a isize)),
1010
Test8B(&'b [isize]),
1111
Test8C(&'b mut &'c str),
1212
}
1313

1414
#[rustc_variance]
15-
struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR [*, o, -, +]
15+
struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR [*, o, +, -]
1616
f: Base<'z, 'y, 'x, 'w>
1717
}
1818

@@ -22,12 +22,12 @@ struct Derived2<'a, 'b:'a, 'c> { //~ ERROR [o, o, *]
2222
}
2323

2424
#[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here)
25-
struct Derived3<'a:'b, 'b, 'c> { //~ ERROR [o, -, *]
25+
struct Derived3<'a:'b, 'b, 'c> { //~ ERROR [o, +, *]
2626
f: Base<'a, 'b, 'a, 'c>
2727
}
2828

2929
#[rustc_variance] // Combine + and * to yield + (just pay attention to 'a here)
30-
struct Derived4<'a, 'b, 'c:'b> { //~ ERROR [+, -, o]
30+
struct Derived4<'a, 'b, 'c:'b> { //~ ERROR [-, +, o]
3131
f: Base<'a, 'b, 'c, 'a>
3232
}
3333

‎tests/ui/variance/variance-regions-indirect.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error: [+, -, o, *]
1+
error: [-, +, o, *]
22
--> $DIR/variance-regions-indirect.rs:8:1
33
|
44
LL | enum Base<'a, 'b, 'c:'b, 'd> {
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66

7-
error: [*, o, -, +]
7+
error: [*, o, +, -]
88
--> $DIR/variance-regions-indirect.rs:15:1
99
|
1010
LL | struct Derived1<'w, 'x:'y, 'y, 'z> {
@@ -16,13 +16,13 @@ error: [o, o, *]
1616
LL | struct Derived2<'a, 'b:'a, 'c> {
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1818

19-
error: [o, -, *]
19+
error: [o, +, *]
2020
--> $DIR/variance-regions-indirect.rs:25:1
2121
|
2222
LL | struct Derived3<'a:'b, 'b, 'c> {
2323
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2424

25-
error: [+, -, o]
25+
error: [-, +, o]
2626
--> $DIR/variance-regions-indirect.rs:30:1
2727
|
2828
LL | struct Derived4<'a, 'b, 'c:'b> {

‎tests/ui/variance/variance-trait-object-bound.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::mem;
1111
trait T { fn foo(&self); }
1212

1313
#[rustc_variance]
14-
struct TOption<'a> { //~ ERROR [-]
14+
struct TOption<'a> { //~ ERROR [+]
1515
v: Option<Box<dyn T + 'a>>,
1616
}
1717

‎tests/ui/variance/variance-trait-object-bound.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: [-]
1+
error: [+]
22
--> $DIR/variance-trait-object-bound.rs:14:1
33
|
44
LL | struct TOption<'a> {

‎tests/ui/variance/variance-types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::cell::Cell;
77
// not considered bivariant.
88

99
#[rustc_variance]
10-
struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR [-, o, o]
10+
struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR [+, o, o]
1111
t: &'a mut (A,B)
1212
}
1313

‎tests/ui/variance/variance-types.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: [-, o, o]
1+
error: [+, o, o]
22
--> $DIR/variance-types.rs:10:1
33
|
44
LL | struct InvariantMut<'a,A:'a,B:'a> {

0 commit comments

Comments
 (0)
Please sign in to comment.