Skip to content

Commit 19c5376

Browse files
committed
Auto merge of #108998 - matthiaskrgr:rollup-sxbdulg, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #106921 (Add documentation about the memory layout of `Cell`) - #108828 (Emit alias-eq when equating numeric var and projection) - #108834 (Do not ICE when we have fn pointer `Fn` obligations with bound vars in the self type) - #108900 (fix(lexer): print whitespace warning for \x0c) - #108930 (feat: implement better error for manual impl of `Fn*` traits) - #108937 (improve readability of winnowing) - #108947 (Don't even try to combine consts with incompatible types) - #108976 (Update triagebot rust-analyzer team mention) - #108983 (Forbid `#[target_feature]` on safe default implementations) Failed merges: - #108950 (Directly construct Inherited in typeck.) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 6dfaa14 + f74bb35 commit 19c5376

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+534
-181
lines changed

compiler/rustc_codegen_ssa/src/target_features.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ fn asm_target_features(tcx: TyCtxt<'_>, did: DefId) -> &FxIndexSet<Symbol> {
442442
pub fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, attr_span: Span) {
443443
if let DefKind::AssocFn = tcx.def_kind(id) {
444444
let parent_id = tcx.local_parent(id);
445-
if let DefKind::Impl { of_trait: true } = tcx.def_kind(parent_id) {
445+
if let DefKind::Trait | DefKind::Impl { of_trait: true } = tcx.def_kind(parent_id) {
446446
tcx.sess
447447
.struct_span_err(
448448
attr_span,

compiler/rustc_hir_analysis/locales/en-US.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ hir_analysis_assoc_type_binding_not_allowed =
4242
associated type bindings are not allowed here
4343
.label = associated type not allowed here
4444
45+
hir_analysis_parenthesized_fn_trait_expansion =
46+
parenthesized trait syntax expands to `{$expanded_type}`
47+
4548
hir_analysis_typeof_reserved_keyword_used =
4649
`typeof` is a reserved keyword but unimplemented
4750
.suggestion = consider replacing `typeof(...)` with an actual type

compiler/rustc_hir_analysis/src/astconv/errors.rs

+72-35
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
use crate::astconv::AstConv;
2-
use crate::errors::{ManualImplementation, MissingTypeParams};
2+
use crate::errors::{
3+
AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams,
4+
ParenthesizedFnTraitExpansion,
5+
};
36
use rustc_data_structures::fx::FxHashMap;
47
use rustc_errors::{pluralize, struct_span_err, Applicability, Diagnostic, ErrorGuaranteed};
58
use rustc_hir as hir;
69
use rustc_hir::def_id::DefId;
710
use rustc_infer::traits::FulfillmentError;
11+
use rustc_middle::ty::TyCtxt;
812
use rustc_middle::ty::{self, Ty};
913
use rustc_session::parse::feature_err;
1014
use rustc_span::edit_distance::find_best_match_for_name;
@@ -78,43 +82,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
7882
// Do not suggest the other syntax if we are in trait impl:
7983
// the desugaring would contain an associated type constraint.
8084
if !is_impl {
81-
let args = trait_segment
82-
.args
83-
.as_ref()
84-
.and_then(|args| args.args.get(0))
85-
.and_then(|arg| match arg {
86-
hir::GenericArg::Type(ty) => match ty.kind {
87-
hir::TyKind::Tup(t) => t
88-
.iter()
89-
.map(|e| sess.source_map().span_to_snippet(e.span))
90-
.collect::<Result<Vec<_>, _>>()
91-
.map(|a| a.join(", ")),
92-
_ => sess.source_map().span_to_snippet(ty.span),
93-
}
94-
.map(|s| format!("({})", s))
95-
.ok(),
96-
_ => None,
97-
})
98-
.unwrap_or_else(|| "()".to_string());
99-
let ret = trait_segment
100-
.args()
101-
.bindings
102-
.iter()
103-
.find_map(|b| match (b.ident.name == sym::Output, &b.kind) {
104-
(true, hir::TypeBindingKind::Equality { term }) => {
105-
let span = match term {
106-
hir::Term::Ty(ty) => ty.span,
107-
hir::Term::Const(c) => self.tcx().hir().span(c.hir_id),
108-
};
109-
sess.source_map().span_to_snippet(span).ok()
110-
}
111-
_ => None,
112-
})
113-
.unwrap_or_else(|| "()".to_string());
11485
err.span_suggestion(
11586
span,
11687
"use parenthetical notation instead",
117-
format!("{}{} -> {}", trait_segment.ident, args, ret),
88+
fn_trait_to_string(self.tcx(), trait_segment, true),
11889
Applicability::MaybeIncorrect,
11990
);
12091
}
@@ -629,3 +600,69 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
629600
err.emit();
630601
}
631602
}
603+
604+
/// Emits an error regarding forbidden type binding associations
605+
pub fn prohibit_assoc_ty_binding(
606+
tcx: TyCtxt<'_>,
607+
span: Span,
608+
segment: Option<(&hir::PathSegment<'_>, Span)>,
609+
) {
610+
tcx.sess.emit_err(AssocTypeBindingNotAllowed { span, fn_trait_expansion: if let Some((segment, span)) = segment && segment.args().parenthesized {
611+
Some(ParenthesizedFnTraitExpansion { span, expanded_type: fn_trait_to_string(tcx, segment, false) })
612+
} else {
613+
None
614+
}});
615+
}
616+
617+
pub(crate) fn fn_trait_to_string(
618+
tcx: TyCtxt<'_>,
619+
trait_segment: &hir::PathSegment<'_>,
620+
parenthesized: bool,
621+
) -> String {
622+
let args = trait_segment
623+
.args
624+
.as_ref()
625+
.and_then(|args| args.args.get(0))
626+
.and_then(|arg| match arg {
627+
hir::GenericArg::Type(ty) => match ty.kind {
628+
hir::TyKind::Tup(t) => t
629+
.iter()
630+
.map(|e| tcx.sess.source_map().span_to_snippet(e.span))
631+
.collect::<Result<Vec<_>, _>>()
632+
.map(|a| a.join(", ")),
633+
_ => tcx.sess.source_map().span_to_snippet(ty.span),
634+
}
635+
.map(|s| {
636+
// `s.empty()` checks to see if the type is the unit tuple, if so we don't want a comma
637+
if parenthesized || s.is_empty() { format!("({})", s) } else { format!("({},)", s) }
638+
})
639+
.ok(),
640+
_ => None,
641+
})
642+
.unwrap_or_else(|| "()".to_string());
643+
644+
let ret = trait_segment
645+
.args()
646+
.bindings
647+
.iter()
648+
.find_map(|b| match (b.ident.name == sym::Output, &b.kind) {
649+
(true, hir::TypeBindingKind::Equality { term }) => {
650+
let span = match term {
651+
hir::Term::Ty(ty) => ty.span,
652+
hir::Term::Const(c) => tcx.hir().span(c.hir_id),
653+
};
654+
655+
(span != tcx.hir().span(trait_segment.hir_id))
656+
.then_some(tcx.sess.source_map().span_to_snippet(span).ok())
657+
.flatten()
658+
}
659+
_ => None,
660+
})
661+
.unwrap_or_else(|| "()".to_string());
662+
663+
if parenthesized {
664+
format!("{}{} -> {}", trait_segment.ident, args, ret)
665+
} else {
666+
format!("{}<{}, Output={}>", trait_segment.ident, args, ret)
667+
}
668+
}

compiler/rustc_hir_analysis/src/astconv/generics.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use super::IsMethodCall;
22
use crate::astconv::{
3-
CreateSubstsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch,
4-
GenericArgCountResult, GenericArgPosition,
3+
errors::prohibit_assoc_ty_binding, CreateSubstsForGenericArgsCtxt, ExplicitLateBound,
4+
GenericArgCountMismatch, GenericArgCountResult, GenericArgPosition,
55
};
6-
use crate::errors::AssocTypeBindingNotAllowed;
76
use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs};
87
use rustc_ast::ast::ParamKindOrd;
98
use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan};
@@ -433,7 +432,7 @@ pub(crate) fn check_generic_arg_count(
433432
(gen_pos != GenericArgPosition::Type || infer_args) && !gen_args.has_lifetime_params();
434433

435434
if gen_pos != GenericArgPosition::Type && let Some(b) = gen_args.bindings.first() {
436-
prohibit_assoc_ty_binding(tcx, b.span);
435+
prohibit_assoc_ty_binding(tcx, b.span, None);
437436
}
438437

439438
let explicit_late_bound =
@@ -589,11 +588,6 @@ pub(crate) fn check_generic_arg_count(
589588
}
590589
}
591590

592-
/// Emits an error regarding forbidden type binding associations
593-
pub fn prohibit_assoc_ty_binding(tcx: TyCtxt<'_>, span: Span) {
594-
tcx.sess.emit_err(AssocTypeBindingNotAllowed { span });
595-
}
596-
597591
/// Prohibits explicit lifetime arguments if late-bound lifetime parameters
598592
/// are present. This is used both for datatypes and function calls.
599593
pub(crate) fn prohibit_explicit_late_bound_lifetimes(

compiler/rustc_hir_analysis/src/astconv/mod.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
mod errors;
66
pub mod generics;
77

8-
use crate::astconv::generics::{
9-
check_generic_arg_count, create_substs_for_generic_args, prohibit_assoc_ty_binding,
10-
};
8+
use crate::astconv::errors::prohibit_assoc_ty_binding;
9+
use crate::astconv::generics::{check_generic_arg_count, create_substs_for_generic_args};
1110
use crate::bounds::Bounds;
1211
use crate::collect::HirPlaceholderCollector;
1312
use crate::errors::{
@@ -295,7 +294,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
295294
ty::BoundConstness::NotConst,
296295
);
297296
if let Some(b) = item_segment.args().bindings.first() {
298-
prohibit_assoc_ty_binding(self.tcx(), b.span);
297+
prohibit_assoc_ty_binding(self.tcx(), b.span, Some((item_segment, span)));
299298
}
300299

301300
substs
@@ -631,7 +630,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
631630
);
632631

633632
if let Some(b) = item_segment.args().bindings.first() {
634-
prohibit_assoc_ty_binding(self.tcx(), b.span);
633+
prohibit_assoc_ty_binding(self.tcx(), b.span, Some((item_segment, span)));
635634
}
636635

637636
args
@@ -825,7 +824,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
825824
constness,
826825
);
827826
if let Some(b) = trait_segment.args().bindings.first() {
828-
prohibit_assoc_ty_binding(self.tcx(), b.span);
827+
prohibit_assoc_ty_binding(self.tcx(), b.span, Some((trait_segment, span)));
829828
}
830829
self.tcx().mk_trait_ref(trait_def_id, substs)
831830
}
@@ -2596,7 +2595,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
25962595
for segment in segments {
25972596
// Only emit the first error to avoid overloading the user with error messages.
25982597
if let Some(b) = segment.args().bindings.first() {
2599-
prohibit_assoc_ty_binding(self.tcx(), b.span);
2598+
prohibit_assoc_ty_binding(self.tcx(), b.span, None);
26002599
return true;
26012600
}
26022601
}

