Skip to content

Commit 646f58a

Browse files
committed
Lint bare traits in AstConv.
1 parent 887999d commit 646f58a

File tree

45 files changed

+366
-297
lines changed

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

+366
-297
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 3 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ use rustc_data_structures::fx::FxHashSet;
4747
use rustc_data_structures::sorted_map::SortedMap;
4848
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
4949
use rustc_data_structures::sync::Lrc;
50-
use rustc_errors::{struct_span_err, Applicability};
50+
use rustc_errors::struct_span_err;
5151
use rustc_hir as hir;
5252
use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
5353
use rustc_hir::def_id::{DefId, DefPathHash, LocalDefId, CRATE_DEF_ID};
@@ -56,11 +56,9 @@ use rustc_hir::intravisit;
5656
use rustc_hir::{ConstArg, GenericArg, InferKind, ParamName};
5757
use rustc_index::vec::{Idx, IndexVec};
5858
use rustc_query_system::ich::StableHashingContext;
59-
use rustc_session::lint::builtin::BARE_TRAIT_OBJECTS;
60-
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
59+
use rustc_session::lint::LintBuffer;
6160
use rustc_session::utils::{FlattenNonterminals, NtToTokenstream};
6261
use rustc_session::Session;
63-
use rustc_span::edition::Edition;
6462
use rustc_span::hygiene::ExpnId;
6563
use rustc_span::source_map::{respan, DesugaringKind};
6664
use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -1190,11 +1188,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
11901188
) -> hir::Ty<'hir> {
11911189
let id = self.lower_node_id(t.id);
11921190
let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx);
1193-
let ty = self.ty_path(id, t.span, qpath);
1194-
if let hir::TyKind::TraitObject(..) = ty.kind {
1195-
self.maybe_lint_bare_trait(t.span, t.id, qself.is_none() && path.is_global());
1196-
}
1197-
ty
1191+
self.ty_path(id, t.span, qpath)
11981192
}
11991193

12001194
fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
@@ -1291,9 +1285,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12911285
lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
12921286
(bounds, lifetime_bound)
12931287
});
1294-
if kind != TraitObjectSyntax::Dyn {
1295-
self.maybe_lint_bare_trait(t.span, t.id, false);
1296-
}
12971288
hir::TyKind::TraitObject(bounds, lifetime_bound, kind)
12981289
}
12991290
TyKind::ImplTrait(def_node_id, ref bounds) => {
@@ -2395,39 +2386,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23952386
name: hir::LifetimeName::Implicit(missing),
23962387
}
23972388
}
2398-
2399-
fn maybe_lint_bare_trait(&mut self, span: Span, id: NodeId, is_global: bool) {
2400-
// FIXME(davidtwco): This is a hack to detect macros which produce spans of the
2401-
// call site which do not have a macro backtrace. See #61963.
2402-
let is_macro_callsite = self
2403-
.sess
2404-
.source_map()
2405-
.span_to_snippet(span)
2406-
.map(|snippet| snippet.starts_with("#["))
2407-
.unwrap_or(true);
2408-
if !is_macro_callsite {
2409-
if span.edition() < Edition::Edition2021 {
2410-
self.resolver.lint_buffer().buffer_lint_with_diagnostic(
2411-
BARE_TRAIT_OBJECTS,
2412-
id,
2413-
span,
2414-
"trait objects without an explicit `dyn` are deprecated",
2415-
BuiltinLintDiagnostics::BareTraitObject(span, is_global),
2416-
)
2417-
} else {
2418-
let msg = "trait objects must include the `dyn` keyword";
2419-
let label = "add `dyn` keyword before this trait";
2420-
let mut err = struct_span_err!(self.sess, span, E0782, "{}", msg,);
2421-
err.span_suggestion_verbose(
2422-
span.shrink_to_lo(),
2423-
label,
2424-
String::from("dyn "),
2425-
Applicability::MachineApplicable,
2426-
);
2427-
err.emit();
2428-
}
2429-
}
2430-
}
24312389
}
24322390

