Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ fn generic_arg_mismatch_err(
) => match path.res {
Res::Err => {
add_braces_suggestion(arg, &mut err);
return err
.with_primary_message("unresolved item provided when a constant was expected")
.emit();
err.primary_message("unresolved item provided when a constant was expected");
// A resolve error will already have been emitted pointing at this.
return err.delay_as_bug();
}
Res::Def(DefKind::TyParam, src_def_id) => {
if let Some(param_local_id) = param.def_id.as_local() {
Expand Down
33 changes: 31 additions & 2 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,8 @@ pub(crate) enum AliasPossibility {
pub(crate) enum PathSource<'a, 'ast, 'ra> {
/// Type paths `Path`.
Type,
/// Type or constant in a `PathSegment` argument.
TypeParam,
/// Trait paths in bounds or impls.
Trait(AliasPossibility),
/// Expression paths `path`, with optional parent context.
Expand Down Expand Up @@ -453,6 +455,7 @@ impl PathSource<'_, '_, '_> {
fn namespace(self) -> Namespace {
match self {
PathSource::Type
| PathSource::TypeParam
| PathSource::Trait(_)
| PathSource::Struct(_)
| PathSource::DefineOpaques => TypeNS,
Expand All @@ -469,6 +472,7 @@ impl PathSource<'_, '_, '_> {
fn defer_to_typeck(self) -> bool {
match self {
PathSource::Type
| PathSource::TypeParam
| PathSource::Expr(..)
| PathSource::Pat
| PathSource::Struct(_)
Expand All @@ -486,6 +490,7 @@ impl PathSource<'_, '_, '_> {
match &self {
PathSource::DefineOpaques => "type alias or associated type with opaqaue types",
PathSource::Type => "type",
PathSource::TypeParam => "type or constant",
PathSource::Trait(_) => "trait",
PathSource::Pat => "unit struct, unit variant or constant",
PathSource::Struct(_) => "struct, variant or union type",
Expand Down Expand Up @@ -560,6 +565,29 @@ impl PathSource<'_, '_, '_> {
| Res::SelfTyParam { .. }
| Res::SelfTyAlias { .. }
),
PathSource::TypeParam => matches!(
res,
Res::Def(
DefKind::Struct
| DefKind::Union
| DefKind::Enum
| DefKind::Trait
| DefKind::TraitAlias
| DefKind::TyAlias
| DefKind::AssocTy
| DefKind::TyParam
| DefKind::OpaqueTy
| DefKind::AnonConst
| DefKind::AssocConst
| DefKind::Const
| DefKind::ConstParam
| DefKind::InlineConst
| DefKind::ForeignTy,
_,
) | Res::PrimTy(..)
| Res::SelfTyParam { .. }
| Res::SelfTyAlias { .. }
),
PathSource::Trait(AliasPossibility::No) => matches!(res, Res::Def(DefKind::Trait, _)),
PathSource::Trait(AliasPossibility::Maybe) => {
matches!(res, Res::Def(DefKind::Trait | DefKind::TraitAlias, _))
Expand Down Expand Up @@ -621,8 +649,8 @@ impl PathSource<'_, '_, '_> {
match (self, has_unexpected_resolution) {
(PathSource::Trait(_), true) => E0404,
(PathSource::Trait(_), false) => E0405,
(PathSource::Type | PathSource::DefineOpaques, true) => E0573,
(PathSource::Type | PathSource::DefineOpaques, false) => E0425,
(PathSource::Type | PathSource::DefineOpaques | PathSource::TypeParam, true) => E0573,
(PathSource::Type | PathSource::DefineOpaques | PathSource::TypeParam, false) => E0425,
(PathSource::Struct(_), true) => E0574,
(PathSource::Struct(_), false) => E0422,
(PathSource::Expr(..), true) | (PathSource::Delegation, true) => E0423,
Expand Down Expand Up @@ -2129,6 +2157,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
PathSource::Trait(..)
| PathSource::TraitItem(..)
| PathSource::Type
| PathSource::TypeParam
| PathSource::PreciseCapturingArg(..)
| PathSource::ReturnTypeNotation => false,
PathSource::Expr(..)
Expand Down
16 changes: 12 additions & 4 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -769,9 +769,11 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
Ok(s.get(start - 1..start) == Some("{"))
});
if let Ok(true) = field_is_format_named_arg {
err.help(
format!("you might have meant to use the available field in a format string: `\"{{}}\", self.{}`", segment.ident.name),
);
err.help(format!(
"you might have meant to use the available field in a format \
string: `\"{{}}\", self.{}`",
segment.ident.name,
));
} else {
err.span_suggestion_verbose(
span.shrink_to_lo(),
Expand Down Expand Up @@ -1026,13 +1028,19 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
fn suggest_typo(
&mut self,
err: &mut Diag<'_>,
source: PathSource<'_, 'ast, 'ra>,
mut source: PathSource<'_, 'ast, 'ra>,
path: &[Segment],
following_seg: Option<&Segment>,
span: Span,
base_error: &BaseError,
suggested_candidates: FxHashSet<String>,
) -> bool {
if self.diag_metadata.currently_processing_generic_args
&& matches!(source, PathSource::Type)
{
source = PathSource::TypeParam;
}

let is_expected = &|res| source.is_expected(res);
let ident_span = path.last().map_or(span, |ident| ident.ident.span);
let typo_sugg =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
None
};

let mut delay_as_bug = false;
let mut infer_subdiags = Vec::new();
let mut multi_suggestions = Vec::new();
match kind {
Expand All @@ -513,7 +514,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
type_name: ty_to_string(self, ty, def_id),
});
}
InferSourceKind::ClosureArg { insert_span, ty, .. } => {
InferSourceKind::ClosureArg { insert_span, ty, kind, .. } => {
if let PatKind::Err(_) = kind {
// We will have already emitted an error about this pattern.
delay_as_bug = true;
}
infer_subdiags.push(SourceKindSubdiag::LetLike {
span: insert_span,
name: String::new(),
Expand All @@ -532,7 +537,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
def_id: _,
generic_args,
have_turbofish,
hir_id,
} => {
if let hir::Node::PathSegment(segment) = self.tcx.hir_node(hir_id)
&& let Some(args) = segment.args
&& let Some(hir::GenericArg::Type(ty)) = args.args.get(argument_index)
&& let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
&& let Res::Err = path.res
{
// We have already emitted a name resolution error.
delay_as_bug = true;
}
let generics = self.tcx.generics_of(generics_def_id);
let is_type = term.as_type().is_some();

Expand Down Expand Up @@ -653,8 +668,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}),
};
*err.long_ty_path() = long_ty_path;
if let InferSourceKind::ClosureArg { kind: PatKind::Err(_), .. } = kind {
// We will have already emitted an error about this pattern.
if delay_as_bug {
// We have already emitted an earlier more relevant error.
err.downgrade_to_delayed_bug();
}
err
Expand Down Expand Up @@ -687,6 +702,7 @@ enum InferSourceKind<'tcx> {
def_id: DefId,
generic_args: &'tcx [GenericArg<'tcx>],
have_turbofish: bool,
hir_id: HirId,
},
FullyQualifiedMethodCall {
receiver: &'tcx Expr<'tcx>,
Expand Down Expand Up @@ -751,6 +767,7 @@ struct InsertableGenericArgs<'tcx> {
generics_def_id: DefId,
def_id: DefId,
have_turbofish: bool,
hir_id: HirId,
}

/// A visitor which searches for the "best" spot to use in the inference error.
Expand Down Expand Up @@ -1013,6 +1030,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
generics_def_id: def_id,
def_id,
have_turbofish: false,
hir_id: expr.hir_id,
}
};
return Box::new(insertable.into_iter());
Expand Down Expand Up @@ -1052,6 +1070,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
generics_def_id,
def_id: path.res.def_id(),
have_turbofish,
hir_id: path.segments.last().unwrap().hir_id,
}
};

Expand All @@ -1072,6 +1091,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
generics_def_id,
def_id: res.def_id(),
have_turbofish,
hir_id: segment.hir_id,
})
})
.chain(last_segment_using_path_data)
Expand Down Expand Up @@ -1106,6 +1126,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
generics_def_id: def_id,
def_id,
have_turbofish: false,
hir_id: segment.hir_id,
}
};