compiler/rustc_hir_analysis/src/errors.rs

+12
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,18 @@ pub struct AssocTypeBindingNotAllowed {
129129
#[primary_span]
130130
#[label]
131131
pub span: Span,
132+
133+
#[subdiagnostic]
134+
pub fn_trait_expansion: Option<ParenthesizedFnTraitExpansion>,
135+
}
136+
137+
#[derive(Subdiagnostic)]
138+
#[help(hir_analysis_parenthesized_fn_trait_expansion)]
139+
pub struct ParenthesizedFnTraitExpansion {
140+
#[primary_span]
141+
pub span: Span,
142+
143+
pub expanded_type: String,
132144
}
133145

134146
#[derive(Diagnostic)]

compiler/rustc_hir_typeck/src/op.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
148148
rhs_ty,
149149
op,
150150
);
151-
self.demand_suptype(expr.span, builtin_return_ty, return_ty);
151+
self.demand_eqtype(expr.span, builtin_return_ty, return_ty);
152+
builtin_return_ty
153+
} else {
154+
return_ty
152155
}
153-
154-
return_ty
155156
}
156157
}
157158
}

compiler/rustc_infer/src/infer/canonical/canonicalizer.rs

+22-9
Original file line numberDiff line numberDiff line change
@@ -411,15 +411,28 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
411411
}
412412
}
413413

