|
3 | 3 |
|
4 | 4 | use rustc_data_structures::fx::FxHashSet;
|
5 | 5 | use rustc_errors::struct_span_err;
|
6 |
| -use rustc_errors::ErrorGuaranteed; |
| 6 | +use rustc_errors::{Diagnostic, ErrorGuaranteed}; |
7 | 7 | use rustc_hir as hir;
|
8 | 8 | use rustc_infer::infer::TyCtxtInferExt;
|
9 | 9 | use rustc_middle::ty::subst::GenericArgKind;
|
@@ -107,6 +107,7 @@ fn do_orphan_check_impl<'tcx>(
|
107 | 107 | Err(err) => emit_orphan_check_error(
|
108 | 108 | tcx,
|
109 | 109 | sp,
|
| 110 | + item.span, |
110 | 111 | tr.path.span,
|
111 | 112 | trait_ref.self_ty(),
|
112 | 113 | impl_.self_ty.span,
|
@@ -207,6 +208,7 @@ fn do_orphan_check_impl<'tcx>(
|
207 | 208 | fn emit_orphan_check_error<'tcx>(
|
208 | 209 | tcx: TyCtxt<'tcx>,
|
209 | 210 | sp: Span,
|
| 211 | + full_impl_span: Span, |
210 | 212 | trait_span: Span,
|
211 | 213 | self_ty: Ty<'tcx>,
|
212 | 214 | self_ty_span: Span,
|
@@ -247,8 +249,20 @@ fn emit_orphan_check_error<'tcx>(
|
247 | 249 | ty::Slice(_) => (this, " because slices are always foreign"),
|
248 | 250 | ty::Array(..) => (this, " because arrays are always foreign"),
|
249 | 251 | ty::Tuple(..) => (this, " because tuples are always foreign"),
|
| 252 | + ty::RawPtr(ptr_ty) => { |
| 253 | + emit_newtype_suggestion_for_raw_ptr( |
| 254 | + full_impl_span, |
| 255 | + self_ty, |
| 256 | + self_ty_span, |
| 257 | + ptr_ty, |
| 258 | + &mut err, |
| 259 | + ); |
| 260 | + |
| 261 | + (format!("`{}`", ty), " because raw pointers are always foreign") |
| 262 | + } |
250 | 263 | _ => (format!("`{}`", ty), ""),
|
251 | 264 | };
|
| 265 | + |
252 | 266 | let msg = format!("{} is not defined in the current crate{}", ty, postfix);
|
253 | 267 | if *is_target_ty {
|
254 | 268 | // Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
|
@@ -330,6 +344,27 @@ fn emit_orphan_check_error<'tcx>(
|
330 | 344 | })
|
331 | 345 | }
|
332 | 346 |
|
| 347 | +fn emit_newtype_suggestion_for_raw_ptr( |
| 348 | + full_impl_span: Span, |
| 349 | + self_ty: Ty<'_>, |
| 350 | + self_ty_span: Span, |
| 351 | + ptr_ty: &ty::TypeAndMut<'_>, |
| 352 | + diag: &mut Diagnostic, |
| 353 | +) { |
| 354 | + if !self_ty.needs_subst() { |
| 355 | + let mut_key = if ptr_ty.mutbl == rustc_middle::mir::Mutability::Mut { "mut " } else { "" }; |
| 356 | + let msg_sugg = "consider introducing a new wrapper type".to_owned(); |
| 357 | + let sugg = vec![ |
| 358 | + ( |
| 359 | + full_impl_span.shrink_to_lo(), |
| 360 | + format!("struct WrapperType(*{}{});\n\n", mut_key, ptr_ty.ty), |
| 361 | + ), |
| 362 | + (self_ty_span, "WrapperType".to_owned()), |
| 363 | + ]; |
| 364 | + diag.multipart_suggestion(msg_sugg, sugg, rustc_errors::Applicability::MaybeIncorrect); |
| 365 | + } |
| 366 | +} |
| 367 | + |
333 | 368 | /// Lint impls of auto traits if they are likely to have
|
334 | 369 | /// unsound or surprising effects on auto impls.
|
335 | 370 | fn lint_auto_trait_impl<'tcx>(
|
|
0 commit comments