Expand Down Expand Up @@ -1233,6 +1254,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
generics_def_id,
def_id,
have_turbofish,
hir_id,
} = args;
let generics = tcx.generics_of(generics_def_id);
if let Some(mut argument_index) = generics
Expand Down Expand Up @@ -1260,6 +1282,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
def_id,
generic_args,
have_turbofish,
hir_id,
},
});
}
Expand Down
1 change: 0 additions & 1 deletion tests/ui/const-generics/assoc_const_as_type_argument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ fn bar<const N: usize>() {}
fn foo<T: Trait>() {
bar::<<T as Trait>::ASSOC>();
//~^ ERROR: expected associated type, found associated constant `Trait::ASSOC`
//~| ERROR: unresolved item provided when a constant was expected
}

fn main() {}
16 changes: 2 additions & 14 deletions tests/ui/const-generics/assoc_const_as_type_argument.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,6 @@ error[E0575]: expected associated type, found associated constant `Trait::ASSOC`
LL | bar::<<T as Trait>::ASSOC>();
| ^^^^^^^^^^^^^^^^^^^ not a associated type

error[E0747]: unresolved item provided when a constant was expected
--> $DIR/assoc_const_as_type_argument.rs:8:11
|
LL | bar::<<T as Trait>::ASSOC>();
| ^^^^^^^^^^^^^^^^^^^
|
help: if this generic argument was intended as a const parameter, surround it with braces
|
LL | bar::<{ <T as Trait>::ASSOC }>();
| + +

error: aborting due to 2 previous errors
error: aborting due to 1 previous error

Some errors have detailed explanations: E0575, E0747.
For more information about an error, try `rustc --explain E0575`.
For more information about this error, try `rustc --explain E0575`.
Loading
Loading