414-
ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var(
415-
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) },
416-
t,
417-
),
418-
419-
ty::Infer(ty::FloatVar(_)) => self.canonicalize_ty_var(
420-
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) },
421-
t,
422-
),
414+
ty::Infer(ty::IntVar(vid)) => {
415+
let nt = self.infcx.opportunistic_resolve_int_var(vid);
416+
if nt != t {
417+
return self.fold_ty(nt);
418+
} else {
419+
self.canonicalize_ty_var(
420+
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) },
421+
t,
422+
)
423+
}
424+
}
425+
ty::Infer(ty::FloatVar(vid)) => {
426+
let nt = self.infcx.opportunistic_resolve_float_var(vid);
427+
if nt != t {
428+
return self.fold_ty(nt);
429+
} else {
430+
self.canonicalize_ty_var(
431+
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) },
432+
t,
433+
)
434+
}
435+
}
423436

424437
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
425438
bug!("encountered a fresh type during canonicalization")

compiler/rustc_infer/src/infer/combine.rs

+33-15
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ use rustc_hir::def_id::DefId;
3434
use rustc_middle::infer::canonical::OriginalQueryValues;
3535
use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
3636
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
37-
use rustc_middle::traits::query::NoSolution;
3837
use rustc_middle::traits::ObligationCause;
3938
use rustc_middle::ty::error::{ExpectedFound, TypeError};
4039
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
@@ -119,20 +118,30 @@ impl<'tcx> InferCtxt<'tcx> {
119118
self.unify_float_variable(!a_is_expected, v_id, v)
120119
}
121120

