Skip to content

Commit 9fb32dc

Browse files
committedJul 11, 2022
Auto merge of #99151 - Dylan-DPC:rollup-40aqkxy, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #98882 (explain doc comments in macros a bit) - #98907 (Deny float const params even when `adt_const_params` is enabled) - #99091 (Do not mention private types from other crates as impl candidates) - #99140 (Implement `SourceMap::is_span_accessible`) - #99147 (Mention similarly named associated type even if it's not clearly in supertrait) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 7d1f57a + 21d6b1f commit 9fb32dc

File tree

31 files changed

+348
-96
lines changed

31 files changed

+348
-96
lines changed
 

‎compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
309309
));
310310

311311
// Check first whether the source is accessible (issue #87060)
312-
if self.infcx.tcx.sess.source_map().span_to_snippet(deref_target).is_ok() {
312+
if self.infcx.tcx.sess.source_map().is_span_accessible(deref_target) {
313313
err.span_note(deref_target, "deref defined here");
314314
}
315315
}

‎compiler/rustc_borrowck/src/diagnostics/mod.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -975,14 +975,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
975975
if self.fn_self_span_reported.insert(fn_span) {
976976
err.span_note(
977977
// Check whether the source is accessible
978-
if self
979-
.infcx
980-
.tcx
981-
.sess
982-
.source_map()
983-
.span_to_snippet(self_arg.span)
984-
.is_ok()
985-
{
978+
if self.infcx.tcx.sess.source_map().is_span_accessible(self_arg.span) {
986979
self_arg.span
987980
} else {
988981
fn_call_span

‎compiler/rustc_const_eval/src/transform/check_consts/ops.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
299299
err.note(&format!("attempting to deref into `{}`", deref_target_ty));
300300

301301
// Check first whether the source is accessible (issue #87060)
302-
if tcx.sess.source_map().span_to_snippet(deref_target).is_ok() {
302+
if tcx.sess.source_map().is_span_accessible(deref_target) {
303303
err.span_note(deref_target, "deref defined here");
304304
}
305305

‎compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ impl Qualif for CustomEq {
226226
// because that component may be part of an enum variant (e.g.,
227227
// `Option::<NonStructuralMatchTy>::Some`), in which case some values of this type may be
228228
// structural-match (`Option::None`).
229-
traits::search_for_structural_match_violation(cx.body.span, cx.tcx, ty).is_some()
229+
traits::search_for_structural_match_violation(cx.body.span, cx.tcx, ty, true).is_some()
230230
}
231231

232232
fn in_adt_inherently<'tcx>(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
expand-explain-doc-comment-outer =
2+
outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match
3+
4+
expand-explain-doc-comment-inner =
5+
inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match

‎compiler/rustc_error_messages/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ pub use unic_langid::{langid, LanguageIdentifier};
3333
fluent_messages! {
3434
borrowck => "../locales/en-US/borrowck.ftl",
3535
builtin_macros => "../locales/en-US/builtin_macros.ftl",
36+
const_eval => "../locales/en-US/const_eval.ftl",
37+
expand => "../locales/en-US/expand.ftl",
3638
lint => "../locales/en-US/lint.ftl",
3739
parser => "../locales/en-US/parser.ftl",
3840
privacy => "../locales/en-US/privacy.ftl",
3941
typeck => "../locales/en-US/typeck.ftl",
40-
const_eval => "../locales/en-US/const_eval.ftl",
4142
}
4243

4344
pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES};

‎compiler/rustc_errors/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1558,7 +1558,7 @@ pub fn add_elided_lifetime_in_path_suggestion(
15581558
insertion_span: Span,
15591559
) {
15601560
diag.span_label(path_span, format!("expected lifetime parameter{}", pluralize!(n)));
1561-
if source_map.span_to_snippet(insertion_span).is_err() {
1561+
if !source_map.is_span_accessible(insertion_span) {
15621562
// Do not try to suggest anything if generated by a proc-macro.
15631563
return;
15641564
}

‎compiler/rustc_expand/src/mbe/macro_rules.rs

+35-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_ast::{NodeId, DUMMY_NODE_ID};
1414
use rustc_ast_pretty::pprust;
1515
use rustc_attr::{self as attr, TransparencyError};
1616
use rustc_data_structures::fx::FxHashMap;
17-
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder};
17+
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
1818
use rustc_feature::Features;
1919
use rustc_lint_defs::builtin::{
2020
RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
@@ -25,6 +25,7 @@ use rustc_session::parse::ParseSess;
2525
use rustc_session::Session;
2626
use rustc_span::edition::Edition;
2727
use rustc_span::hygiene::Transparency;
28+
use rustc_span::source_map::SourceMap;
2829
use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent};
2930
use rustc_span::Span;
3031

@@ -345,7 +346,7 @@ fn expand_macro<'cx>(
345346
if !def_span.is_dummy() && !cx.source_map().is_imported(def_span) {
346347
err.span_label(cx.source_map().guess_head_span(def_span), "when calling this macro");
347348
}
348-
349+
annotate_doc_comment(&mut err, sess.source_map(), span);
349350
// Check whether there's a missing comma in this macro call, like `println!("{}" a);`
350351
if let Some((arg, comma_span)) = arg.add_comma() {
351352
for lhs in lhses {
@@ -453,7 +454,10 @@ pub fn compile_declarative_macro(
453454
Failure(token, msg) => {
454455
let s = parse_failure_msg(&token);
455456
let sp = token.span.substitute_dummy(def.span);
456-
sess.parse_sess.span_diagnostic.struct_span_err(sp, &s).span_label(sp, msg).emit();
457+
let mut err = sess.parse_sess.span_diagnostic.struct_span_err(sp, &s);
458+
err.span_label(sp, msg);
459+
annotate_doc_comment(&mut err, sess.source_map(), sp);
460+
err.emit();
457461
return dummy_syn_ext();
458462
}
459463
Error(sp, msg) => {
@@ -590,6 +594,34 @@ pub fn compile_declarative_macro(
590594
(mk_syn_ext(expander), rule_spans)
591595
}
592596

597+
#[derive(SessionSubdiagnostic)]
598+
enum ExplainDocComment {
599+
#[label(expand::explain_doc_comment_inner)]
600+
Inner {
601+
#[primary_span]
602+
span: Span,
603+
},
604+
#[label(expand::explain_doc_comment_outer)]
605+
Outer {
606+
#[primary_span]
607+
span: Span,
608+
},
609+
}
610+
611+
fn annotate_doc_comment(
612+
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
613+
sm: &SourceMap,
614+
span: Span,
615+
) {
616+
if let Ok(src) = sm.span_to_snippet(span) {
617+
if src.starts_with("///") || src.starts_with("/**") {
618+
err.subdiagnostic(ExplainDocComment::Outer { span });
619+
} else if src.starts_with("//!") || src.starts_with("/*!") {
620+
err.subdiagnostic(ExplainDocComment::Inner { span });
621+
}
622+
}
623+
}
624+
593625
fn check_lhs_nt_follows(sess: &ParseSess, def: &ast::Item, lhs: &mbe::TokenTree) -> bool {
594626
// lhs is going to be like TokenTree::Delimited(...), where the
595627
// entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens.

‎compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
432432
"`let` bindings require an \"irrefutable pattern\", like a `struct` or \
433433
an `enum` with only one variant",
434434
);
435-
if self.tcx.sess.source_map().span_to_snippet(span).is_ok() {
435+
if self.tcx.sess.source_map().is_span_accessible(span) {
436436
let semi_span = span.shrink_to_hi().with_lo(span.hi() - BytePos(1));
437437
let start_span = span.shrink_to_lo();
438438
let end_span = semi_span.shrink_to_lo();

‎compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs

+31-26
Original file line numberDiff line numberDiff line change
@@ -120,32 +120,37 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
120120
}
121121

122122
fn search_for_structural_match_violation(&self, ty: Ty<'tcx>) -> Option<String> {
123-
traits::search_for_structural_match_violation(self.span, self.tcx(), ty).map(|non_sm_ty| {
124-
with_no_trimmed_paths!(match non_sm_ty.kind {
125-
traits::NonStructuralMatchTyKind::Adt(adt) => self.adt_derive_msg(adt),
126-
traits::NonStructuralMatchTyKind::Dynamic => {
127-
"trait objects cannot be used in patterns".to_string()
128-
}
129-
traits::NonStructuralMatchTyKind::Opaque => {
130-
"opaque types cannot be used in patterns".to_string()
131-
}
132-
traits::NonStructuralMatchTyKind::Closure => {
133-
"closures cannot be used in patterns".to_string()
134-
}
135-
traits::NonStructuralMatchTyKind::Generator => {
136-
"generators cannot be used in patterns".to_string()
137-
}
138-
traits::NonStructuralMatchTyKind::Param => {
139-
bug!("use of a constant whose type is a parameter inside a pattern")
140-
}
141-
traits::NonStructuralMatchTyKind::Projection => {
142-
bug!("use of a constant whose type is a projection inside a pattern")
143-
}
144-
traits::NonStructuralMatchTyKind::Foreign => {
145-
bug!("use of a value of a foreign type inside a pattern")
146-
}
147-
})
148-
})
123+
traits::search_for_structural_match_violation(self.span, self.tcx(), ty, true).map(
124+
|non_sm_ty| {
125+
with_no_trimmed_paths!(match non_sm_ty.kind {
126+
traits::NonStructuralMatchTyKind::Adt(adt) => self.adt_derive_msg(adt),
127+
traits::NonStructuralMatchTyKind::Dynamic => {
128+
"trait objects cannot be used in patterns".to_string()
129+
}
130+
traits::NonStructuralMatchTyKind::Opaque => {
131+
"opaque types cannot be used in patterns".to_string()
132+
}
133+
traits::NonStructuralMatchTyKind::Closure => {
134+
"closures cannot be used in patterns".to_string()
135+
}
136+
traits::NonStructuralMatchTyKind::Generator => {
137+
"generators cannot be used in patterns".to_string()
138+
}
139+
traits::NonStructuralMatchTyKind::Float => {
140+
"floating-point numbers cannot be used in patterns".to_string()
141+
}
142+
traits::NonStructuralMatchTyKind::Param => {
143+
bug!("use of a constant whose type is a parameter inside a pattern")
144+
}
145+
traits::NonStructuralMatchTyKind::Projection => {
146+
bug!("use of a constant whose type is a projection inside a pattern")
147+
}
148+
traits::NonStructuralMatchTyKind::Foreign => {
149+
bug!("use of a value of a foreign type inside a pattern")
150+
}
151+
})
152+
},
153+
)
149154
}
150155

151156
fn type_marked_structural(&self, ty: Ty<'tcx>) -> bool {

‎compiler/rustc_resolve/src/diagnostics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1647,7 +1647,7 @@ impl<'a> Resolver<'a> {
16471647

16481648
fn binding_description(&self, b: &NameBinding<'_>, ident: Ident, from_prelude: bool) -> String {
16491649
let res = b.res();
1650-
if b.span.is_dummy() || self.session.source_map().span_to_snippet(b.span).is_err() {
1650+
if b.span.is_dummy() || !self.session.source_map().is_span_accessible(b.span) {
16511651
// These already contain the "built-in" prefix or look bad with it.
16521652
let add_built_in =
16531653
!matches!(b.res(), Res::NonMacroAttr(..) | Res::PrimTy(..) | Res::ToolMod);

‎compiler/rustc_span/src/source_map.rs

+7
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,13 @@ impl SourceMap {
597597
local_begin.sf.src.is_some() && local_end.sf.src.is_some()
598598
}
599599

600+
pub fn is_span_accessible(&self, sp: Span) -> bool {
601+
self.span_to_source(sp, |src, start_index, end_index| {
602+
Ok(src.get(start_index..end_index).is_some())
603+
})
604+
.map_or(false, |is_accessible| is_accessible)
605+
}
606+
600607
/// Returns the source snippet as `String` corresponding to the given `Span`.
601608
pub fn span_to_snippet(&self, sp: Span) -> Result<String, SpanSnippetError> {
602609
self.span_to_source(sp, |src, start_index, end_index| {

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

+22-2
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
673673
if !self.report_similar_impl_candidates(
674674
impl_candidates,
675675
trait_ref,
676+
obligation.cause.body_id,
676677
&mut err,
677678
) {
678679
// This is *almost* equivalent to
@@ -707,6 +708,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
707708
self.report_similar_impl_candidates(
708709
impl_candidates,
709710
trait_ref,
711+
obligation.cause.body_id,
710712
&mut err,
711713
);
712714
}
@@ -1353,6 +1355,7 @@ trait InferCtxtPrivExt<'hir, 'tcx> {
13531355
&self,
13541356
impl_candidates: Vec<ImplCandidate<'tcx>>,
13551357
trait_ref: ty::PolyTraitRef<'tcx>,
1358+
body_id: hir::HirId,
13561359
err: &mut Diagnostic,
13571360
) -> bool;
13581361

@@ -1735,6 +1738,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
17351738
&self,
17361739
impl_candidates: Vec<ImplCandidate<'tcx>>,
17371740
trait_ref: ty::PolyTraitRef<'tcx>,
1741+
body_id: hir::HirId,
17381742
err: &mut Diagnostic,
17391743
) -> bool {
17401744
let report = |mut candidates: Vec<TraitRef<'tcx>>, err: &mut Diagnostic| {
@@ -1805,8 +1809,24 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
18051809
|| self.tcx.is_builtin_derive(def_id)
18061810
})
18071811
.filter_map(|def_id| self.tcx.impl_trait_ref(def_id))
1808-
// Avoid mentioning type parameters.
1809-
.filter(|trait_ref| !matches!(trait_ref.self_ty().kind(), ty::Param(_)))
1812+
.filter(|trait_ref| {
1813+
let self_ty = trait_ref.self_ty();
1814+
// Avoid mentioning type parameters.
1815+
if let ty::Param(_) = self_ty.kind() {
1816+
false
1817+
}
1818+
// Avoid mentioning types that are private to another crate
1819+
else if let ty::Adt(def, _) = self_ty.peel_refs().kind() {
1820+
// FIXME(compiler-errors): This could be generalized, both to
1821+
// be more granular, and probably look past other `#[fundamental]`
1822+
// types, too.
1823+
self.tcx
1824+
.visibility(def.did())
1825+
.is_accessible_from(body_id.owner.to_def_id(), self.tcx)
1826+
} else {
1827+
true
1828+
}
1829+
})
18101830
.collect();
18111831
return report(normalized_impl_candidates, err);
18121832
}

‎compiler/rustc_trait_selection/src/traits/structural_match.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub enum NonStructuralMatchTyKind<'tcx> {
2626
Closure,
2727
Generator,
2828
Projection,
29+
Float,
2930
}
3031

3132
/// This method traverses the structure of `ty`, trying to find an
@@ -53,12 +54,16 @@ pub enum NonStructuralMatchTyKind<'tcx> {
5354
/// For more background on why Rust has this requirement, and issues
5455
/// that arose when the requirement was not enforced completely, see
5556
/// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307.
57+
///
58+
/// The floats_allowed flag is used to deny constants in floating point
5659
pub fn search_for_structural_match_violation<'tcx>(
5760
span: Span,
5861
tcx: TyCtxt<'tcx>,
5962
ty: Ty<'tcx>,
63+
floats_allowed: bool,
6064
) -> Option<NonStructuralMatchTy<'tcx>> {
61-
ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default() }).break_value()
65+
ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default(), floats_allowed })
66+
.break_value()
6267
}
6368

6469
/// This method returns true if and only if `adt_ty` itself has been marked as
@@ -119,6 +124,8 @@ struct Search<'tcx> {
119124
/// Tracks ADTs previously encountered during search, so that
120125
/// we will not recur on them again.
121126
seen: FxHashSet<hir::def_id::DefId>,
127+
128+
floats_allowed: bool,
122129
}
123130

124131
impl<'tcx> Search<'tcx> {
@@ -192,13 +199,24 @@ impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> {
192199
// for empty array.
193200
return ControlFlow::CONTINUE;
194201
}
195-
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => {
202+
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Str | ty::Never => {
196203
// These primitive types are always structural match.
197204
//
198205
// `Never` is kind of special here, but as it is not inhabitable, this should be fine.
199206
return ControlFlow::CONTINUE;
200207
}
201208

209+
ty::Float(_) => {
210+
if self.floats_allowed {
211+
return ControlFlow::CONTINUE;
212+
} else {
213+
return ControlFlow::Break(NonStructuralMatchTy {
214+
ty,
215+
kind: NonStructuralMatchTyKind::Float,
216+
});
217+
}
218+
}
219+
202220
ty::Array(..) | ty::Slice(_) | ty::Ref(..) | ty::Tuple(..) => {
203221
// First check all contained types and then tell the caller to continue searching.
204222
return ty.super_visit_with(self);

‎compiler/rustc_typeck/src/astconv/errors.rs

+54-2
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,62 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
164164
suggested_name,
165165
Applicability::MaybeIncorrect,
166166
);
167-
} else {
168-
err.span_label(span, format!("associated type `{}` not found", assoc_name));
167+
return err.emit();
169168
}
170169

170+
// If we didn't find a good item in the supertraits (or couldn't get
171+
// the supertraits), like in ItemCtxt, then look more generally from
172+
// all visible traits. If there's one clear winner, just suggest that.
173+
174+
let visible_traits: Vec<_> = self
175+
.tcx()
176+
.all_traits()
177+
.filter(|trait_def_id| {
178+
let viz = self.tcx().visibility(*trait_def_id);
179+
if let Some(def_id) = self.item_def_id() {
180+
viz.is_accessible_from(def_id, self.tcx())
181+
} else {
182+
viz.is_visible_locally()
183+
}
184+
})
185+
.collect();
186+
187+
let wider_candidate_names: Vec<_> = visible_traits
188+
.iter()
189+
.flat_map(|trait_def_id| {
190+
self.tcx().associated_items(*trait_def_id).in_definition_order()
191+
})
192+
.filter_map(
193+
|item| if item.kind == ty::AssocKind::Type { Some(item.name) } else { None },
194+
)
195+
.collect();
196+
197+
if let (Some(suggested_name), true) = (
198+
find_best_match_for_name(&wider_candidate_names, assoc_name.name, None),
199+
assoc_name.span != DUMMY_SP,
200+
) {
201+
if let [best_trait] = visible_traits
202+
.iter()
203+
.filter(|trait_def_id| {
204+
self.tcx()
205+
.associated_items(*trait_def_id)
206+
.filter_by_name_unhygienic(suggested_name)
207+
.any(|item| item.kind == ty::AssocKind::Type)
208+
})
209+
.collect::<Vec<_>>()[..]
210+
{
211+
err.span_label(
212+
assoc_name.span,
213+
format!(
214+
"there is a similarly named associated type `{suggested_name}` in the trait `{}`",
215+
self.tcx().def_path_str(*best_trait)
216+
),
217+
);
218+
return err.emit();
219+
}
220+
}
221+
222+
err.span_label(span, format!("associated type `{}` not found", assoc_name));
171223
err.emit()
172224
}
173225

‎compiler/rustc_typeck/src/check/demand.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
760760
if let Some(call_span) =
761761
iter::successors(Some(expr.span), |s| s.parent_callsite())
762762
.find(|&s| sp.contains(s))
763-
&& sm.span_to_snippet(call_span).is_ok()
763+
&& sm.is_span_accessible(call_span)
764764
{
765765
return Some((
766766
sp.with_hi(call_span.lo()),
@@ -773,7 +773,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
773773
return None;
774774
}
775775
if sp.contains(expr.span)
776-
&& sm.span_to_snippet(expr.span).is_ok()
776+
&& sm.is_span_accessible(expr.span)
777777
{
778778
return Some((
779779
sp.with_hi(expr.span.lo()),

‎compiler/rustc_typeck/src/check/wfcheck.rs

+49-37
Original file line numberDiff line numberDiff line change
@@ -824,50 +824,62 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
824824
}
825825

826826
if let Some(non_structural_match_ty) =
827-
traits::search_for_structural_match_violation(param.span, tcx, ty)
827+
traits::search_for_structural_match_violation(param.span, tcx, ty, false)
828828
{
829829
// We use the same error code in both branches, because this is really the same
830830
// issue: we just special-case the message for type parameters to make it
831831
// clearer.
832-
if let ty::Param(_) = ty.peel_refs().kind() {
833-
// Const parameters may not have type parameters as their types,
834-
// because we cannot be sure that the type parameter derives `PartialEq`
835-
// and `Eq` (just implementing them is not enough for `structural_match`).
836-
struct_span_err!(
837-
tcx.sess,
838-
hir_ty.span,
839-
E0741,
840-
"`{}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
841-
used as the type of a const parameter",
842-
ty,
843-
)
844-
.span_label(
845-
hir_ty.span,
846-
format!("`{}` may not derive both `PartialEq` and `Eq`", ty),
847-
)
848-
.note(
849-
"it is not currently possible to use a type parameter as the type of a \
850-
const parameter",
851-
)
852-
.emit();
853-
} else {
854-
let mut diag = struct_span_err!(
855-
tcx.sess,
856-
hir_ty.span,
857-
E0741,
858-
"`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
859-
the type of a const parameter",
860-
non_structural_match_ty.ty,
861-
);
862-
863-
if ty == non_structural_match_ty.ty {
864-
diag.span_label(
832+
match ty.peel_refs().kind() {
833+
ty::Param(_) => {
834+
// Const parameters may not have type parameters as their types,
835+
// because we cannot be sure that the type parameter derives `PartialEq`
836+
// and `Eq` (just implementing them is not enough for `structural_match`).
837+
struct_span_err!(
838+
tcx.sess,
865839
hir_ty.span,
866-
format!("`{ty}` doesn't derive both `PartialEq` and `Eq`"),
867-
);
840+
E0741,
841+
"`{ty}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
842+
used as the type of a const parameter",
843+
)
844+
.span_label(
845+
hir_ty.span,
846+
format!("`{ty}` may not derive both `PartialEq` and `Eq`"),
847+
)
848+
.note(
849+
"it is not currently possible to use a type parameter as the type of a \
850+
const parameter",
851+
)
852+
.emit();
853+
}
854+
ty::Float(_) => {
855+
struct_span_err!(
856+
tcx.sess,
857+
hir_ty.span,
858+
E0741,
859+
"`{ty}` is forbidden as the type of a const generic parameter",
860+
)
861+
.note("floats do not derive `Eq` or `Ord`, which are required for const parameters")
862+
.emit();
868863
}
864+
_ => {
865+
let mut diag = struct_span_err!(
866+
tcx.sess,
867+
hir_ty.span,
868+
E0741,
869+
"`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
870+
the type of a const parameter",
871+
non_structural_match_ty.ty,
872+
);
869873

870-
diag.emit();
874+
if ty == non_structural_match_ty.ty {
875+
diag.span_label(
876+
hir_ty.span,
877+
format!("`{ty}` doesn't derive both `PartialEq` and `Eq`"),
878+
);
879+
}
880+
881+
diag.emit();
882+
}
871883
}
872884
}
873885
} else {

‎compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
812812
/// Builds the `type defined here` message.
813813
fn show_definition(&self, err: &mut Diagnostic) {
814814
let mut spans: MultiSpan = if let Some(def_span) = self.tcx.def_ident_span(self.def_id) {
815-
if self.tcx.sess.source_map().span_to_snippet(def_span).is_ok() {
815+
if self.tcx.sess.source_map().is_span_accessible(def_span) {
816816
def_span.into()
817817
} else {
818818
return;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0741]: `f32` is forbidden as the type of a const generic parameter
2+
--> $DIR/float-generic.rs:5:17
3+
|
4+
LL | fn foo<const F: f32>() {}
5+
| ^^^
6+
|
7+
= note: floats do not derive `Eq` or `Ord`, which are required for const parameters
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0741`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// revisions: simple adt_const_params
2+
#![cfg_attr(adt_const_params, feature(adt_const_params))]
3+
#![cfg_attr(adt_const_params, allow(incomplete_features))]
4+
5+
fn foo<const F: f32>() {}
6+
//~^ ERROR `f32` is forbidden as the type of a const generic parameter
7+
8+
const C: f32 = 1.0;
9+
10+
fn main() {
11+
foo::<C>();
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: `f32` is forbidden as the type of a const generic parameter
2+
--> $DIR/float-generic.rs:5:17
3+
|
4+
LL | fn foo<const F: f32>() {}
5+
| ^^^
6+
|
7+
= note: the only supported types are integers, `bool` and `char`
8+
= help: more complex types are supported with `#![feature(adt_const_params)]`
9+
10+
error: aborting due to previous error
11+

‎src/test/ui/parser/macro/macro-doc-comments-1.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ LL | macro_rules! outer {
55
| ------------------ when calling this macro
66
...
77
LL | //! Inner
8-
| ^^^^^^^^^ no rules expected this token in macro call
8+
| ^^^^^^^^^
9+
| |
10+
| no rules expected this token in macro call
11+
| inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match
912

1013
error: aborting due to previous error
1114

‎src/test/ui/parser/macro/macro-doc-comments-2.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ LL | macro_rules! inner {
55
| ------------------ when calling this macro
66
...
77
LL | /// Outer
8-
| ^^^^^^^^^ no rules expected this token in macro call
8+
| ^^^^^^^^^
9+
| |
10+
| no rules expected this token in macro call
11+
| outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match
912

1013
error: aborting due to previous error
1114

‎src/test/ui/resolve/issue-55673.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
trait Foo {
2+
type Bar;
3+
}
4+
5+
fn foo<T: Foo>()
6+
where
7+
T::Baa: std::fmt::Debug,
8+
//~^ ERROR associated type `Baa` not found for `T`
9+
{
10+
}
11+
12+
fn main() {}
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0220]: associated type `Baa` not found for `T`
2+
--> $DIR/issue-55673.rs:7:8
3+
|
4+
LL | T::Baa: std::fmt::Debug,
5+
| ^^^ there is a similarly named associated type `Bar` in the trait `Foo`
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0220`.
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
pub trait Meow {
2+
fn meow(&self) {}
3+
}
4+
5+
pub struct GlobalMeow;
6+
7+
impl Meow for GlobalMeow {}
8+
9+
pub(crate) struct PrivateMeow;
10+
11+
impl Meow for PrivateMeow {}
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// aux-build:meow.rs
2+
3+
extern crate meow;
4+
5+
use meow::Meow;
6+
7+
fn needs_meow<T: Meow>(t: T) {}
8+
9+
fn main() {
10+
needs_meow(1usize);
11+
//~^ ERROR the trait bound `usize: Meow` is not satisfied
12+
}
13+
14+
struct LocalMeow;
15+
16+
impl Meow for LocalMeow {}
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0277]: the trait bound `usize: Meow` is not satisfied
2+
--> $DIR/issue-99080.rs:10:16
3+
|
4+
LL | needs_meow(1usize);
5+
| ---------- ^^^^^^ the trait `Meow` is not implemented for `usize`
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
= help: the following other types implement trait `Meow`:
10+
GlobalMeow
11+
LocalMeow
12+
note: required by a bound in `needs_meow`
13+
--> $DIR/issue-99080.rs:7:18
14+
|
15+
LL | fn needs_meow<T: Meow>(t: T) {}
16+
| ^^^^ required by this bound in `needs_meow`
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0277`.

‎src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ LL | s.strip_suffix(b'\n').unwrap_or(s)
1515
&'c &'b str
1616
[char; N]
1717
char
18-
pattern::MultiCharEqPattern<C>
1918
= note: required because of the requirements on the impl of `Pattern<'_>` for `u8`
2019

2120
error: aborting due to previous error

‎src/test/ui/traits/issue-59029-1.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error[E0220]: associated type `Res` not found for `Self`
22
--> $DIR/issue-59029-1.rs:5:52
33
|
44
LL | trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
5-
| ^^^ associated type `Res` not found
5+
| ^^^ there is a similarly named associated type `Res` in the trait `Svc`
66

77
error[E0220]: associated type `Res` not found for `Self`
88
--> $DIR/issue-59029-1.rs:5:52
99
|
1010
LL | trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
11-
| ^^^ associated type `Res` not found
11+
| ^^^ there is a similarly named associated type `Res` in the trait `Svc`
1212

1313
error: aborting due to 2 previous errors
1414

‎src/test/ui/type-alias-impl-trait/not_well_formed.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0220]: associated type `Assoc` not found for `V`
22
--> $DIR/not_well_formed.rs:9:29
33
|
44
LL | type Foo<V> = impl Trait<V::Assoc>;
5-
| ^^^^^ associated type `Assoc` not found
5+
| ^^^^^ there is a similarly named associated type `Assoc` in the trait `TraitWithAssoc`
66

77
error: aborting due to previous error
88

0 commit comments

Comments
 (0)
Please sign in to comment.