24332391
/// Helper struct for delayed construction of GenericArgs.

compiler/rustc_lint/src/context.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -635,16 +635,6 @@ pub trait LintContext: Sized {
635635
}
636636
},
637637
BuiltinLintDiagnostics::Normal => (),
638-
BuiltinLintDiagnostics::BareTraitObject(span, is_global) => {
639-
let (sugg, app) = match sess.source_map().span_to_snippet(span) {
640-
Ok(s) if is_global => {
641-
(format!("dyn ({})", s), Applicability::MachineApplicable)
642-
}
643-
Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
644-
Err(_) => ("dyn <type>".to_string(), Applicability::HasPlaceholders),
645-
};
646-
db.span_suggestion(span, "use `dyn`", sugg, app);
647-
}
648638
BuiltinLintDiagnostics::AbsPathWithModule(span) => {
649639
let (sugg, app) = match sess.source_map().span_to_snippet(span) {
650640
Ok(ref s) => {

compiler/rustc_lint_defs/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,6 @@ pub enum ExternDepSpec {
285285
#[derive(PartialEq, Debug)]
286286
pub enum BuiltinLintDiagnostics {
287287
Normal,
288-
BareTraitObject(Span, /* is_global */ bool),
289288
AbsPathWithModule(Span),
290289
ProcMacroDeriveResolutionFallback(Span),
291290
MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),

compiler/rustc_typeck/src/astconv/mod.rs

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::errors::{
1313
};
1414
use crate::middle::resolve_lifetime as rl;
1515
use crate::require_c_abi_if_c_variadic;
16+
use rustc_ast::TraitObjectSyntax;
1617
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1718
use rustc_errors::{struct_span_err, Applicability, ErrorReported, FatalError};
1819
use rustc_hir as hir;
@@ -24,7 +25,8 @@ use rustc_hir::{GenericArg, GenericArgs};
2425
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, Subst, SubstsRef};
2526
use rustc_middle::ty::GenericParamDefKind;
2627
use rustc_middle::ty::{self, Const, DefIdTree, Ty, TyCtxt, TypeFoldable};
27-
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
28+
use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS};
29+
use rustc_span::edition::Edition;
2830
use rustc_span::lev_distance::find_best_match_for_name;
2931
use rustc_span::symbol::{Ident, Symbol};
3032
use rustc_span::{Span, DUMMY_SP};
@@ -2289,13 +2291,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
22892291
/// Parses the programmer's textual representation of a type into our
22902292
/// internal notion of a type.
22912293
pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
2292-
self.ast_ty_to_ty_inner(ast_ty, false)
2294+
self.ast_ty_to_ty_inner(ast_ty, false, false)
2295+
}
2296+
2297+
/// Parses the programmer's textual representation of a type into our
2298+
/// internal notion of a type. This is meant to be used within a path.
2299+
pub fn ast_ty_to_ty_in_path(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
2300+
self.ast_ty_to_ty_inner(ast_ty, false, true)
22932301
}
22942302

22952303
/// Turns a `hir::Ty` into a `Ty`. For diagnostics' purposes we keep track of whether trait
22962304
/// objects are borrowed like `&dyn Trait` to avoid emitting redundant errors.
22972305
#[tracing::instrument(level = "debug", skip(self))]
2298-
fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool) -> Ty<'tcx> {
2306+
fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool, in_path: bool) -> Ty<'tcx> {
22992307
let tcx = self.tcx();
23002308