122-
// All other cases of inference are errors
123-
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
124-
Err(TypeError::Sorts(ty::relate::expected_found(relation, a, b)))
121+
// We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm.
122+
(
123+
ty::Alias(AliasKind::Projection, _),
124+
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)),
125+
)
126+
| (
127+
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)),
128+
ty::Alias(AliasKind::Projection, _),
129+
) if self.tcx.trait_solver_next() => {
130+
bug!()
125131
}
126132

127-
(ty::Alias(AliasKind::Projection, _), _) if self.tcx.trait_solver_next() => {
133+
(_, ty::Alias(AliasKind::Projection, _)) | (ty::Alias(AliasKind::Projection, _), _)
134+
if self.tcx.trait_solver_next() =>
135+
{
128136
relation.register_type_equate_obligation(a, b);
129-
Ok(b)
130-
}
131-
(_, ty::Alias(AliasKind::Projection, _)) if self.tcx.trait_solver_next() => {
132-
relation.register_type_equate_obligation(b, a);
133137
Ok(a)
134138
}
135139

140+
// All other cases of inference are errors
141+
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
142+
Err(TypeError::Sorts(ty::relate::expected_found(relation, a, b)))
143+
}
144+
136145
_ => ty::relate::super_relate_tys(relation, a, b),
137146
}
138147
}
@@ -161,9 +170,9 @@ impl<'tcx> InferCtxt<'tcx> {
161170
//
162171
// This probe is probably not strictly necessary but it seems better to be safe and not accidentally find
163172
// ourselves with a check to find bugs being required for code to compile because it made inference progress.
164-
self.probe(|_| {
173+
let compatible_types = self.probe(|_| {
165174
if a.ty() == b.ty() {
166-
return;
175+
return Ok(());
167176
}
168177

169178
// We don't have access to trait solving machinery in `rustc_infer` so the logic for determining if the
@@ -173,15 +182,24 @@ impl<'tcx> InferCtxt<'tcx> {
173182
(relation.param_env(), a.ty(), b.ty()),
174183
&mut OriginalQueryValues::default(),
175184
);
176-
177-
if let Err(NoSolution) = self.tcx.check_tys_might_be_eq(canonical) {
185+
self.tcx.check_tys_might_be_eq(canonical).map_err(|_| {
178186
self.tcx.sess.delay_span_bug(
179187
DUMMY_SP,
180188
&format!("cannot relate consts of different types (a={:?}, b={:?})", a, b,),
181-
);
182-
}
189+
)
190+
})
183191
});
184192

193+
// If the consts have differing types, just bail with a const error with
194+
// the expected const's type. Specifically, we don't want const infer vars
195+
// to do any type shapeshifting before and after resolution.
196+
if let Err(guar) = compatible_types {
197+
return Ok(self.tcx.const_error_with_guaranteed(
198+
if relation.a_is_expected() { a.ty() } else { b.ty() },
199+
guar,
200+
));
201+
}
202+
185203
match (a.kind(), b.kind()) {
186204
(
187205
ty::ConstKind::Infer(InferConst::Var(a_vid)),

0 commit comments

Comments
 (0)