Change:
If I understand correctly, type parameter defaults have no effect in the block . Just like in PR , this should have a warning and then an error. Example cc
Argh, I guess I failed to cover those?
Nominating for triage.
triage: P-high

Discussion:
// Create generics from the generics specified in the impl head. debug!("convert: ast_generics={:?}", generics); let def_id = ccx.tcx.map.local_def_id(it.id); <del> let ty_generics = ty_generics_for_type_or_impl(ccx, generics); </del> <ins> let ty_generics = ty_generics_for_impl(ccx, generics); </ins> let mut ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics); debug!("convert: impl_bounds={:?}", ty_predicates);

ty::TypeScheme { ty: ty, generics: ty_generics } } hir::ItemTy(ref t, ref generics) => { <del> let ty_generics = ty_generics_for_type_or_impl(ccx, generics); </del> <ins> let ty_generics = ty_generics_for_type(ccx, generics); </ins> let ty = ccx.icx(generics).to_ty(&ExplicitRscope, &t); ty::TypeScheme { ty: ty, generics: ty_generics } } hir::ItemEnum(ref ei, ref generics) => { <del> let ty_generics = ty_generics_for_type_or_impl(ccx, generics); </del> <ins> let ty_generics = ty_generics_for_type(ccx, generics); </ins> let substs = mk_item_substs(ccx, &ty_generics); let def = convert_enum_def(tcx, it, ei); let t = tcx.mk_enum(def, tcx.mk_substs(substs)); ty::TypeScheme { ty: t, generics: ty_generics } } hir::ItemStruct(ref si, ref generics) => { <del> let ty_generics = ty_generics_for_type_or_impl(ccx, generics); </del> <ins> let ty_generics = ty_generics_for_type(ccx, generics); </ins> let substs = mk_item_substs(ccx, &ty_generics); let def = convert_struct_def(tcx, it, si); let t = tcx.mk_struct(def, tcx.mk_substs(substs));

assert!(prev_predicates.is_none()); } <del> fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, generics: &hir::Generics) -> ty::Generics<'tcx> { ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty()) </del> <ins> fn ty_generics_for_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, generics: &hir::Generics) -> ty::Generics<'tcx> { ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty(), true) } fn ty_generics_for_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, generics: &hir::Generics) -> ty::Generics<'tcx> { ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty(), false) </ins> } fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,

debug!("ty_generics_for_trait(trait_id={:?}, substs={:?})", ccx.tcx.map.local_def_id(trait_id), substs); <del> let mut generics = ty_generics_for_type_or_impl(ccx, ast_generics); </del> <ins> let mut generics = ty_generics_for_type(ccx, ast_generics); </ins> // Add in the self type parameter. //

base_generics: &ty::Generics<'tcx>) -> ty::Generics<'tcx> { <del> ty_generics(ccx, FnSpace, generics, base_generics) </del> <ins> ty_generics(ccx, FnSpace, generics, base_generics, false) </ins> } fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,

fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, space: ParamSpace, ast_generics: &hir::Generics, <del> base_generics: &ty::Generics<'tcx>) </del> <ins> base_generics: &ty::Generics<'tcx>, allow_defaults: bool) </ins> -> ty::Generics<'tcx> { let tcx = ccx.tcx;

// Now create the real type parameters. for i in 0..ast_generics.ty_params.len() { <del> let def = get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32); </del> <ins> let def = get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32, allow_defaults); </ins> debug!("ty_generics: def for type param: {:?}, {:?}", def, space); result.types.push(space, def); }

fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, ast_generics: &hir::Generics, space: ParamSpace, <del> index: u32) </del> <ins> index: u32, allow_defaults: bool) </ins> -> ty::TypeParameterDef<'tcx> { let param = &ast_generics.ty_params[index as usize];

let parent = tcx.map.get_parent(param.id); <del> if space != TypeSpace && default.is_some() { </del> <ins> if !allow_defaults && default.is_some() { </ins> if !tcx.sess.features.borrow().default_type_parameter_fallback { tcx.sess.add_lint( lint::builtin::INVALID_TYPE_PARAM_DEFAULT,

fn avg<T=i32>(_: T) {} //~^ ERROR defaults for type parameters are only allowed //~| WARNING hard error <ins> struct S<T>(T); impl<T=i32> S<T> {} //~^ ERROR defaults for type parameters are only allowed //~| WARNING hard error </ins> fn main() {}