23012309
let result_ty = match ast_ty.kind {
@@ -2306,7 +2314,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
23062314
hir::TyKind::Rptr(ref region, ref mt) => {
23072315
let r = self.ast_region_to_region(region, None);
23082316
debug!(?r);
2309-
let t = self.ast_ty_to_ty_inner(mt.ty, true);
2317+
let t = self.ast_ty_to_ty_inner(mt.ty, true, false);
23102318
tcx.mk_ref(r, ty::TypeAndMut { ty: t, mutbl: mt.mutbl })
23112319
}
23122320
hir::TyKind::Never => tcx.types.never,
@@ -2325,6 +2333,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
23252333
))
23262334
}
23272335
hir::TyKind::TraitObject(bounds, ref lifetime, _) => {
2336+
self.maybe_lint_bare_trait(ast_ty, in_path);
23282337
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed)
23292338
}
23302339
hir::TyKind::Path(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
@@ -2345,7 +2354,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
23452354
}
23462355
hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {
23472356
debug!(?qself, ?segment);
2348-
let ty = self.ast_ty_to_ty(qself);
2357+
let ty = self.ast_ty_to_ty_inner(qself, false, true);
23492358

23502359
let res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = qself.kind {
23512360
path.res
@@ -2602,4 +2611,49 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
26022611
}
26032612
Some(r)
26042613
}
2614+
2615+
fn maybe_lint_bare_trait(&self, self_ty: &hir::Ty<'_>, in_path: bool) {
2616+
let tcx = self.tcx();
2617+
if let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
2618+
self_ty.kind
2619+
{
2620+
let (mut sugg, app) = match tcx.sess.source_map().span_to_snippet(self_ty.span) {
2621+
Ok(s) if poly_trait_ref.trait_ref.path.is_global() => {
2622+
(format!("dyn ({})", s), Applicability::MachineApplicable)
2623+
}
2624+
Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
2625+
Err(_) => ("dyn <type>".to_string(), Applicability::HasPlaceholders),
2626+
};
2627+
if in_path {
2628+
let has_bracket = tcx
2629+
.sess
2630+
.source_map()
2631+
.span_to_prev_source(self_ty.span)
2632+
.ok()
2633+
.map_or(false, |s| s.trim_end().ends_with('<'));
2634+
if !has_bracket {
2635+
sugg = format!("<{}>", sugg);
2636+
}
2637+
}
2638+
if tcx.sess.edition() >= Edition::Edition2021 {
2639+
let msg = "trait objects must include the `dyn` keyword";
2640+
let label = "add `dyn` keyword before this trait";
2641+
let mut err =
2642+
rustc_errors::struct_span_err!(tcx.sess, self_ty.span, E0782, "{}", msg);
2643+
err.span_suggestion_verbose(self_ty.span, label, sugg, app).emit();
2644+
} else {
2645+
let msg = "trait objects without an explicit `dyn` are deprecated";
2646+
tcx.struct_span_lint_hir(
2647+
BARE_TRAIT_OBJECTS,
2648+
self_ty.hir_id,
2649+
self_ty.span,
2650+
|lint| {
2651+
let mut db = lint.build(msg);
2652+
db.span_suggestion(self_ty.span, "use `dyn`", sugg, app);
2653+
db.emit()
2654+
},
2655+
);
2656+
}
2657+
}
2658+
}
26052659
}

compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs

Lines changed: 2 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@ use crate::check::callee::{self, DeferredCallResolution};
66
use crate::check::method::{self, MethodCallee, SelfSource};
77
use crate::check::{BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy};
88

