Skip to content

Commit b48530b

Browse files
committed
Report missing cases of bare_trait_objects
1 parent 38ed36b commit b48530b

File tree

4 files changed

+81
-2
lines changed

4 files changed

+81
-2
lines changed

compiler/rustc_typeck/src/astconv/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1608,6 +1608,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16081608
// the whole path.
16091609
// Will fail except for `T::A` and `Self::A`; i.e., if `qself_ty`/`qself_def` are not a type
16101610
// parameter or `Self`.
1611+
// NOTE: When this function starts resolving `Trait::AssocTy` successfully
1612+
// it should also start reportint the `BARE_TRAIT_OBJECTS` lint.
16111613
pub fn associated_path_to_ty(
16121614
&self,
16131615
hir_ref_id: hir::HirId,

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

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

9+
use rustc_ast::TraitObjectSyntax;
910
use rustc_data_structures::captures::Captures;
1011
use rustc_data_structures::fx::FxHashSet;
1112
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorReported};
1213
use rustc_hir as hir;
1314
use rustc_hir::def::{CtorOf, DefKind, Res};
1415
use rustc_hir::def_id::DefId;
1516
use rustc_hir::lang_items::LangItem;
16-
use rustc_hir::{ExprKind, GenericArg, Node, QPath};
17+
use rustc_hir::{ExprKind, GenericArg, Node, QPath, TyKind};
1718
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
1819
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
1920
use rustc_infer::infer::{InferOk, InferResult};
@@ -26,7 +27,9 @@ use rustc_middle::ty::{
2627
self, AdtKind, CanonicalUserType, DefIdTree, GenericParamDefKind, ToPolyTraitRef, ToPredicate,
2728
Ty, UserType,
2829
};
29-
use rustc_session::{lint, parse::feature_err};
30+
use rustc_session::lint;
31+
use rustc_session::lint::builtin::BARE_TRAIT_OBJECTS;
32+
use rustc_session::parse::feature_err;
3033
use rustc_span::source_map::{original_sp, DUMMY_SP};
3134
use rustc_span::symbol::{kw, sym, Ident};
3235
use rustc_span::{self, BytePos, MultiSpan, Span};
@@ -947,6 +950,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
947950
result
948951
});
949952

953+
if result.is_ok() {
954+
self.maybe_lint_bare_trait(qpath, hir_id);
955+
}
956+
950957
// Write back the new resolution.
951958
self.write_resolution(hir_id, result);
952959
(
@@ -956,6 +963,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
956963
)
957964
}
958965

966+
fn maybe_lint_bare_trait(&self, qpath: &QPath<'_>, hir_id: hir::HirId) {
967+
if let QPath::TypeRelative(self_ty, _) = qpath {
968+
if let TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
969+
self_ty.kind
970+
{
971+
self.tcx.struct_span_lint_hir(BARE_TRAIT_OBJECTS, hir_id, self_ty.span, |lint| {
972+
let mut db = lint
973+
.build(&format!("trait objects without an explicit `dyn` are deprecated"));
974+
let (sugg, app) = match self.tcx.sess.source_map().span_to_snippet(self_ty.span)
975+
{
976+
Ok(s) if poly_trait_ref.trait_ref.path.is_global() => {
977+
(format!("<dyn ({})>", s), Applicability::MachineApplicable)
978+
}
979+
Ok(s) => (format!("<dyn {}>", s), Applicability::MachineApplicable),
980+
Err(_) => ("<dyn <type>>".to_string(), Applicability::HasPlaceholders),
981+
};
982+
db.span_suggestion(self_ty.span, "use `dyn`", sugg, app);
983+
db.emit()
984+
});
985+
}
986+
}
987+
}
988+
959989
/// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
960990
pub(in super::super) fn get_node_fn_decl(
961991
&self,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![feature(associated_type_defaults)]
2+
3+
trait Assoc {
4+
fn func() {}
5+
const CONST: u8 = 0;
6+
type Ty = u8;
7+
}
8+
9+
trait Dyn {}
10+
11+
impl Assoc for dyn Dyn {}
12+
13+
fn main() {
14+
Dyn::func(); //~ WARN trait objects without an explicit `dyn` are deprecated
15+
::Dyn::func(); //~ WARN trait objects without an explicit `dyn` are deprecated
16+
Dyn::CONST; //~ WARN trait objects without an explicit `dyn` are deprecated
17+
let _: Dyn::Ty; //~ ERROR ambiguous associated type
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0223]: ambiguous associated type
2+
--> $DIR/bare-trait-objects-path.rs:17:12
3+
|
4+
LL | let _: Dyn::Ty;
5+
| ^^^^^^^ help: use fully-qualified syntax: `<dyn Dyn as Trait>::Ty`
6+
7+
warning: trait objects without an explicit `dyn` are deprecated
8+
--> $DIR/bare-trait-objects-path.rs:14:5
9+
|
10+
LL | Dyn::func();
11+
| ^^^ help: use `dyn`: `<dyn Dyn>`
12+
|
13+
= note: `#[warn(bare_trait_objects)]` on by default
14+
15+
warning: trait objects without an explicit `dyn` are deprecated
16+
--> $DIR/bare-trait-objects-path.rs:15:5
17+
|
18+
LL | ::Dyn::func();
19+
| ^^^^^ help: use `dyn`: `<dyn (::Dyn)>`
20+
21+
warning: trait objects without an explicit `dyn` are deprecated
22+
--> $DIR/bare-trait-objects-path.rs:16:5
23+
|
24+
LL | Dyn::CONST;
25+
| ^^^ help: use `dyn`: `<dyn Dyn>`
26+
27+
error: aborting due to previous error; 3 warnings emitted
28+
29+
For more information about this error, try `rustc --explain E0223`.

0 commit comments

Comments
 (0)