9-
use rustc_ast::TraitObjectSyntax;
109
use rustc_data_structures::captures::Captures;
1110
use rustc_data_structures::fx::FxHashSet;
1211
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorReported};
1312
use rustc_hir as hir;
1413
use rustc_hir::def::{CtorOf, DefKind, Res};
1514
use rustc_hir::def_id::DefId;
1615
use rustc_hir::lang_items::LangItem;
17-
use rustc_hir::{ExprKind, GenericArg, Node, QPath, TyKind};
16+
use rustc_hir::{ExprKind, GenericArg, Node, QPath};
1817
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
1918
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
2019
use rustc_infer::infer::{InferOk, InferResult};
@@ -28,8 +27,6 @@ use rustc_middle::ty::{
2827
Ty, UserType,
2928
};
3029
use rustc_session::lint;
31-
use rustc_session::lint::builtin::BARE_TRAIT_OBJECTS;
32-
use rustc_span::edition::Edition;
3330
use rustc_span::hygiene::DesugaringKind;
3431
use rustc_span::source_map::{original_sp, DUMMY_SP};
3532
use rustc_span::symbol::{kw, sym, Ident};
@@ -844,7 +841,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
844841
// to be object-safe.
845842
// We manually call `register_wf_obligation` in the success path
846843
// below.
847-
(<dyn AstConv<'_>>::ast_ty_to_ty(self, qself), qself, segment)
844+
(<dyn AstConv<'_>>::ast_ty_to_ty_in_path(self, qself), qself, segment)
848845
}
849846
QPath::LangItem(..) => {
850847
bug!("`resolve_ty_and_res_fully_qualified_call` called on `LangItem`")
@@ -890,7 +887,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
890887
});
891888

892889
if result.is_ok() {
893-
self.maybe_lint_bare_trait(qpath, hir_id, span);
894890
self.register_wf_obligation(ty.into(), qself.span, traits::WellFormed(None));
895891
}
896892

@@ -903,56 +899,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
903899
)
904900
}
905901

906-
fn maybe_lint_bare_trait(&self, qpath: &QPath<'_>, hir_id: hir::HirId, span: Span) {
907-
if let QPath::TypeRelative(self_ty, _) = qpath {
908-
if let TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
909-
self_ty.kind
910-
{
911-
let msg = "trait objects without an explicit `dyn` are deprecated";
912-
let (sugg, app) = match self.tcx.sess.source_map().span_to_snippet(self_ty.span) {
913-
Ok(s) if poly_trait_ref.trait_ref.path.is_global() => {
914-
(format!("dyn ({})", s), Applicability::MachineApplicable)
915-
}
916-
Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
917-
Err(_) => ("dyn <type>".to_string(), Applicability::HasPlaceholders),
918-
};
919-
// Wrap in `<..>` if it isn't already.
920-
let sugg = match self.tcx.sess.source_map().span_to_snippet(span) {
921-
Ok(s) if s.starts_with('<') => sugg,
922-
_ => format!("<{}>", sugg),
923-
};
924-
let sugg_label = "use `dyn`";
925-
if self.sess().edition() >= Edition::Edition2021 {
926-
let mut err = rustc_errors::struct_span_err!(
927-
self.sess(),
928-
self_ty.span,
929-
E0782,
930-
"{}",
931-
msg,
932-
);
933-
err.span_suggestion(
934-
self_ty.span,
935-
sugg_label,
936-
sugg,
937-
Applicability::MachineApplicable,
938-
)
939-
.emit();
940-
} else {
941-
self.tcx.struct_span_lint_hir(
942-
BARE_TRAIT_OBJECTS,
943-
hir_id,
944-
self_ty.span,
945-
|lint| {
946-
let mut db = lint.build(msg);
947-
db.span_suggestion(self_ty.span, sugg_label, sugg, app);
948-
db.emit()
949-
},
950-
);
951-
}
952-
}
953-
}
954-
}
955-
956902
/// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
957903
pub(in super::super) fn get_node_fn_decl(
958904
&self,

src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ fn b() {
1212
//~^ ERROR expected trait, found constant `BAR`
1313
//~| ERROR expected trait, found constant `BAR`
1414
//~| ERROR type provided when a constant was expected
15-
//~| WARN trait objects without an explicit `dyn` are deprecated
16-
//~| WARN this is accepted in the current edition
1715
}
1816
fn c() {
1917
foo::<3 + 3>(); //~ ERROR expressions must be enclosed in braces

0 commit comments

Comments
 (0)